Home | History | Annotate | Download | only in opengl
      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      */
     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, objW}, that returns the
    207      *        computed homogeneous 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