• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.globaltime;
18 
19 import java.nio.Buffer;
20 import java.nio.ByteBuffer;
21 import java.nio.ByteOrder;
22 import java.nio.IntBuffer;
23 import java.nio.ShortBuffer;
24 
25 import javax.microedition.khronos.opengles.GL10;
26 
27 /**
28  * An abstract superclass for various three-dimensional objects to be drawn
29  * using OpenGL ES.  Each subclass is responsible for setting up NIO buffers
30  * containing vertices, texture coordinates, colors, normals, and indices.
31  * The {@link #draw(GL10)} method draws the object to the given OpenGL context.
32  */
33 public abstract class Shape {
34 
35     public static final int INT_BYTES = 4;
36     public static final int SHORT_BYTES = 2;
37 
38     public static final float DEGREES_TO_RADIANS = (float) Math.PI / 180.0f;
39     public static final float PI = (float) Math.PI;
40     public static final float TWO_PI = (float) (2.0 * Math.PI);
41     public static final float PI_OVER_TWO = (float) (Math.PI / 2.0);
42 
43     protected int mPrimitive;
44     protected int mIndexDatatype;
45 
46     protected boolean mEmitTextureCoordinates;
47     protected boolean mEmitNormals;
48     protected boolean mEmitColors;
49 
50     protected IntBuffer mVertexBuffer;
51     protected IntBuffer mTexcoordBuffer;
52     protected IntBuffer mColorBuffer;
53     protected IntBuffer mNormalBuffer;
54     protected Buffer mIndexBuffer;
55     protected int mNumIndices = -1;
56 
57     /**
58      * Constructs a Shape.
59      *
60      * @param primitive a GL primitive type understood by glDrawElements,
61      * such as GL10.GL_TRIANGLES
62      * @param indexDatatype the GL datatype for the  index buffer, such as
63      * GL10.GL_UNSIGNED_SHORT
64      * @param emitTextureCoordinates true to enable use of the texture
65      * coordinate buffer
66      * @param emitNormals true to enable use of the normal buffer
67      * @param emitColors true to enable use of the color buffer
68      */
Shape(int primitive, int indexDatatype, boolean emitTextureCoordinates, boolean emitNormals, boolean emitColors)69     protected Shape(int primitive,
70         int indexDatatype,
71         boolean emitTextureCoordinates,
72         boolean emitNormals,
73         boolean emitColors) {
74         mPrimitive = primitive;
75         mIndexDatatype = indexDatatype;
76         mEmitTextureCoordinates = emitTextureCoordinates;
77         mEmitNormals = emitNormals;
78         mEmitColors = emitColors;
79     }
80 
81     /**
82      * Converts the given floating-point value to fixed-point.
83      */
toFixed(float x)84     public static int toFixed(float x) {
85         return (int) (x * 65536.0);
86     }
87 
88     /**
89      * Converts the given fixed-point value to floating-point.
90      */
toFloat(int x)91     public static float toFloat(int x) {
92         return (float) (x / 65536.0);
93     }
94 
95     /**
96      * Computes the cross-product of two vectors p and q and places
97      * the result in out.
98      */
cross(float[] p, float[] q, float[] out)99     public static void cross(float[] p, float[] q, float[] out) {
100         out[0] = p[1] * q[2] - p[2] * q[1];
101         out[1] = p[2] * q[0] - p[0] * q[2];
102         out[2] = p[0] * q[1] - p[1] * q[0];
103     }
104 
105     /**
106      * Returns the length of a vector, given as three floats.
107      */
length(float vx, float vy, float vz)108     public static float length(float vx, float vy, float vz) {
109         return (float) Math.sqrt(vx * vx + vy * vy + vz * vz);
110     }
111 
112     /**
113      * Returns the length of a vector, given as an array of three floats.
114      */
length(float[] v)115     public static float length(float[] v) {
116         return length(v[0], v[1], v[2]);
117     }
118 
119     /**
120      * Normalizes the given vector of three floats to have length == 1.0.
121      * Vectors with length zero are unaffected.
122      */
normalize(float[] v)123     public static void normalize(float[] v) {
124         float length = length(v);
125         if (length != 0.0f) {
126             float norm = 1.0f / length;
127             v[0] *= norm;
128             v[1] *= norm;
129             v[2] *= norm;
130         }
131     }
132 
133     /**
134      * Returns the number of triangles associated with this shape.
135      */
getNumTriangles()136     public int getNumTriangles() {
137         if (mPrimitive == GL10.GL_TRIANGLES) {
138             return mIndexBuffer.capacity() / 3;
139         } else if (mPrimitive == GL10.GL_TRIANGLE_STRIP) {
140             return mIndexBuffer.capacity() - 2;
141         }
142         return 0;
143     }
144 
145     /**
146      * Copies the given data into the instance
147      * variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
148      * and mIndexBuffer.
149      *
150      * @param vertices an array of fixed-point vertex coordinates
151      * @param texcoords an array of fixed-point texture coordinates
152      * @param normals an array of fixed-point normal vector coordinates
153      * @param colors an array of fixed-point color channel values
154      * @param indices an array of short indices
155      */
allocateBuffers(int[] vertices, int[] texcoords, int[] normals, int[] colors, short[] indices)156     public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
157         int[] colors, short[] indices) {
158         allocate(vertices, texcoords, normals, colors);
159 
160         ByteBuffer ibb =
161             ByteBuffer.allocateDirect(indices.length * SHORT_BYTES);
162         ibb.order(ByteOrder.nativeOrder());
163         ShortBuffer shortIndexBuffer = ibb.asShortBuffer();
164         shortIndexBuffer.put(indices);
165         shortIndexBuffer.position(0);
166         this.mIndexBuffer = shortIndexBuffer;
167     }
168 
169     /**
170      * Copies the given data into the instance
171      * variables mVertexBuffer, mTexcoordBuffer, mNormalBuffer, mColorBuffer,
172      * and mIndexBuffer.
173      *
174      * @param vertices an array of fixed-point vertex coordinates
175      * @param texcoords an array of fixed-point texture coordinates
176      * @param normals an array of fixed-point normal vector coordinates
177      * @param colors an array of fixed-point color channel values
178      * @param indices an array of int indices
179      */
allocateBuffers(int[] vertices, int[] texcoords, int[] normals, int[] colors, int[] indices)180     public void allocateBuffers(int[] vertices, int[] texcoords, int[] normals,
181         int[] colors, int[] indices) {
182         allocate(vertices, texcoords, normals, colors);
183 
184         ByteBuffer ibb =
185             ByteBuffer.allocateDirect(indices.length * INT_BYTES);
186         ibb.order(ByteOrder.nativeOrder());
187         IntBuffer intIndexBuffer = ibb.asIntBuffer();
188         intIndexBuffer.put(indices);
189         intIndexBuffer.position(0);
190         this.mIndexBuffer = intIndexBuffer;
191     }
192 
193     /**
194      * Allocate the vertex, texture coordinate, normal, and color buffer.
195      */
allocate(int[] vertices, int[] texcoords, int[] normals, int[] colors)196     private void allocate(int[] vertices, int[] texcoords, int[] normals,
197         int[] colors) {
198         ByteBuffer vbb =
199             ByteBuffer.allocateDirect(vertices.length * INT_BYTES);
200         vbb.order(ByteOrder.nativeOrder());
201         mVertexBuffer = vbb.asIntBuffer();
202         mVertexBuffer.put(vertices);
203         mVertexBuffer.position(0);
204 
205         if ((texcoords != null) && mEmitTextureCoordinates) {
206             ByteBuffer tbb =
207                 ByteBuffer.allocateDirect(texcoords.length * INT_BYTES);
208             tbb.order(ByteOrder.nativeOrder());
209             mTexcoordBuffer = tbb.asIntBuffer();
210             mTexcoordBuffer.put(texcoords);
211             mTexcoordBuffer.position(0);
212         }
213 
214         if ((normals != null) && mEmitNormals) {
215             ByteBuffer nbb =
216                 ByteBuffer.allocateDirect(normals.length * INT_BYTES);
217             nbb.order(ByteOrder.nativeOrder());
218             mNormalBuffer = nbb.asIntBuffer();
219             mNormalBuffer.put(normals);
220             mNormalBuffer.position(0);
221         }
222 
223         if ((colors != null) && mEmitColors) {
224             ByteBuffer cbb =
225                 ByteBuffer.allocateDirect(colors.length * INT_BYTES);
226             cbb.order(ByteOrder.nativeOrder());
227             mColorBuffer = cbb.asIntBuffer();
228             mColorBuffer.put(colors);
229             mColorBuffer.position(0);
230         }
231     }
232 
233     /**
234      * Draws the shape to the given OpenGL ES 1.0 context.  Texture coordinates,
235      * normals, and colors are emitted according the the preferences set for
236      * this shape.
237      */
draw(GL10 gl)238     public void draw(GL10 gl) {
239         gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
240         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
241 
242         if (mEmitTextureCoordinates) {
243             gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
244             gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, mTexcoordBuffer);
245             gl.glEnable(GL10.GL_TEXTURE_2D);
246         } else {
247             gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
248             gl.glDisable(GL10.GL_TEXTURE_2D);
249         }
250 
251         if (mEmitNormals) {
252             gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
253             gl.glNormalPointer(GL10.GL_FIXED, 0, mNormalBuffer);
254         } else {
255             gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
256         }
257 
258         if (mEmitColors) {
259             gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
260             gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
261         } else {
262             gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
263         }
264 
265         gl.glDrawElements(mPrimitive,
266                           mNumIndices > 0 ? mNumIndices : mIndexBuffer.capacity(),
267                           mIndexDatatype,
268                           mIndexBuffer);
269     }
270 }
271