• 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 android.opengl;
18 
19 import javax.microedition.khronos.opengles.GL10;
20 
21 /**
22  * A set of GL utilities inspired by the OpenGL Utility Toolkit.
23  *
24  */
25 
26 public class GLU {
27 
28     /**
29      * Return an error string from a GL or GLU error code.
30      *
31      * @param error - a GL or GLU error code.
32      * @return the error string for the input error code, or NULL if the input
33      *         was not a valid GL or GLU error code.
34      */
gluErrorString(int error)35     public static String gluErrorString(int error) {
36         switch (error) {
37         case GL10.GL_NO_ERROR:
38             return "no error";
39         case GL10.GL_INVALID_ENUM:
40             return "invalid enum";
41         case GL10.GL_INVALID_VALUE:
42             return "invalid value";
43         case GL10.GL_INVALID_OPERATION:
44             return "invalid operation";
45         case GL10.GL_STACK_OVERFLOW:
46             return "stack overflow";
47         case GL10.GL_STACK_UNDERFLOW:
48             return "stack underflow";
49         case GL10.GL_OUT_OF_MEMORY:
50             return "out of memory";
51         default:
52             return null;
53         }
54     }
55 
56     /**
57      * Define a viewing transformation in terms of an eye point, a center of
58      * view, and an up vector.
59      *
60      * @param gl a GL10 interface
61      * @param eyeX eye point X
62      * @param eyeY eye point Y
63      * @param eyeZ eye point Z
64      * @param centerX center of view X
65      * @param centerY center of view Y
66      * @param centerZ center of view Z
67      * @param upX up vector X
68      * @param upY up vector Y
69      * @param upZ up vector Z
70      */
gluLookAt(GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)71     public static void gluLookAt(GL10 gl, float eyeX, float eyeY, float eyeZ,
72             float centerX, float centerY, float centerZ, float upX, float upY,
73             float upZ) {
74 
75         // See the OpenGL GLUT documentation for gluLookAt for a description
76         // of the algorithm. We implement it in a straightforward way:
77 
78         float fx = centerX - eyeX;
79         float fy = centerY - eyeY;
80         float fz = centerZ - eyeZ;
81 
82         // Normalize f
83         float rlf = 1.0f / Matrix.length(fx, fy, fz);
84         fx *= rlf;
85         fy *= rlf;
86         fz *= rlf;
87 
88         // compute s = f x up (x means "cross product")
89         float sx = fy * upZ - fz * upY;
90         float sy = fz * upX - fx * upZ;
91         float sz = fx * upY - fy * upX;
92 
93         // and normalize s
94         float rls = 1.0f / Matrix.length(sx, sy, sz);
95         sx *= rls;
96         sy *= rls;
97         sz *= rls;
98 
99         // compute u = s x f
100         float ux = sy * fz - sz * fy;
101         float uy = sz * fx - sx * fz;
102         float uz = sx * fy - sy * fx;
103 
104         float[] scratch = sScratch;
105         synchronized(scratch) {
106             scratch[0] = sx;
107             scratch[1] = ux;
108             scratch[2] = -fx;
109             scratch[3] = 0.0f;
110 
111             scratch[4] = sy;
112             scratch[5] = uy;
113             scratch[6] = -fy;
114             scratch[7] = 0.0f;
115 
116             scratch[8] = sz;
117             scratch[9] = uz;
118             scratch[10] = -fz;
119             scratch[11] = 0.0f;
120 
121             scratch[12] = 0.0f;
122             scratch[13] = 0.0f;
123             scratch[14] = 0.0f;
124             scratch[15] = 1.0f;
125 
126             gl.glMultMatrixf(scratch, 0);
127         }
128         gl.glTranslatef(-eyeX, -eyeY, -eyeZ);
129     }
130 
131     /**
132      * Set up a 2D orthographic projection matrix
133      *
134      * @param gl
135      * @param left
136      * @param right
137      * @param bottom
138      * @param top
139      */
gluOrtho2D(GL10 gl, float left, float right, float bottom, float top)140     public static void gluOrtho2D(GL10 gl, float left, float right,
141             float bottom, float top) {
142         gl.glOrthof(left, right, bottom, top, -1.0f, 1.0f);
143     }
144 
145     /**
146      * Set up a perspective projection matrix
147      *
148      * @param gl a GL10 interface
149      * @param fovy specifies the field of view angle, in degrees, in the Y
150      *        direction.
151      * @param aspect specifies the aspect ration that determins the field of
152      *        view in the x direction. The aspect ratio is the ratio of x
153      *        (width) to y (height).
154      * @param zNear specifies the distance from the viewer to the near clipping
155      *        plane (always positive).
156      * @param zFar specifies the distance from the viewer to the far clipping
157      *        plane (always positive).
158      */
gluPerspective(GL10 gl, float fovy, float aspect, float zNear, float zFar)159     public static void gluPerspective(GL10 gl, float fovy, float aspect,
160             float zNear, float zFar) {
161         float top = zNear * (float) Math.tan(fovy * (Math.PI / 360.0));
162         float bottom = -top;
163         float left = bottom * aspect;
164         float right = top * aspect;
165         gl.glFrustumf(left, right, bottom, top, zNear, zFar);
166     }
167 
168     /**
169      * Map object coordinates into window coordinates. gluProject transforms the
170      * specified object coordinates into window coordinates using model, proj,
171      * and view. The result is stored in win.
172      * <p>
173      * Note that you can use the OES_matrix_get extension, if present, to get
174      * the current modelView and projection matrices.
175      *
176      * @param objX object coordinates X
177      * @param objY object coordinates Y
178      * @param objZ object coordinates Z
179      * @param model the current modelview matrix
180      * @param modelOffset the offset into the model array where the modelview
181      *        maxtrix data starts.
182      * @param project the current projection matrix
183      * @param projectOffset the offset into the project array where the project
184      *        matrix data starts.
185      * @param view the current view, {x, y, width, height}
186      * @param viewOffset the offset into the view array where the view vector
187      *        data starts.
188      * @param win the output vector {winX, winY, winZ}, that returns the
189      *        computed window coordinates.
190      * @param winOffset the offset into the win array where the win vector data
191      *        starts.
192      * @return A return value of GL_TRUE indicates success, a return value of
193      *         GL_FALSE indicates failure.
194      */
gluProject(float objX, float objY, float objZ, float[] model, int modelOffset, float[] project, int projectOffset, int[] view, int viewOffset, float[] win, int winOffset)195     public static int gluProject(float objX, float objY, float objZ,
196             float[] model, int modelOffset, float[] project, int projectOffset,
197             int[] view, int viewOffset, float[] win, int winOffset) {
198         float[] scratch = sScratch;
199         synchronized(scratch) {
200             final int M_OFFSET = 0; // 0..15
201             final int V_OFFSET = 16; // 16..19
202             final int V2_OFFSET = 20; // 20..23
203             Matrix.multiplyMM(scratch, M_OFFSET, project, projectOffset,
204                     model, modelOffset);
205 
206             scratch[V_OFFSET + 0] = objX;
207             scratch[V_OFFSET + 1] = objY;
208             scratch[V_OFFSET + 2] = objZ;
209             scratch[V_OFFSET + 3] = 1.0f;
210 
211             Matrix.multiplyMV(scratch, V2_OFFSET,
212                     scratch, M_OFFSET, scratch, V_OFFSET);
213 
214             float w = scratch[V2_OFFSET + 3];
215             if (w == 0.0f) {
216                 return GL10.GL_FALSE;
217             }
218 
219             float rw = 1.0f / w;
220 
221             win[winOffset] =
222                     view[viewOffset] + view[viewOffset + 2]
223                             * (scratch[V2_OFFSET + 0] * rw + 1.0f)
224                             * 0.5f;
225             win[winOffset + 1] =
226                     view[viewOffset + 1] + view[viewOffset + 3]
227                             * (scratch[V2_OFFSET + 1] * rw + 1.0f) * 0.5f;
228             win[winOffset + 2] = (scratch[V2_OFFSET + 2] * rw + 1.0f) * 0.5f;
229         }
230 
231         return GL10.GL_TRUE;
232     }
233 
234     /**
235      * Map window coordinates to object coordinates. gluUnProject maps the
236      * specified window coordinates into object coordinates using model, proj,
237      * and view. The result is stored in obj.
238      * <p>
239      * Note that you can use the OES_matrix_get extension, if present, to get
240      * the current modelView and projection matrices.
241      *
242      * @param winX window coordinates X
243      * @param winY window coordinates Y
244      * @param winZ window coordinates Z
245      * @param model the current modelview matrix
246      * @param modelOffset the offset into the model array where the modelview
247      *        maxtrix data starts.
248      * @param project the current projection matrix
249      * @param projectOffset the offset into the project array where the project
250      *        matrix data starts.
251      * @param view the current view, {x, y, width, height}
252      * @param viewOffset the offset into the view array where the view vector
253      *        data starts.
254      * @param obj the output vector {objX, objY, objZ}, that returns the
255      *        computed object coordinates.
256      * @param objOffset the offset into the obj array where the obj vector data
257      *        starts.
258      * @return A return value of GL10.GL_TRUE indicates success, a return value
259      *         of GL10.GL_FALSE indicates failure.
260      */
gluUnProject(float winX, float winY, float winZ, float[] model, int modelOffset, float[] project, int projectOffset, int[] view, int viewOffset, float[] obj, int objOffset)261     public static int gluUnProject(float winX, float winY, float winZ,
262             float[] model, int modelOffset, float[] project, int projectOffset,
263             int[] view, int viewOffset, float[] obj, int objOffset) {
264         float[] scratch = sScratch;
265         synchronized(scratch) {
266             final int PM_OFFSET = 0; // 0..15
267             final int INVPM_OFFSET = 16; // 16..31
268                final int V_OFFSET = 0; // 0..3 Reuses PM_OFFSET space
269             Matrix.multiplyMM(scratch, PM_OFFSET, project, projectOffset,
270                     model, modelOffset);
271 
272             if (!Matrix.invertM(scratch, INVPM_OFFSET, scratch, PM_OFFSET)) {
273                 return GL10.GL_FALSE;
274             }
275 
276             scratch[V_OFFSET + 0] =
277                     2.0f * (winX - view[viewOffset + 0]) / view[viewOffset + 2]
278                             - 1.0f;
279             scratch[V_OFFSET + 1] =
280                     2.0f * (winY - view[viewOffset + 1]) / view[viewOffset + 3]
281                             - 1.0f;
282             scratch[V_OFFSET + 2] = 2.0f * winZ - 1.0f;
283             scratch[V_OFFSET + 3] = 1.0f;
284 
285             Matrix.multiplyMV(obj, objOffset, scratch, INVPM_OFFSET,
286                     scratch, V_OFFSET);
287         }
288 
289         return GL10.GL_TRUE;
290     }
291 
292     private static final float[] sScratch = new float[32];
293  }
294