Initial Contribution
This commit is contained in:
270
samples/GlobalTime/src/com/android/globaltime/Shape.java
Normal file
270
samples/GlobalTime/src/com/android/globaltime/Shape.java
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.globaltime;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* An abstract superclass for various three-dimensional objects to be drawn
|
||||
* using OpenGL ES. Each subclass is responsible for setting up NIO buffers
|
||||
* containing vertices, texture coordinates, colors, normals, and indices.
|
||||
* The {@link #draw(GL10)} method draws the object to the given OpenGL context.
|
||||
*/
|
||||
public abstract class Shape {
|
||||
|
||||
public static final int INT_BYTES = 4;
|
||||
public static final int SHORT_BYTES = 2;
|
||||
|
||||
public static final float DEGREES_TO_RADIANS = (float) Math.PI / 180.0f;
|
||||
public static final float PI = (float) Math.PI;
|
||||
public static final float TWO_PI = (float) (2.0 * Math.PI);
|
||||
public static final float PI_OVER_TWO = (float) (Math.PI / 2.0);
|
||||
|
||||
protected int mPrimitive;
|
||||
protected int mIndexDatatype;
|
||||
|
||||
protected boolean mEmitTextureCoordinates;
|
||||
protected boolean mEmitNormals;
|
||||
protected boolean mEmitColors;
|
||||
|
||||
protected IntBuffer mVertexBuffer;
|
||||
protected IntBuffer mTexcoordBuffer;
|
||||
protected IntBuffer mColorBuffer;
|
||||
protected IntBuffer mNormalBuffer;
|
||||
protected Buffer mIndexBuffer;
|
||||
protected int mNumIndices = -1;
|
||||
|
||||
/**
|
||||
* Constructs a Shape.
|
||||
*
|
||||
* @param primitive a GL primitive type understood by glDrawElements,
|
||||
* such as GL10.GL_TRIANGLES
|
||||
* @param indexDatatype the GL datatype for the index buffer, such as
|
||||
* GL10.GL_UNSIGNED_SHORT
|
||||
* @param emitTextureCoordinates true to enable use of the texture
|
||||
* coordinate buffer
|
||||
* @param emitNormals true to enable use of the normal buffer
|
||||
* @param emitColors true to enable use of the color buffer
|
||||
*/
|
||||
protected Shape(int primitive,
|
||||
int indexDatatype,
|
||||
boolean emitTextureCoordinates,
|
||||
boolean emitNormals,
|
||||
boolean emitColors) {
|
||||
mPrimitive = primitive;
|
||||
mIndexDatatype = indexDatatype;
|
||||
mEmitTextureCoordinates = emitTextureCoordinates;
|
||||
mEmitNormals = emitNormals;
|
||||
mEmitColors = emitColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given floating-point value to fixed-point.
|
||||
*/
|
||||
public static int toFixed(float x) {
|
||||
return (int) (x * 65536.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given fixed-point value to floating-point.
|
||||
*/
|
||||
public static float toFloat(int x) {
|
||||
return (float) (x / 65536.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cross-product of two vectors p and q and places
|
||||
* the result in out.
|
||||
*/
|
||||
public static void cross(float[] p, float[] q, float[] out) {
|
||||
out[0] = p[1] * q[2] - p[2] * q[1];
|
||||
out[1] = p[2] * q[0] - p[0] * q[2];
|
||||
out[2] = p[0] * q[1] - p[1] * q[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of a vector, given as three floats.
|
||||
*/
|
||||
public static float length(float vx, float vy, float vz) {
|
||||
return (float) Math.sqrt(vx * vx + vy * vy + vz * vz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of a vector, given as an array of three floats.
|
||||
*/
|
||||
public static float length(float[] v) {
|
||||
return length(v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the given vector of three floats to have length == 1.0.
|
||||
* Vectors with length zero are unaffected.
|
||||
*/
|
||||
public static void normalize(float[] v) {
|
||||
float length = length(v);
|
||||
if (length != 0.0f) {
|
||||
float norm = 1.0f / length;
|
||||
v[0] *= norm;
|
||||
v[1] *= norm;
|
||||
v[2] *= norm;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of triangles associated with this shape.
|
||||
*/
|
||||
public int getNumTriangles() {
|
||||
if (mPrimitive == GL10.GL_TRIANGLES) {
|
||||
return mIndexBuffer.capacity() / 3;
|
||||
} else if (mPrimitive == GL10.GL_TRIANGLE_STRIP) {
|
||||
return mIndexBuffer.capacity() - 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the given data into the instance
|
||||
* variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
|
||||
* and mIndexBuffer.
|
||||
*
|
||||
* @param vertices an array of fixed-point vertex coordinates
|
||||
* @param texcoords an array of fixed-point texture coordinates
|
||||
* @param normals an array of fixed-point normal vector coordinates
|
||||
* @param colors an array of fixed-point color channel values
|
||||
* @param indices an array of short indices
|
||||
*/
|
||||
public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
|
||||
int[] colors, short[] indices) {
|
||||
allocate(vertices, texcoords, normals, colors);
|
||||
|
||||
ByteBuffer ibb =
|
||||
ByteBuffer.allocateDirect(indices.length * SHORT_BYTES);
|
||||
ibb.order(ByteOrder.nativeOrder());
|
||||
ShortBuffer shortIndexBuffer = ibb.asShortBuffer();
|
||||
shortIndexBuffer.put(indices);
|
||||
shortIndexBuffer.position(0);
|
||||
this.mIndexBuffer = shortIndexBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the given data into the instance
|
||||
* variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
|
||||
* and mIndexBuffer.
|
||||
*
|
||||
* @param vertices an array of fixed-point vertex coordinates
|
||||
* @param texcoords an array of fixed-point texture coordinates
|
||||
* @param normals an array of fixed-point normal vector coordinates
|
||||
* @param colors an array of fixed-point color channel values
|
||||
* @param indices an array of int indices
|
||||
*/
|
||||
public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
|
||||
int[] colors, int[] indices) {
|
||||
allocate(vertices, texcoords, normals, colors);
|
||||
|
||||
ByteBuffer ibb =
|
||||
ByteBuffer.allocateDirect(indices.length * INT_BYTES);
|
||||
ibb.order(ByteOrder.nativeOrder());
|
||||
IntBuffer intIndexBuffer = ibb.asIntBuffer();
|
||||
intIndexBuffer.put(indices);
|
||||
intIndexBuffer.position(0);
|
||||
this.mIndexBuffer = intIndexBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the vertex, texture coordinate, normal, and color buffer.
|
||||
*/
|
||||
private void allocate(int[] vertices, int[] texcoords, int[] normals,
|
||||
int[] colors) {
|
||||
ByteBuffer vbb =
|
||||
ByteBuffer.allocateDirect(vertices.length * INT_BYTES);
|
||||
vbb.order(ByteOrder.nativeOrder());
|
||||
mVertexBuffer = vbb.asIntBuffer();
|
||||
mVertexBuffer.put(vertices);
|
||||
mVertexBuffer.position(0);
|
||||
|
||||
if ((texcoords != null) && mEmitTextureCoordinates) {
|
||||
ByteBuffer tbb =
|
||||
ByteBuffer.allocateDirect(texcoords.length * INT_BYTES);
|
||||
tbb.order(ByteOrder.nativeOrder());
|
||||
mTexcoordBuffer = tbb.asIntBuffer();
|
||||
mTexcoordBuffer.put(texcoords);
|
||||
mTexcoordBuffer.position(0);
|
||||
}
|
||||
|
||||
if ((normals != null) && mEmitNormals) {
|
||||
ByteBuffer nbb =
|
||||
ByteBuffer.allocateDirect(normals.length * INT_BYTES);
|
||||
nbb.order(ByteOrder.nativeOrder());
|
||||
mNormalBuffer = nbb.asIntBuffer();
|
||||
mNormalBuffer.put(normals);
|
||||
mNormalBuffer.position(0);
|
||||
}
|
||||
|
||||
if ((colors != null) && mEmitColors) {
|
||||
ByteBuffer cbb =
|
||||
ByteBuffer.allocateDirect(colors.length * INT_BYTES);
|
||||
cbb.order(ByteOrder.nativeOrder());
|
||||
mColorBuffer = cbb.asIntBuffer();
|
||||
mColorBuffer.put(colors);
|
||||
mColorBuffer.position(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the shape to the given OpenGL ES 1.0 context. Texture coordinates,
|
||||
* normals, and colors are emitted according the the preferences set for
|
||||
* this shape.
|
||||
*/
|
||||
public void draw(GL10 gl) {
|
||||
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
|
||||
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||
|
||||
if (mEmitTextureCoordinates) {
|
||||
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTexcoordBuffer);
|
||||
gl.glEnable(GL10.GL_TEXTURE_2D);
|
||||
} else {
|
||||
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||
gl.glDisable(GL10.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
if (mEmitNormals) {
|
||||
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
|
||||
gl.glNormalPointer(GL10.GL_FIXED, 0, mNormalBuffer);
|
||||
} else {
|
||||
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
if (mEmitColors) {
|
||||
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
|
||||
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
|
||||
} else {
|
||||
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
gl.glDrawElements(mPrimitive,
|
||||
mNumIndices > 0 ? mNumIndices : mIndexBuffer.capacity(),
|
||||
mIndexDatatype,
|
||||
mIndexBuffer);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user