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