GLU.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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[] m = new float[16]; 105 m[0] = sx; 106 m[1] = ux; 107 m[2] = -fx; 108 m[3] = 0.0f; 109 110 m[4] = sy; 111 m[5] = uy; 112 m[6] = -fy; 113 m[7] = 0.0f; 114 115 m[8] = sz; 116 m[9] = uz; 117 m[10] = -fz; 118 m[11] = 0.0f; 119 120 m[12] = 0.0f; 121 m[13] = 0.0f; 122 m[14] = 0.0f; 123 m[15] = 1.0f; 124 125 gl.glMultMatrixf(m, 0); 126 gl.glTranslatef(-eyeX, -eyeY, -eyeZ); 127 } 128 129 /** 130 * Set up a 2D orthographic projection matrix 131 * 132 * @param gl 133 * @param left 134 * @param right 135 * @param bottom 136 * @param top 137 */ 138 public static void gluOrtho2D(GL10 gl, float left, float right, 139 float bottom, float top) { 140 gl.glOrthof(left, right, bottom, top, -1.0f, 1.0f); 141 } 142 143 /** 144 * Set up a perspective projection matrix 145 * 146 * @param gl a GL10 interface 147 * @param fovy specifies the field of view angle, in degrees, in the Y 148 * direction. 149 * @param aspect specifies the aspect ration that determins the field of 150 * view in the x direction. The aspect ratio is the ratio of x 151 * (width) to y (height). 152 * @param zNear specifies the distance from the viewer to the near clipping 153 * plane (always positive). 154 * @param zFar specifies the distance from the viewer to the far clipping 155 * plane (always positive). 156 */ 157 public static void gluPerspective(GL10 gl, float fovy, float aspect, 158 float zNear, float zFar) { 159 float top = zNear * (float) Math.tan(fovy * (Math.PI / 360.0)); 160 float bottom = -top; 161 float left = bottom * aspect; 162 float right = top * aspect; 163 gl.glFrustumf(left, right, bottom, top, zNear, zFar); 164 } 165 166 /** 167 * Map object coordinates into window coordinates. gluProject transforms the 168 * specified object coordinates into window coordinates using model, proj, 169 * and view. The result is stored in win. 170 * <p> 171 * Note that you can use the OES_matrix_get extension, if present, to get 172 * the current modelView and projection matrices. 173 * 174 * @param objX object coordinates X 175 * @param objY object coordinates Y 176 * @param objZ object coordinates Z 177 * @param model the current modelview matrix 178 * @param modelOffset the offset into the model array where the modelview 179 * maxtrix data starts. 180 * @param project the current projection matrix 181 * @param projectOffset the offset into the project array where the project 182 * matrix data starts. 183 * @param view the current view, {x, y, width, height} 184 * @param viewOffset the offset into the view array where the view vector 185 * data starts. 186 * @param win the output vector {winX, winY, winZ}, that returns the 187 * computed window coordinates. 188 * @param winOffset the offset into the win array where the win vector data 189 * starts. 190 * @return A return value of GL_TRUE indicates success, a return value of 191 * GL_FALSE indicates failure. 192 */ 193 public static int gluProject(float objX, float objY, float objZ, 194 float[] model, int modelOffset, float[] project, int projectOffset, 195 int[] view, int viewOffset, float[] win, int winOffset) { 196 float[] m = new float[16]; 197 Matrix.multiplyMM(m, 0, project, projectOffset, model, modelOffset); 198 199 float[] v = new float[4]; 200 201 v[0] = objX; 202 v[1] = objY; 203 v[2] = objZ; 204 v[3] = 1.0f; 205 206 float[] v2 = new float[4]; 207 208 Matrix.multiplyMV(v2, 0, m, 0, v, 0); 209 210 float w = v2[3]; 211 if (w == 0.0f) { 212 return GL10.GL_FALSE; 213 } 214 215 float rw = 1.0f / w; 216 217 win[winOffset] = 218 view[viewOffset] + view[viewOffset + 2] * (v2[0] * rw + 1.0f) 219 * 0.5f; 220 win[winOffset + 1] = 221 view[viewOffset + 1] + view[viewOffset + 3] 222 * (v2[1] * rw + 1.0f) * 0.5f; 223 win[winOffset + 2] = (v2[2] * rw + 1.0f) * 0.5f; 224 225 return GL10.GL_TRUE; 226 } 227 228 /** 229 * Map window coordinates to object coordinates. gluUnProject maps the 230 * specified window coordinates into object coordinates using model, proj, 231 * and view. The result is stored in obj. 232 * <p> 233 * Note that you can use the OES_matrix_get extension, if present, to get 234 * the current modelView and projection matrices. 235 * 236 * @param winX window coordinates X 237 * @param winY window coordinates Y 238 * @param winZ window coordinates Z 239 * @param model the current modelview matrix 240 * @param modelOffset the offset into the model array where the modelview 241 * maxtrix data starts. 242 * @param project the current projection matrix 243 * @param projectOffset the offset into the project array where the project 244 * matrix data starts. 245 * @param view the current view, {x, y, width, height} 246 * @param viewOffset the offset into the view array where the view vector 247 * data starts. 248 * @param obj the output vector {objX, objY, objZ}, that returns the 249 * computed object coordinates. 250 * @param objOffset the offset into the obj array where the obj vector data 251 * starts. 252 * @return A return value of GL10.GL_TRUE indicates success, a return value 253 * of GL10.GL_FALSE indicates failure. 254 */ 255 public static int gluUnProject(float winX, float winY, float winZ, 256 float[] model, int modelOffset, float[] project, int projectOffset, 257 int[] view, int viewOffset, float[] obj, int objOffset) { 258 float[] pm = new float[16]; 259 Matrix.multiplyMM(pm, 0, project, projectOffset, model, modelOffset); 260 261 float[] invPM = new float[16]; 262 if (!Matrix.invertM(invPM, 0, pm, 0)) { 263 return GL10.GL_FALSE; 264 } 265 266 float[] v = new float[4]; 267 268 v[0] = 269 2.0f * (winX - view[viewOffset + 0]) / view[viewOffset + 2] 270 - 1.0f; 271 v[1] = 272 2.0f * (winY - view[viewOffset + 1]) / view[viewOffset + 3] 273 - 1.0f; 274 v[2] = 2.0f * winZ - 1.0f; 275 v[3] = 1.0f; 276 277 float[] v2 = new float[4]; 278 279 Matrix.multiplyMV(v2, 0, invPM, 0, v, 0); 280 281 obj[objOffset] = v2[0]; 282 obj[objOffset + 1] = v2[1]; 283 obj[objOffset + 2] = v2[2]; 284 285 return GL10.GL_TRUE; 286 } 287 288 } 289