GLU.java revision 843ef36f7b96cc19ea7d2996b7c8661b41ec3452
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 17package android.opengl; 18 19import javax.microedition.khronos.opengles.GL10; 20 21/** 22 * A set of GL utilities inspired by the OpenGL Utility Toolkit. 23 * 24 */ 25 26public 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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