MatrixStack.java revision 1bb0c42b2a62f580eea4764d6a4434ffecfbf353
1package com.cooliris.media; 2 3/* 4 * Copyright (C) 2007 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19import android.opengl.Matrix; 20 21import java.nio.FloatBuffer; 22import java.nio.IntBuffer; 23 24/** 25 * A matrix stack, similar to OpenGL ES's internal matrix stack. 26 */ 27public 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 apply(float[] mCoordsIn, float[] mCoordsOut) { 43 Matrix.multiplyMV(mCoordsOut, 0, mMatrix, mTop, mCoordsIn, 0); 44 } 45 46 public void glFrustumf(float left, float right, float bottom, float top, float near, float far) { 47 Matrix.frustumM(mMatrix, mTop, left, right, bottom, top, near, far); 48 } 49 50 public void glFrustumx(int left, int right, int bottom, int top, int near, int far) { 51 glFrustumf(fixedToFloat(left), fixedToFloat(right), fixedToFloat(bottom), fixedToFloat(top), fixedToFloat(near), 52 fixedToFloat(far)); 53 } 54 55 public void glLoadIdentity() { 56 Matrix.setIdentityM(mMatrix, mTop); 57 } 58 59 public void glLoadMatrixf(float[] m, int offset) { 60 System.arraycopy(m, offset, mMatrix, mTop, MATRIX_SIZE); 61 } 62 63 public void glLoadMatrixf(FloatBuffer m) { 64 m.get(mMatrix, mTop, MATRIX_SIZE); 65 } 66 67 public void glLoadMatrixx(int[] m, int offset) { 68 for (int i = 0; i < MATRIX_SIZE; i++) { 69 mMatrix[mTop + i] = fixedToFloat(m[offset + i]); 70 } 71 } 72 73 public void glLoadMatrixx(IntBuffer m) { 74 for (int i = 0; i < MATRIX_SIZE; i++) { 75 mMatrix[mTop + i] = fixedToFloat(m.get()); 76 } 77 } 78 79 public void glMultMatrixf(float[] m, int offset) { 80 System.arraycopy(mMatrix, mTop, mTemp, 0, MATRIX_SIZE); 81 Matrix.multiplyMM(mMatrix, mTop, mTemp, 0, m, offset); 82 } 83 84 public void glMultMatrixf(FloatBuffer m) { 85 m.get(mTemp, MATRIX_SIZE, MATRIX_SIZE); 86 glMultMatrixf(mTemp, MATRIX_SIZE); 87 } 88 89 public void glMultMatrixx(int[] m, int offset) { 90 for (int i = 0; i < MATRIX_SIZE; i++) { 91 mTemp[MATRIX_SIZE + i] = fixedToFloat(m[offset + i]); 92 } 93 glMultMatrixf(mTemp, MATRIX_SIZE); 94 } 95 96 public void glMultMatrixx(IntBuffer m) { 97 for (int i = 0; i < MATRIX_SIZE; i++) { 98 mTemp[MATRIX_SIZE + i] = fixedToFloat(m.get()); 99 } 100 glMultMatrixf(mTemp, MATRIX_SIZE); 101 } 102 103 public void glOrthof(float left, float right, float bottom, float top, 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, int far) { 108 glOrthof(fixedToFloat(left), fixedToFloat(right), fixedToFloat(bottom), fixedToFloat(top), fixedToFloat(near), 109 fixedToFloat(far)); 110 } 111 112 public void glPopMatrix() { 113 preflight_adjust(-1); 114 adjust(-1); 115 } 116 117 public void glPushMatrix() { 118 preflight_adjust(1); 119 System.arraycopy(mMatrix, mTop, mMatrix, mTop + MATRIX_SIZE, MATRIX_SIZE); 120 adjust(1); 121 } 122 123 public void glRotatef(float angle, float x, float y, float z) { 124 Matrix.setRotateM(mTemp, 0, angle, x, y, z); 125 System.arraycopy(mMatrix, mTop, mTemp, MATRIX_SIZE, MATRIX_SIZE); 126 Matrix.multiplyMM(mMatrix, mTop, mTemp, MATRIX_SIZE, mTemp, 0); 127 } 128 129 public void glRotatex(int angle, int x, int y, int z) { 130 glRotatef(angle, fixedToFloat(x), fixedToFloat(y), fixedToFloat(z)); 131 } 132 133 public void glScalef(float x, float y, float z) { 134 Matrix.scaleM(mMatrix, mTop, x, y, z); 135 } 136 137 public void glScalex(int x, int y, int z) { 138 glScalef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z)); 139 } 140 141 public void glTranslatef(float x, float y, float z) { 142 Matrix.translateM(mMatrix, mTop, x, y, z); 143 } 144 145 public void glTranslatex(int x, int y, int z) { 146 glTranslatef(fixedToFloat(x), fixedToFloat(y), fixedToFloat(z)); 147 } 148 149 public void getMatrix(float[] dest, int offset) { 150 System.arraycopy(mMatrix, mTop, dest, offset, MATRIX_SIZE); 151 } 152 153 private float fixedToFloat(int x) { 154 return x * (1.0f / 65536.0f); 155 } 156 157 private void preflight_adjust(int dir) { 158 int newTop = mTop + dir * MATRIX_SIZE; 159 if (newTop < 0) { 160 throw new IllegalArgumentException("stack underflow"); 161 } 162 if (newTop + MATRIX_SIZE > mMatrix.length) { 163 throw new IllegalArgumentException("stack overflow"); 164 } 165 } 166 167 private void adjust(int dir) { 168 mTop += dir * MATRIX_SIZE; 169 } 170 171 private final static int DEFAULT_MAX_DEPTH = 32; 172 private final static int MATRIX_SIZE = 16; 173 private float[] mMatrix; 174 private int mTop; 175 private float[] mTemp; 176} 177