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