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 {
MatrixStack()28     public MatrixStack() {
29         commonInit(DEFAULT_MAX_DEPTH);
30     }
31 
MatrixStack(int maxDepth)32     public MatrixStack(int maxDepth) {
33         commonInit(maxDepth);
34     }
35 
commonInit(int maxDepth)36     private void commonInit(int maxDepth) {
37         mMatrix = new float[maxDepth * MATRIX_SIZE];
38         mTemp = new float[MATRIX_SIZE * 2];
39         glLoadIdentity();
40     }
41 
glFrustumf(float left, float right, float bottom, float top, float near, float far)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 
glFrustumx(int left, int right, int bottom, int top, int near, int far)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 
glLoadIdentity()54     public void glLoadIdentity() {
55         Matrix.setIdentityM(mMatrix, mTop);
56     }
57 
glLoadMatrixf(float[] m, int offset)58     public void glLoadMatrixf(float[] m, int offset) {
59         System.arraycopy(m, offset, mMatrix, mTop, MATRIX_SIZE);
60     }
61 
glLoadMatrixf(FloatBuffer m)62     public void glLoadMatrixf(FloatBuffer m) {
63         m.get(mMatrix, mTop, MATRIX_SIZE);
64     }
65 
glLoadMatrixx(int[] m, int offset)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 
glLoadMatrixx(IntBuffer m)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 
glMultMatrixf(float[] m, int offset)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 
glMultMatrixf(FloatBuffer m)83     public void glMultMatrixf(FloatBuffer m) {
84         m.get(mTemp, MATRIX_SIZE, MATRIX_SIZE);
85         glMultMatrixf(mTemp, MATRIX_SIZE);
86     }
87 
glMultMatrixx(int[] m, int offset)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 
glMultMatrixx(IntBuffer m)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 
glOrthof(float left, float right, float bottom, float top, float near, float far)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 
glOrthox(int left, int right, int bottom, int top, int near, int far)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 
glPopMatrix()114     public void glPopMatrix() {
115         preflight_adjust(-1);
116         adjust(-1);
117     }
118 
glPushMatrix()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 
glRotatef(float angle, float x, float y, float z)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 
glRotatex(int angle, int x, int y, int z)132     public void glRotatex(int angle, int x, int y, int z) {
133         glRotatef(angle, fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
134     }
135 
glScalef(float x, float y, float z)136     public void glScalef(float x, float y, float z) {
137         Matrix.scaleM(mMatrix, mTop, x, y, z);
138     }
139 
glScalex(int x, int y, int z)140     public void glScalex(int x, int y, int z) {
141         glScalef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
142     }
143 
glTranslatef(float x, float y, float z)144     public void glTranslatef(float x, float y, float z) {
145         Matrix.translateM(mMatrix, mTop, x, y, z);
146     }
147 
glTranslatex(int x, int y, int z)148     public void glTranslatex(int x, int y, int z) {
149         glTranslatef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z));
150     }
151 
getMatrix(float[] dest, int offset)152     public void getMatrix(float[] dest, int offset) {
153         System.arraycopy(mMatrix, mTop, dest, offset, MATRIX_SIZE);
154     }
155 
fixedToFloat(int x)156     private float fixedToFloat(int x) {
157         return x * (1.0f / 65536.0f);
158     }
159 
preflight_adjust(int dir)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 
adjust(int dir)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