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 float[] scratch = sScratch; 76 synchronized(scratch) { 77 Matrix.setLookAtM(scratch, 0, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, 78 upX, upY, upZ); 79 gl.glMultMatrixf(scratch, 0); 80 } 81 } 82 83 /** 84 * Set up a 2D orthographic projection matrix 85 * 86 * @param gl 87 * @param left 88 * @param right 89 * @param bottom 90 * @param top 91 */ 92 public static void gluOrtho2D(GL10 gl, float left, float right, 93 float bottom, float top) { 94 gl.glOrthof(left, right, bottom, top, -1.0f, 1.0f); 95 } 96 97 /** 98 * Set up a perspective projection matrix 99 * 100 * @param gl a GL10 interface 101 * @param fovy specifies the field of view angle, in degrees, in the Y 102 * direction. 103 * @param aspect specifies the aspect ration that determins the field of 104 * view in the x direction. The aspect ratio is the ratio of x 105 * (width) to y (height). 106 * @param zNear specifies the distance from the viewer to the near clipping 107 * plane (always positive). 108 * @param zFar specifies the distance from the viewer to the far clipping 109 * plane (always positive). 110 */ 111 public static void gluPerspective(GL10 gl, float fovy, float aspect, 112 float zNear, float zFar) { 113 float top = zNear * (float) Math.tan(fovy * (Math.PI / 360.0)); 114 float bottom = -top; 115 float left = bottom * aspect; 116 float right = top * aspect; 117 gl.glFrustumf(left, right, bottom, top, zNear, zFar); 118 } 119 120 /** 121 * Map object coordinates into window coordinates. gluProject transforms the 122 * specified object coordinates into window coordinates using model, proj, 123 * and view. The result is stored in win. 124 * <p> 125 * Note that you can use the OES_matrix_get extension, if present, to get 126 * the current modelView and projection matrices. 127 * 128 * @param objX object coordinates X 129 * @param objY object coordinates Y 130 * @param objZ object coordinates Z 131 * @param model the current modelview matrix 132 * @param modelOffset the offset into the model array where the modelview 133 * maxtrix data starts. 134 * @param project the current projection matrix 135 * @param projectOffset the offset into the project array where the project 136 * matrix data starts. 137 * @param view the current view, {x, y, width, height} 138 * @param viewOffset the offset into the view array where the view vector 139 * data starts. 140 * @param win the output vector {winX, winY, winZ}, that returns the 141 * computed window coordinates. 142 * @param winOffset the offset into the win array where the win vector data 143 * starts. 144 * @return A return value of GL_TRUE indicates success, a return value of 145 * GL_FALSE indicates failure. 146 */ 147 public static int gluProject(float objX, float objY, float objZ, 148 float[] model, int modelOffset, float[] project, int projectOffset, 149 int[] view, int viewOffset, float[] win, int winOffset) { 150 float[] scratch = sScratch; 151 synchronized(scratch) { 152 final int M_OFFSET = 0; // 0..15 153 final int V_OFFSET = 16; // 16..19 154 final int V2_OFFSET = 20; // 20..23 155 Matrix.multiplyMM(scratch, M_OFFSET, project, projectOffset, 156 model, modelOffset); 157 158 scratch[V_OFFSET + 0] = objX; 159 scratch[V_OFFSET + 1] = objY; 160 scratch[V_OFFSET + 2] = objZ; 161 scratch[V_OFFSET + 3] = 1.0f; 162 163 Matrix.multiplyMV(scratch, V2_OFFSET, 164 scratch, M_OFFSET, scratch, V_OFFSET); 165 166 float w = scratch[V2_OFFSET + 3]; 167 if (w == 0.0f) { 168 return GL10.GL_FALSE; 169 } 170 171 float rw = 1.0f / w; 172 173 win[winOffset] = 174 view[viewOffset] + view[viewOffset + 2] 175 * (scratch[V2_OFFSET + 0] * rw + 1.0f) 176 * 0.5f; 177 win[winOffset + 1] = 178 view[viewOffset + 1] + view[viewOffset + 3] 179 * (scratch[V2_OFFSET + 1] * rw + 1.0f) * 0.5f; 180 win[winOffset + 2] = (scratch[V2_OFFSET + 2] * rw + 1.0f) * 0.5f; 181 } 182 183 return GL10.GL_TRUE; 184 } 185 186 /** 187 * Map window coordinates to object coordinates. gluUnProject maps the 188 * specified window coordinates into object coordinates using model, proj, 189 * and view. The result is stored in obj. 190 * <p> 191 * Note that you can use the OES_matrix_get extension, if present, to get 192 * the current modelView and projection matrices. 193 * 194 * @param winX window coordinates X 195 * @param winY window coordinates Y 196 * @param winZ window coordinates Z 197 * @param model the current modelview matrix 198 * @param modelOffset the offset into the model array where the modelview 199 * maxtrix data starts. 200 * @param project the current projection matrix 201 * @param projectOffset the offset into the project array where the project 202 * matrix data starts. 203 * @param view the current view, {x, y, width, height} 204 * @param viewOffset the offset into the view array where the view vector 205 * data starts. 206 * @param obj the output vector {objX, objY, objZ}, that returns the 207 * computed object coordinates. 208 * @param objOffset the offset into the obj array where the obj vector data 209 * starts. 210 * @return A return value of GL10.GL_TRUE indicates success, a return value 211 * of GL10.GL_FALSE indicates failure. 212 */ 213 public static int gluUnProject(float winX, float winY, float winZ, 214 float[] model, int modelOffset, float[] project, int projectOffset, 215 int[] view, int viewOffset, float[] obj, int objOffset) { 216 float[] scratch = sScratch; 217 synchronized(scratch) { 218 final int PM_OFFSET = 0; // 0..15 219 final int INVPM_OFFSET = 16; // 16..31 220 final int V_OFFSET = 0; // 0..3 Reuses PM_OFFSET space 221 Matrix.multiplyMM(scratch, PM_OFFSET, project, projectOffset, 222 model, modelOffset); 223 224 if (!Matrix.invertM(scratch, INVPM_OFFSET, scratch, PM_OFFSET)) { 225 return GL10.GL_FALSE; 226 } 227 228 scratch[V_OFFSET + 0] = 229 2.0f * (winX - view[viewOffset + 0]) / view[viewOffset + 2] 230 - 1.0f; 231 scratch[V_OFFSET + 1] = 232 2.0f * (winY - view[viewOffset + 1]) / view[viewOffset + 3] 233 - 1.0f; 234 scratch[V_OFFSET + 2] = 2.0f * winZ - 1.0f; 235 scratch[V_OFFSET + 3] = 1.0f; 236 237 Matrix.multiplyMV(obj, objOffset, scratch, INVPM_OFFSET, 238 scratch, V_OFFSET); 239 } 240 241 return GL10.GL_TRUE; 242 } 243 244 private static final float[] sScratch = new float[32]; 245 } 246