Home | History | Annotate | Download | only in spritetext
      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 com.example.android.apis.graphics.spritetext;
     18 
     19 import android.opengl.Matrix;
     20 
     21 import java.nio.FloatBuffer;
     22 import java.nio.IntBuffer;
     23 
     24 /**
     25  * A matrix stack, similar to OpenGL ES's internal matrix stack.
     26  */
     27 public class MatrixStack {
     28     public MatrixStack() {
     29         commonInit(DEFAULT_MAX_DEPTH);
     30     }
     31 
     32     public MatrixStack(int maxDepth) {
     33         commonInit(maxDepth);
     34     }
     35 
     36     private void commonInit(int maxDepth) {
     37         mMatrix = new float[maxDepth * MATRIX_SIZE];
     38         mTemp = new float[MATRIX_SIZE * 2];
     39         glLoadIdentity();
     40     }
     41 
     42     public void glFrustumf(float left, float right, float bottom, float top,
     43             float near, float far) {
     44         Matrix.frustumM(mMatrix, mTop, left, right, bottom, top, near, far);
     45     }
     46 
     47     public void glFrustumx(int left, int right, int bottom, int top, int near,
     48             int far) {
     49         glFrustumf(fixedToFloat(left),fixedToFloat(right),
     50                 fixedToFloat(bottom), fixedToFloat(top),
     51                 fixedToFloat(near), fixedToFloat(far));
     52     }
     53 
     54     public void glLoadIdentity() {
     55         Matrix.setIdentityM(mMatrix, mTop);
     56     }
     57 
     58     public void glLoadMatrixf(float[] m, int offset) {
     59         System.arraycopy(m, offset, mMatrix, mTop, MATRIX_SIZE);
     60     }
     61 
     62     public void glLoadMatrixf(FloatBuffer m) {
     63         m.get(mMatrix, mTop, MATRIX_SIZE);
     64     }
     65 
     66     public void glLoadMatrixx(int[] m, int offset) {
     67         for(int i = 0; i < MATRIX_SIZE; i++) {
     68             mMatrix[mTop + i] = fixedToFloat(m[offset + i]);
     69         }
     70     }
     71 
     72     public void glLoadMatrixx(IntBuffer m) {
     73         for(int i = 0; i < MATRIX_SIZE; i++) {
     74             mMatrix[mTop + i] = fixedToFloat(m.get());
     75         }
     76     }
     77 
     78     public void glMultMatrixf(float[] m, int offset) {
     79         System.arraycopy(mMatrix, mTop, mTemp, 0, MATRIX_SIZE);
     80         Matrix.multiplyMM(mMatrix, mTop, mTemp, 0, m, offset);
     81     }
     82 
     83     public void glMultMatrixf(FloatBuffer m) {
     84         m.get(mTemp, MATRIX_SIZE, MATRIX_SIZE);
     85         glMultMatrixf(mTemp, MATRIX_SIZE);
     86     }
     87 
     88     public void glMultMatrixx(int[] m, int offset) {
     89         for(int i = 0; i < MATRIX_SIZE; i++) {
     90             mTemp[MATRIX_SIZE + i] = fixedToFloat(m[offset + i]);
     91         }
     92         glMultMatrixf(mTemp, MATRIX_SIZE);
     93     }
     94 
     95     public void glMultMatrixx(IntBuffer m) {
     96         for(int i = 0; i < MATRIX_SIZE; i++) {
     97             mTemp[MATRIX_SIZE + i] = fixedToFloat(m.get());
     98         }
     99         glMultMatrixf(mTemp, MATRIX_SIZE);
    100     }
    101 
    102     public void glOrthof(float left, float right, float bottom, float top,
    103             float near, float far) {
    104         Matrix.orthoM(mMatrix, mTop, left, right, bottom, top, near, far);
    105     }
    106 
    107     public void glOrthox(int left, int right, int bottom, int top, int near,
    108             int far) {
    109         glOrthof(fixedToFloat(left), fixedToFloat(right),
    110                 fixedToFloat(bottom), fixedToFloat(top),
    111                 fixedToFloat(near), fixedToFloat(far));
    112     }
    113 
    114     public void glPopMatrix() {
    115         preflight_adjust(-1);
    116         adjust(-1);
    117     }
    118 
    119     public void glPushMatrix() {
    120         preflight_adjust(1);
    121         System.arraycopy(mMatrix, mTop, mMatrix, mTop + MATRIX_SIZE,
    122                 MATRIX_SIZE);
    123         adjust(1);
    124     }
    125 
    126     public void glRotatef(float angle, float x, float y, float z) {
    127         Matrix.setRotateM(mTemp, 0, angle, x, y, z);
    128         System.arraycopy(mMatrix, mTop, mTemp, MATRIX_SIZE, MATRIX_SIZE);
    129         Matrix.multiplyMM(mMatrix, mTop, mTemp, MATRIX_SIZE, mTemp, 0);
    130     }
    131 
    132     public void glRotatex(int angle, int x, int y, int z) {
    133         glRotatef(angle, fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
    134     }
    135 
    136     public void glScalef(float x, float y, float z) {
    137         Matrix.scaleM(mMatrix, mTop, x, y, z);
    138     }
    139 
    140     public void glScalex(int x, int y, int z) {
    141         glScalef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
    142     }
    143 
    144     public void glTranslatef(float x, float y, float z) {
    145         Matrix.translateM(mMatrix, mTop, x, y, z);
    146     }
    147 
    148     public void glTranslatex(int x, int y, int z) {
    149         glTranslatef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
    150     }
    151 
    152     public void getMatrix(float[] dest, int offset) {
    153         System.arraycopy(mMatrix, mTop, dest, offset, MATRIX_SIZE);
    154     }
    155 
    156     private float fixedToFloat(int x) {
    157         return x * (1.0f / 65536.0f);
    158     }
    159 
    160     private void preflight_adjust(int dir) {
    161         int newTop = mTop + dir * MATRIX_SIZE;
    162         if (newTop < 0) {
    163             throw new IllegalArgumentException("stack underflow");
    164         }
    165         if (newTop + MATRIX_SIZE > mMatrix.length) {
    166             throw new IllegalArgumentException("stack overflow");
    167         }
    168     }
    169 
    170     private void adjust(int dir) {
    171         mTop += dir * MATRIX_SIZE;
    172     }
    173 
    174     private final static int DEFAULT_MAX_DEPTH = 32;
    175     private final static int MATRIX_SIZE = 16;
    176     private float[] mMatrix;
    177     private int mTop;
    178     private float[] mTemp;
    179 }
    180