1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17a4eae1abb4f2547dfbda84301ee764ce35464881John Reckpackage com.android.gallery3d.glrenderer; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 197da54d7e41e04ea5122009b40de19be0724e1ca4George Mountimport android.graphics.Bitmap; 2064072a071151b55fcbf97f6204d3c2258db386faGeorge Mountimport android.graphics.Rect; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.RectF; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.opengl.GLU; 237da54d7e41e04ea5122009b40de19be0724e1ca4George Mountimport android.opengl.GLUtils; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.opengl.Matrix; 25a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport android.util.Log; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 272b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.common.Utils; 282b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.util.IntArray; 292b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 30a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport junit.framework.Assert; 31a4eae1abb4f2547dfbda84301ee764ce35464881John Reck 327da54d7e41e04ea5122009b40de19be0724e1ca4George Mountimport java.nio.Buffer; 33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.ByteBuffer; 34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.ByteOrder; 35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.nio.FloatBuffer; 36cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Changimport java.util.ArrayList; 372b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL10; 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL11; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport javax.microedition.khronos.opengles.GL11Ext; 418ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Linimport javax.microedition.khronos.opengles.GL11ExtensionPack; 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 4350b33abe053ccab7be3d1bca2328e792507963d4George Mountpublic class GLES11Canvas implements GLCanvas { 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @SuppressWarnings("unused") 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "GLCanvasImp"; 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final float OPAQUE_ALPHA = 0.95f; 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int OFFSET_FILL_RECT = 0; 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int OFFSET_DRAW_LINE = 4; 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int OFFSET_DRAW_RECT = 6; 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final float[] BOX_COORDINATES = { 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 0, 0, 1, 0, 0, 1, 1, 1, // used for filling a rectangle 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 0, 0, 1, 1, // used for drawing a line 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 0, 0, 0, 1, 1, 1, 1, 0}; // used for drawing the outline of a rectangle 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private GL11 mGL; 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final float mMatrixValues[] = new float[16]; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final float mTextureMatrixValues[] = new float[16]; 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 62174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // The results of mapPoints are stored in this buffer, and the order is 63174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // x1, y1, x2, y2. 64174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang private final float mMapPointsBuffer[] = new float[4]; 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final float mTextureColor[] = new float[4]; 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mBoxCoords; 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private GLState mGLState; 718ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private final ArrayList<RawTexture> mTargetStack = new ArrayList<RawTexture>(); 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private float mAlpha; 748ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private final ArrayList<ConfigState> mRestoreStack = new ArrayList<ConfigState>(); 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private ConfigState mRecycledRestoreAction; 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final RectF mDrawTextureSourceRect = new RectF(); 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final RectF mDrawTextureTargetRect = new RectF(); 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final float[] mTempMatrix = new float[32]; 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final IntArray mUnboundTextures = new IntArray(); 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final IntArray mDeleteBuffers = new IntArray(); 828ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private int mScreenWidth; 838ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private int mScreenHeight; 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mBlendEnabled = true; 858ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private int mFrameBuffer[] = new int[1]; 867da54d7e41e04ea5122009b40de19be0724e1ca4George Mount private static float[] sCropRect = new float[4]; 878ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 888ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private RawTexture mTargetTexture; 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Drawing statistics 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int mCountDrawLine; 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int mCountFillRect; 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int mCountDrawMesh; 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int mCountTextureRect; 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int mCountTextureOES; 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 9750b33abe053ccab7be3d1bca2328e792507963d4George Mount private static GLId mGLId = new GLES11IdImpl(); 9850b33abe053ccab7be3d1bca2328e792507963d4George Mount 9950b33abe053ccab7be3d1bca2328e792507963d4George Mount public GLES11Canvas(GL11 gl) { 10050b33abe053ccab7be3d1bca2328e792507963d4George Mount mGL = gl; 10150b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLState = new GLState(gl); 10250b33abe053ccab7be3d1bca2328e792507963d4George Mount // First create an nio buffer, then create a VBO from it. 10350b33abe053ccab7be3d1bca2328e792507963d4George Mount int size = BOX_COORDINATES.length * Float.SIZE / Byte.SIZE; 10450b33abe053ccab7be3d1bca2328e792507963d4George Mount FloatBuffer xyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer(); 10550b33abe053ccab7be3d1bca2328e792507963d4George Mount xyBuffer.put(BOX_COORDINATES, 0, BOX_COORDINATES.length).position(0); 10650b33abe053ccab7be3d1bca2328e792507963d4George Mount 10750b33abe053ccab7be3d1bca2328e792507963d4George Mount int[] name = new int[1]; 10850b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glGenBuffers(1, name, 0); 10950b33abe053ccab7be3d1bca2328e792507963d4George Mount mBoxCoords = name[0]; 11050b33abe053ccab7be3d1bca2328e792507963d4George Mount 11150b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords); 11250b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glBufferData(GL11.GL_ARRAY_BUFFER, xyBuffer.capacity() * (Float.SIZE / Byte.SIZE), 11350b33abe053ccab7be3d1bca2328e792507963d4George Mount xyBuffer, GL11.GL_STATIC_DRAW); 11450b33abe053ccab7be3d1bca2328e792507963d4George Mount 11550b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glVertexPointer(2, GL11.GL_FLOAT, 0, 0); 11650b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0); 11750b33abe053ccab7be3d1bca2328e792507963d4George Mount 11850b33abe053ccab7be3d1bca2328e792507963d4George Mount // Enable the texture coordinate array for Texture 1 11950b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glClientActiveTexture(GL11.GL_TEXTURE1); 12050b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0); 12150b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glClientActiveTexture(GL11.GL_TEXTURE0); 12250b33abe053ccab7be3d1bca2328e792507963d4George Mount gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 12350b33abe053ccab7be3d1bca2328e792507963d4George Mount 12450b33abe053ccab7be3d1bca2328e792507963d4George Mount // mMatrixValues and mAlpha will be initialized in setSize() 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1277817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setSize(int width, int height) { 129a4eae1abb4f2547dfbda84301ee764ce35464881John Reck Assert.assertTrue(width >= 0 && height >= 0); 1308ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 1318ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin if (mTargetTexture == null) { 1328ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin mScreenWidth = width; 1338ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin mScreenHeight = height; 1348ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 1358ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin mAlpha = 1.0f; 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = mGL; 138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glViewport(0, 0, width, height); 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glMatrixMode(GL11.GL_PROJECTION); 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glLoadIdentity(); 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GLU.gluOrtho2D(gl, 0, width, 0, height); 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glMatrixMode(GL11.GL_MODELVIEW); 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glLoadIdentity(); 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1468ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin float matrix[] = mMatrixValues; 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Matrix.setIdentityM(matrix, 0); 1488ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin // to match the graphic coordinate system in android, we flip it vertically. 1498ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin if (mTargetTexture == null) { 1508ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin Matrix.translateM(matrix, 0, 0, height, 0); 1518ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin Matrix.scaleM(matrix, 0, 1, -1, 1); 1528ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1557817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setAlpha(float alpha) { 157a4eae1abb4f2547dfbda84301ee764ce35464881John Reck Assert.assertTrue(alpha >= 0 && alpha <= 1); 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAlpha = alpha; 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1617817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 1627b83fb8e3a8978b33a6b9bfc56d85fe2c1a9cf06Chih-Chung Chang public float getAlpha() { 1637b83fb8e3a8978b33a6b9bfc56d85fe2c1a9cf06Chih-Chung Chang return mAlpha; 1647b83fb8e3a8978b33a6b9bfc56d85fe2c1a9cf06Chih-Chung Chang } 1657b83fb8e3a8978b33a6b9bfc56d85fe2c1a9cf06Chih-Chung Chang 1667817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void multiplyAlpha(float alpha) { 168a4eae1abb4f2547dfbda84301ee764ce35464881John Reck Assert.assertTrue(alpha >= 0 && alpha <= 1); 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAlpha *= alpha; 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static ByteBuffer allocateDirectNativeOrderBuffer(int size) { 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()); 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void drawRect(float x, float y, float width, float height, GLPaint paint) { 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = mGL; 179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setColorMode(paint.getColor(), mAlpha); 181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setLineWidth(paint.getLineWidth()); 182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin saveTransform(); 184174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang translate(x, y); 185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin scale(width, height, 1); 186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glLoadMatrixf(mMatrixValues, 0); 188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glDrawArrays(GL11.GL_LINE_LOOP, OFFSET_DRAW_RECT, 4); 189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin restoreTransform(); 191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountDrawLine++; 192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1947817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) { 196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = mGL; 197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setColorMode(paint.getColor(), mAlpha); 199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setLineWidth(paint.getLineWidth()); 200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin saveTransform(); 202174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang translate(x1, y1); 203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin scale(x2 - x1, y2 - y1, 1); 204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glLoadMatrixf(mMatrixValues, 0); 206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glDrawArrays(GL11.GL_LINE_STRIP, OFFSET_DRAW_LINE, 2); 207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin restoreTransform(); 209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountDrawLine++; 210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2127817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void fillRect(float x, float y, float width, float height, int color) { 214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setColorMode(color, mAlpha); 215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = mGL; 216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin saveTransform(); 218174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang translate(x, y); 219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin scale(width, height, 1); 220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glLoadMatrixf(mMatrixValues, 0); 222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4); 223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin restoreTransform(); 225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountFillRect++; 226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2287817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void translate(float x, float y, float z) { 230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Matrix.translateM(mMatrixValues, 0, x, y, z); 231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 233174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // This is a faster version of translate(x, y, z) because 234174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // (1) we knows z = 0, (2) we inline the Matrix.translateM call, 235174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // (3) we unroll the loop 2367817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 237174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang public void translate(float x, float y) { 238174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float[] m = mMatrixValues; 239174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang m[12] += m[0] * x + m[4] * y; 240174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang m[13] += m[1] * x + m[5] * y; 241174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang m[14] += m[2] * x + m[6] * y; 242174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang m[15] += m[3] * x + m[7] * y; 243174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang } 244174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang 2457817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void scale(float sx, float sy, float sz) { 247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Matrix.scaleM(mMatrixValues, 0, sx, sy, sz); 248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2507817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void rotate(float angle, float x, float y, float z) { 252cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang if (angle == 0) return; 253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float[] temp = mTempMatrix; 254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Matrix.setRotateM(temp, 0, angle, x, y, z); 255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Matrix.multiplyMM(temp, 16, mMatrixValues, 0, temp, 0); 256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin System.arraycopy(temp, 16, mMatrixValues, 0, 16); 257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2597817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void multiplyMatrix(float matrix[], int offset) { 261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float[] temp = mTempMatrix; 262532d93caddc91a7aa33ca113adbc0b8255d498ebChih-Chung Chang Matrix.multiplyMM(temp, 0, mMatrixValues, 0, matrix, offset); 263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin System.arraycopy(temp, 0, mMatrixValues, 0, 16); 264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void textureRect(float x, float y, float width, float height) { 267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11 gl = mGL; 268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin saveTransform(); 270174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang translate(x, y); 271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin scale(width, height, 1); 272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glLoadMatrixf(mMatrixValues, 0); 274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4); 275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin restoreTransform(); 277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountTextureRect++; 278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 2807817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer, 282f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int uvBuffer, int indexBuffer, int indexCount) { 283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float alpha = mAlpha; 284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!bindTexture(tex)) return; 285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 286f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setBlendEnabled(mBlendEnabled 287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin && (!tex.isOpaque() || alpha < OPAQUE_ALPHA)); 288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setTextureAlpha(alpha); 289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Reset the texture matrix. We will set our own texture coordinates 291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // below. 292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setTextureCoords(0, 0, 1, 1); 293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 294f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin saveTransform(); 295174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang translate(x, y); 296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glLoadMatrixf(mMatrixValues, 0); 298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, xyBuffer); 300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0); 301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, uvBuffer); 303f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0); 304f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 305f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 306f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glDrawElements(GL11.GL_TRIANGLE_STRIP, 307f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin indexCount, GL11.GL_UNSIGNED_BYTE, 0); 308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords); 310f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glVertexPointer(2, GL11.GL_FLOAT, 0, 0); 311f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0); 312f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 313f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin restoreTransform(); 314f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountDrawMesh++; 315f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 316f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 317174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // Transforms two points by the given matrix m. The result 318174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // {x1', y1', x2', y2'} are stored in mMapPointsBuffer and also returned. 319174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang private float[] mapPoints(float m[], int x1, int y1, int x2, int y2) { 320174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float[] r = mMapPointsBuffer; 321174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang 322174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // Multiply m and (x1 y1 0 1) to produce (x3 y3 z3 w3). z3 is unused. 323174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float x3 = m[0] * x1 + m[4] * y1 + m[12]; 324174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float y3 = m[1] * x1 + m[5] * y1 + m[13]; 325174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float w3 = m[3] * x1 + m[7] * y1 + m[15]; 326174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang r[0] = x3 / w3; 327174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang r[1] = y3 / w3; 328174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang 329174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang // Same for x2 y2. 330174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float x4 = m[0] * x2 + m[4] * y2 + m[12]; 331174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float y4 = m[1] * x2 + m[5] * y2 + m[13]; 332174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang float w4 = m[3] * x2 + m[7] * y2 + m[15]; 333174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang r[2] = x4 / w4; 334174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang r[3] = y4 / w4; 335174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang 336174cac8f92029fc2829c94f274e70793ae948931Chih-Chung Chang return r; 337f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 338f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 339f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void drawBoundTexture( 340f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin BasicTexture texture, int x, int y, int width, int height) { 341f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Test whether it has been rotated or flipped, if so, glDrawTexiOES 342f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // won't work 343f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (isMatrixRotatedOrFlipped(mMatrixValues)) { 3441a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang if (texture.hasBorder()) { 3451a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang setTextureCoords( 3461a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang 1.0f / texture.getTextureWidth(), 3471a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang 1.0f / texture.getTextureHeight(), 3481a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang (texture.getWidth() - 1.0f) / texture.getTextureWidth(), 3491a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang (texture.getHeight() - 1.0f) / texture.getTextureHeight()); 3501a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang } else { 3511a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang setTextureCoords(0, 0, 3521a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang (float) texture.getWidth() / texture.getTextureWidth(), 3531a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang (float) texture.getHeight() / texture.getTextureHeight()); 3541a088db165c138f57d9445ca0b7e50fe90d3ad1dChih-Chung Chang } 355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin textureRect(x, y, width, height); 356f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // draw the rect from bottom-left to top-right 358f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float points[] = mapPoints( 359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mMatrixValues, x, y + height, x + width, y); 360cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang x = (int) (points[0] + 0.5f); 361cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang y = (int) (points[1] + 0.5f); 362cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang width = (int) (points[2] + 0.5f) - x; 363cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang height = (int) (points[3] + 0.5f) - y; 364f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (width > 0 && height > 0) { 365f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ((GL11Ext) mGL).glDrawTexiOES(x, y, 0, width, height); 366f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountTextureOES++; 367f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 368f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 369f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 370f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3717817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 372f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void drawTexture( 373f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin BasicTexture texture, int x, int y, int width, int height) { 374f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin drawTexture(texture, x, y, width, height, mAlpha); 375f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 376f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3777b83fb8e3a8978b33a6b9bfc56d85fe2c1a9cf06Chih-Chung Chang private void drawTexture(BasicTexture texture, 378f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int x, int y, int width, int height, float alpha) { 379f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (width <= 0 || height <= 0) return; 380f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 381f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setBlendEnabled(mBlendEnabled 382f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin && (!texture.isOpaque() || alpha < OPAQUE_ALPHA)); 383f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!bindTexture(texture)) return; 384f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setTextureAlpha(alpha); 385f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin drawBoundTexture(texture, x, y, width, height); 386f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 387f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 3887817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 389f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void drawTexture(BasicTexture texture, RectF source, RectF target) { 390f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (target.width() <= 0 || target.height() <= 0) return; 391f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 392f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Copy the input to avoid changing it. 393f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDrawTextureSourceRect.set(source); 394f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDrawTextureTargetRect.set(target); 395f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source = mDrawTextureSourceRect; 396f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin target = mDrawTextureTargetRect; 397f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 398f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setBlendEnabled(mBlendEnabled 399f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin && (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA)); 400f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!bindTexture(texture)) return; 401f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin convertCoordinate(source, target, texture); 402f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setTextureCoords(source); 403f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setTextureAlpha(mAlpha); 404f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin textureRect(target.left, target.top, target.width(), target.height()); 405f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 406f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 4077817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 408b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public void drawTexture(BasicTexture texture, float[] mTextureTransform, 409b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang int x, int y, int w, int h) { 410b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGLState.setBlendEnabled(mBlendEnabled 411b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang && (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA)); 412b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang if (!bindTexture(texture)) return; 413b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang setTextureCoords(mTextureTransform); 414b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGLState.setTextureAlpha(mAlpha); 415b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang textureRect(x, y, w, h); 416b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 417b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 418f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // This function changes the source coordinate to the texture coordinates. 419f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // It also clips the source and target coordinates if it is beyond the 420f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // bound of the texture. 421a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin private static void convertCoordinate(RectF source, RectF target, 422f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin BasicTexture texture) { 423f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 424f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int width = texture.getWidth(); 425f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int height = texture.getHeight(); 426f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int texWidth = texture.getTextureWidth(); 427f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int texHeight = texture.getTextureHeight(); 428f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Convert to texture coordinates 429f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source.left /= texWidth; 430f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source.right /= texWidth; 431f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source.top /= texHeight; 432f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source.bottom /= texHeight; 433f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 434f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Clip if the rendering range is beyond the bound of the texture. 435f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float xBound = (float) width / texWidth; 436f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (source.right > xBound) { 437f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin target.right = target.left + target.width() * 438f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin (xBound - source.left) / source.width(); 439f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source.right = xBound; 440f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 441f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float yBound = (float) height / texHeight; 442f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (source.bottom > yBound) { 443f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin target.bottom = target.top + target.height() * 444f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin (yBound - source.top) / source.height(); 445f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin source.bottom = yBound; 446f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 447f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 448f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 4497817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 450f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void drawMixed(BasicTexture from, 451f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int toColor, float ratio, int x, int y, int w, int h) { 452f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin drawMixed(from, toColor, ratio, x, y, w, h, mAlpha); 453f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 454f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 455f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean bindTexture(BasicTexture texture) { 456f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (!texture.onBind(this)) return false; 457b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang int target = texture.getTarget(); 458b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGLState.setTextureTarget(target); 459b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGL.glBindTexture(target, texture.getId()); 460f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 461f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 462f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 463f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void setTextureColor(float r, float g, float b, float alpha) { 464f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float[] color = mTextureColor; 465f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin color[0] = r; 466f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin color[1] = g; 467f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin color[2] = b; 468f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin color[3] = alpha; 469f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 470f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 471a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin private void setMixedColor(int toColor, float ratio, float alpha) { 472f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // 473f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // The formula we want: 474f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // alpha * ((1 - ratio) * from + ratio * to) 475fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin // 476f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // The formula that GL supports is in the form of: 477fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin // combo * from + (1 - combo) * to * scale 478f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // 479fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin // So, we have combo = alpha * (1 - ratio) 480fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin // and scale = alpha * ratio / (1 - combo) 481f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // 482fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin float combo = alpha * (1 - ratio); 483fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin float scale = alpha * ratio / (1 - combo); 484f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 485f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Specify the interpolation factor via the alpha component of 486f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // GL_TEXTURE_ENV_COLORs. 487f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // RGB component are get from toColor and will used as SRC1 488fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin float colorScale = scale * (toColor >>> 24) / (0xff * 0xff); 489fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin setTextureColor(((toColor >>> 16) & 0xff) * colorScale, 490fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin ((toColor >>> 8) & 0xff) * colorScale, 491fc7efade75629450c0c160329fb42b3dbd5361f4Owen Lin (toColor & 0xff) * colorScale, combo); 492a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin GL11 gl = mGL; 493f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, mTextureColor, 0); 494f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 495f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE); 496f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE); 497f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_RGB, GL11.GL_CONSTANT); 498f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_RGB, GL11.GL_SRC_COLOR); 499f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC1_ALPHA, GL11.GL_CONSTANT); 500f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND1_ALPHA, GL11.GL_SRC_ALPHA); 501f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 502f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Wire up the interpolation factor for RGB. 503f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT); 504f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA); 505f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 506f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Wire up the interpolation factor for alpha. 507f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT); 508f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA); 509f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 510a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin } 511a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 512a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin @Override 513a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin public void drawMixed(BasicTexture from, int toColor, float ratio, 514a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin RectF source, RectF target) { 515a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin if (target.width() <= 0 || target.height() <= 0) return; 516a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 517a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin if (ratio <= 0.01f) { 518a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin drawTexture(from, source, target); 519a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin return; 520a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin } else if (ratio >= 1) { 521a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin fillRect(target.left, target.top, target.width(), target.height(), toColor); 522a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin return; 523a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin } 524a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 525a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin float alpha = mAlpha; 526a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 527a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin // Copy the input to avoid changing it. 528a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin mDrawTextureSourceRect.set(source); 529a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin mDrawTextureTargetRect.set(target); 530a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin source = mDrawTextureSourceRect; 531a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin target = mDrawTextureTargetRect; 532a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 533a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque() 534a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA)); 535a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 536a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin if (!bindTexture(from)) return; 537a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 538a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin // Interpolate the RGB and alpha values between both textures. 539a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin mGLState.setTexEnvMode(GL11.GL_COMBINE); 540a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin setMixedColor(toColor, ratio, alpha); 541a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin convertCoordinate(source, target, from); 542a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin setTextureCoords(source); 543a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin textureRect(target.left, target.top, target.width(), target.height()); 544a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin mGLState.setTexEnvMode(GL11.GL_REPLACE); 545a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin } 546a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 547a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin private void drawMixed(BasicTexture from, int toColor, 548a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin float ratio, int x, int y, int width, int height, float alpha) { 549a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin // change from 0 to 0.01f to prevent getting divided by zero below 550a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin if (ratio <= 0.01f) { 551a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin drawTexture(from, x, y, width, height, alpha); 552a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin return; 553a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin } else if (ratio >= 1) { 554a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin fillRect(x, y, width, height, toColor); 555a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin return; 556a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin } 557a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 558a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin mGLState.setBlendEnabled(mBlendEnabled && (!from.isOpaque() 559a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin || !Utils.isOpaque(toColor) || alpha < OPAQUE_ALPHA)); 560a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 561a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin final GL11 gl = mGL; 562a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin if (!bindTexture(from)) return; 563a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 564a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin // Interpolate the RGB and alpha values between both textures. 565a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin mGLState.setTexEnvMode(GL11.GL_COMBINE); 566a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin setMixedColor(toColor, ratio, alpha); 567a8f3473271cb4bfc5b47f520402bad7cddb5d3e8Owen Lin 568f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin drawBoundTexture(from, x, y, width, height); 569f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGLState.setTexEnvMode(GL11.GL_REPLACE); 570f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 571f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 572f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // TODO: the code only work for 2D should get fixed for 3D or removed 573f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int MSKEW_X = 4; 574f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int MSKEW_Y = 1; 575f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int MSCALE_X = 0; 576f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final int MSCALE_Y = 5; 577f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 578f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static boolean isMatrixRotatedOrFlipped(float matrix[]) { 579f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin final float eps = 1e-5f; 580f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return Math.abs(matrix[MSKEW_X]) > eps 581f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin || Math.abs(matrix[MSKEW_Y]) > eps 582f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin || matrix[MSCALE_X] < -eps 583f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin || matrix[MSCALE_Y] > eps; 584f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 585f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 586f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class GLState { 587f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 588f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final GL11 mGL; 589f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 590f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private int mTexEnvMode = GL11.GL_REPLACE; 591f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private float mTextureAlpha = 1.0f; 5921cbde8f63a4862e814078da9b7cefce0c6291dabOwen Lin private int mTextureTarget = GL11.GL_TEXTURE_2D; 593f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mBlendEnabled = true; 594f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private float mLineWidth = 1.0f; 595f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private boolean mLineSmooth = false; 596f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 597f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public GLState(GL11 gl) { 598f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL = gl; 599f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 600f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Disable unused state 601f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glDisable(GL11.GL_LIGHTING); 602f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 603f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Enable used features 604f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glEnable(GL11.GL_DITHER); 605f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 606f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 607f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 608f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glEnable(GL11.GL_TEXTURE_2D); 609f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 610f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glTexEnvf(GL11.GL_TEXTURE_ENV, 611f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE); 612f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 613f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Set the background color 614f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glClearColor(0f, 0f, 0f, 0f); 615f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 616f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glEnable(GL11.GL_BLEND); 617f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); 618f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 619f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // We use 565 or 8888 format, so set the alignment to 2 bytes/pixel. 620f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin gl.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 2); 621f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 622f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 623f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setTexEnvMode(int mode) { 624f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mTexEnvMode == mode) return; 625f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTexEnvMode = mode; 626f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, mode); 627f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 628f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 629f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setLineWidth(float width) { 630f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mLineWidth == width) return; 631f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mLineWidth = width; 632f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glLineWidth(width); 633f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 634f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 635f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setTextureAlpha(float alpha) { 636f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mTextureAlpha == alpha) return; 637f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureAlpha = alpha; 638f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (alpha >= OPAQUE_ALPHA) { 639f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // The alpha is need for those texture without alpha channel 640f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glColor4f(1, 1, 1, 1); 641f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setTexEnvMode(GL11.GL_REPLACE); 642f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 643f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glColor4f(alpha, alpha, alpha, alpha); 644f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setTexEnvMode(GL11.GL_MODULATE); 645f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 646f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 647f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 648f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setColorMode(int color, float alpha) { 649f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setBlendEnabled(!Utils.isOpaque(color) || alpha < OPAQUE_ALPHA); 650f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 651f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // Set mTextureAlpha to an invalid value, so that it will reset 652f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // again in setTextureAlpha(float) later. 653f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureAlpha = -1.0f; 654f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 655b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang setTextureTarget(0); 656f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 657f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float prealpha = (color >>> 24) * alpha * 65535f / 255f / 255f; 658f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glColor4x( 659f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Math.round(((color >> 16) & 0xFF) * prealpha), 660f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Math.round(((color >> 8) & 0xFF) * prealpha), 661f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Math.round((color & 0xFF) * prealpha), 662f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Math.round(255 * prealpha)); 663f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 664f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 665b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang // target is a value like GL_TEXTURE_2D. If target = 0, texturing is disabled. 666b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang public void setTextureTarget(int target) { 667b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang if (mTextureTarget == target) return; 668b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang if (mTextureTarget != 0) { 669b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGL.glDisable(mTextureTarget); 670b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 671b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mTextureTarget = target; 672b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang if (mTextureTarget != 0) { 673b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGL.glEnable(mTextureTarget); 674f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 675f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 676f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 677f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setBlendEnabled(boolean enabled) { 678f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mBlendEnabled == enabled) return; 679f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mBlendEnabled = enabled; 680f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (enabled) { 681f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glEnable(GL11.GL_BLEND); 682f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 683f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glDisable(GL11.GL_BLEND); 684f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 685f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 686f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 687f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 6887817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 689915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu public void clearBuffer(float[] argb) { 690915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu if(argb != null && argb.length == 4) { 691915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu mGL.glClearColor(argb[1], argb[2], argb[3], argb[0]); 692915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu } else { 693915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu mGL.glClearColor(0, 0, 0, 1); 694915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu } 695f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glClear(GL10.GL_COLOR_BUFFER_BIT); 696f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 697f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 698c90a116a7fd65d41e8258dc7b9a14218649697e6Bobby Georgescu @Override 699c90a116a7fd65d41e8258dc7b9a14218649697e6Bobby Georgescu public void clearBuffer() { 700915c2c5b2c367df71599370613af0924bd7c4887Bobby Georgescu clearBuffer(null); 701c90a116a7fd65d41e8258dc7b9a14218649697e6Bobby Georgescu } 702c90a116a7fd65d41e8258dc7b9a14218649697e6Bobby Georgescu 703f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void setTextureCoords(RectF source) { 704f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin setTextureCoords(source.left, source.top, source.right, source.bottom); 705f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 706f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 707f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void setTextureCoords(float left, float top, 708f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float right, float bottom) { 709f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glMatrixMode(GL11.GL_TEXTURE); 710f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureMatrixValues[0] = right - left; 711f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureMatrixValues[5] = bottom - top; 712f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureMatrixValues[10] = 1; 713f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureMatrixValues[12] = left; 714f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureMatrixValues[13] = top; 715f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mTextureMatrixValues[15] = 1; 716f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glLoadMatrixf(mTextureMatrixValues, 0); 717f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mGL.glMatrixMode(GL11.GL_MODELVIEW); 718f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 719f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 720b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang private void setTextureCoords(float[] mTextureTransform) { 721b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGL.glMatrixMode(GL11.GL_TEXTURE); 722b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGL.glLoadMatrixf(mTextureTransform, 0); 723b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang mGL.glMatrixMode(GL11.GL_MODELVIEW); 724b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang } 725b29a27f475a2c449abdda8d4e03d30914feed8c6Chih-Chung Chang 726f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // unloadTexture and deleteBuffer can be called from the finalizer thread, 727f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin // so we synchronized on the mUnboundTextures object. 7287817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 729f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean unloadTexture(BasicTexture t) { 730f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mUnboundTextures) { 73137c605949219b8bf54c165c34d6405f5f2989f50Owen Lin if (!t.isLoaded()) return false; 732f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mUnboundTextures.add(t.mId); 733f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 734f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 735f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 736f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 7377817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 738f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void deleteBuffer(int bufferId) { 739f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mUnboundTextures) { 740f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mDeleteBuffers.add(bufferId); 741f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 742f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 743f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 7447817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 745f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void deleteRecycledResources() { 746f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin synchronized (mUnboundTextures) { 747f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin IntArray ids = mUnboundTextures; 748f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (ids.size() > 0) { 74950b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glDeleteTextures(mGL, ids.size(), ids.getInternalArray(), 0); 750f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ids.clear(); 751f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 752f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 753f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ids = mDeleteBuffers; 754f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (ids.size() > 0) { 75550b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glDeleteBuffers(mGL, ids.size(), ids.getInternalArray(), 0); 756f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ids.clear(); 757f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 758f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 759f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 760f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 7617817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 762cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang public void save() { 763cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang save(SAVE_FLAG_ALL); 764f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 765f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 7667817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 767cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang public void save(int saveFlags) { 768f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ConfigState config = obtainRestoreConfig(); 769f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 770f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if ((saveFlags & SAVE_FLAG_ALPHA) != 0) { 771f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin config.mAlpha = mAlpha; 772f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 773f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin config.mAlpha = -1; 774f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 775f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 776f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if ((saveFlags & SAVE_FLAG_MATRIX) != 0) { 777f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin System.arraycopy(mMatrixValues, 0, config.mMatrix, 0, 16); 778f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 779f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin config.mMatrix[0] = Float.NEGATIVE_INFINITY; 780f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 781f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 782cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang mRestoreStack.add(config); 783f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 784f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 7857817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 786f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void restore() { 787f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mRestoreStack.isEmpty()) throw new IllegalStateException(); 788cfa105d3934c4dfa14f02b693bfa97c8d17d56a9Chih-Chung Chang ConfigState config = mRestoreStack.remove(mRestoreStack.size() - 1); 789f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin config.restore(this); 790f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin freeRestoreConfig(config); 791f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 792f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 793f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void freeRestoreConfig(ConfigState action) { 794f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin action.mNextFree = mRecycledRestoreAction; 795f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRecycledRestoreAction = action; 796f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 797f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 798f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private ConfigState obtainRestoreConfig() { 799f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mRecycledRestoreAction != null) { 800f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ConfigState result = mRecycledRestoreAction; 801f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mRecycledRestoreAction = result.mNextFree; 802f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return result; 803f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 804f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return new ConfigState(); 805f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 806f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 807f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class ConfigState { 808f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float mAlpha; 809f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin float mMatrix[] = new float[16]; 810f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ConfigState mNextFree; 811f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 812a4eae1abb4f2547dfbda84301ee764ce35464881John Reck public void restore(GLES11Canvas canvas) { 813f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mAlpha >= 0) canvas.setAlpha(mAlpha); 814f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mMatrix[0] != Float.NEGATIVE_INFINITY) { 815f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin System.arraycopy(mMatrix, 0, canvas.mMatrixValues, 0, 16); 816f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 817f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 818f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 819f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 8207817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 821f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void dumpStatisticsAndClear() { 822f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String line = String.format( 823f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin "MESH:%d, TEX_OES:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d", 824f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountDrawMesh, mCountTextureRect, mCountTextureOES, 825f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountFillRect, mCountDrawLine); 826f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountDrawMesh = 0; 827f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountTextureRect = 0; 828f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountTextureOES = 0; 829f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountFillRect = 0; 830f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mCountDrawLine = 0; 831f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Log.d(TAG, line); 832f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 833f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 834f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void saveTransform() { 835f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin System.arraycopy(mMatrixValues, 0, mTempMatrix, 0, 16); 836f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 837f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 838f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private void restoreTransform() { 839f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin System.arraycopy(mTempMatrix, 0, mMatrixValues, 0, 16); 840f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 8418ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8428ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private void setRenderTarget(RawTexture texture) { 8438ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin GL11ExtensionPack gl11ep = (GL11ExtensionPack) mGL; 8448ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8458ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin if (mTargetTexture == null && texture != null) { 84650b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glGenBuffers(1, mFrameBuffer, 0); 8478ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin gl11ep.glBindFramebufferOES( 8488ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFrameBuffer[0]); 8498ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 8508ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin if (mTargetTexture != null && texture == null) { 8518ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0); 8528ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin gl11ep.glDeleteFramebuffersOES(1, mFrameBuffer, 0); 8538ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 8548ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8558ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin mTargetTexture = texture; 8568ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin if (texture == null) { 8578ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin setSize(mScreenWidth, mScreenHeight); 8588ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } else { 8598ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin setSize(texture.getWidth(), texture.getHeight()); 8608ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 86137c605949219b8bf54c165c34d6405f5f2989f50Owen Lin if (!texture.isLoaded()) texture.prepare(this); 8628ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8638ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin gl11ep.glFramebufferTexture2DOES( 8648ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin GL11ExtensionPack.GL_FRAMEBUFFER_OES, 8658ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, 8668ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin GL11.GL_TEXTURE_2D, texture.getId(), 0); 8678ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8688ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin checkFramebufferStatus(gl11ep); 8698ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 8708ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 8718ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8728ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin @Override 8738ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin public void endRenderTarget() { 8748ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin RawTexture texture = mTargetStack.remove(mTargetStack.size() - 1); 8758ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin setRenderTarget(texture); 8768ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin restore(); // restore matrix and alpha 8778ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 8788ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8798ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin @Override 8808ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin public void beginRenderTarget(RawTexture texture) { 8818ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin save(); // save matrix and alpha 8828ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin mTargetStack.add(mTargetTexture); 8838ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin setRenderTarget(texture); 8848ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 8858ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin 8868ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin private static void checkFramebufferStatus(GL11ExtensionPack gl11ep) { 8878ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES); 8888ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) { 8898ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin String msg = ""; 8908ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin switch (status) { 8918ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES: 8928ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin msg = "FRAMEBUFFER_FORMATS"; 8938ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin break; 8948ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES: 8958ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin msg = "FRAMEBUFFER_ATTACHMENT"; 8968ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin break; 8978ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES: 8988ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin msg = "FRAMEBUFFER_MISSING_ATTACHMENT"; 8998ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin break; 9008ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES: 9018ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin msg = "FRAMEBUFFER_DRAW_BUFFER"; 9028ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin break; 9038ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES: 9048ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin msg = "FRAMEBUFFER_READ_BUFFER"; 9058ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin break; 9068ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin case GL11ExtensionPack.GL_FRAMEBUFFER_UNSUPPORTED_OES: 9078ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin msg = "FRAMEBUFFER_UNSUPPORTED"; 9088ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin break; 9098ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin case GL11ExtensionPack.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES: 9108ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin msg = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; 9118ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin break; 9128ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 9138ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin throw new RuntimeException(msg + ":" + Integer.toHexString(status)); 9148ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 9158ac2e8630f33f4d5f65731dc56efa9bfb3570cd7Owen Lin } 9167da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9177da54d7e41e04ea5122009b40de19be0724e1ca4George Mount @Override 9187da54d7e41e04ea5122009b40de19be0724e1ca4George Mount public void setTextureParameters(BasicTexture texture) { 9197da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int width = texture.getWidth(); 9207da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int height = texture.getHeight(); 9217da54d7e41e04ea5122009b40de19be0724e1ca4George Mount // Define a vertically flipped crop rectangle for OES_draw_texture. 9227da54d7e41e04ea5122009b40de19be0724e1ca4George Mount // The four values in sCropRect are: left, bottom, width, and 9237da54d7e41e04ea5122009b40de19be0724e1ca4George Mount // height. Negative value of width or height means flip. 9247da54d7e41e04ea5122009b40de19be0724e1ca4George Mount sCropRect[0] = 0; 9257da54d7e41e04ea5122009b40de19be0724e1ca4George Mount sCropRect[1] = height; 9267da54d7e41e04ea5122009b40de19be0724e1ca4George Mount sCropRect[2] = width; 9277da54d7e41e04ea5122009b40de19be0724e1ca4George Mount sCropRect[3] = -height; 9287da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9297da54d7e41e04ea5122009b40de19be0724e1ca4George Mount // Set texture parameters. 9307da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int target = texture.getTarget(); 9317da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glBindTexture(target, texture.getId()); 9327da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glTexParameterfv(target, GL11Ext.GL_TEXTURE_CROP_RECT_OES, sCropRect, 0); 9337da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE); 9347da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glTexParameteri(target, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE); 9357da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glTexParameterf(target, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); 9367da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glTexParameterf(target, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); 9377da54d7e41e04ea5122009b40de19be0724e1ca4George Mount } 9387da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9397da54d7e41e04ea5122009b40de19be0724e1ca4George Mount @Override 9407da54d7e41e04ea5122009b40de19be0724e1ca4George Mount public void initializeTextureSize(BasicTexture texture, int format, int type) { 9417da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int target = texture.getTarget(); 9427da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glBindTexture(target, texture.getId()); 9437da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int width = texture.getTextureWidth(); 9447da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int height = texture.getTextureHeight(); 9457da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glTexImage2D(target, 0, format, width, height, 0, format, type, null); 9467da54d7e41e04ea5122009b40de19be0724e1ca4George Mount } 9477da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9487da54d7e41e04ea5122009b40de19be0724e1ca4George Mount @Override 9497da54d7e41e04ea5122009b40de19be0724e1ca4George Mount public void initializeTexture(BasicTexture texture, Bitmap bitmap) { 9507da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int target = texture.getTarget(); 9517da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glBindTexture(target, texture.getId()); 9527da54d7e41e04ea5122009b40de19be0724e1ca4George Mount GLUtils.texImage2D(target, 0, bitmap, 0); 9537da54d7e41e04ea5122009b40de19be0724e1ca4George Mount } 9547da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9557da54d7e41e04ea5122009b40de19be0724e1ca4George Mount @Override 9567da54d7e41e04ea5122009b40de19be0724e1ca4George Mount public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap, 9577da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int format, int type) { 9587da54d7e41e04ea5122009b40de19be0724e1ca4George Mount int target = texture.getTarget(); 9597da54d7e41e04ea5122009b40de19be0724e1ca4George Mount mGL.glBindTexture(target, texture.getId()); 9607da54d7e41e04ea5122009b40de19be0724e1ca4George Mount GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap, format, type); 9617da54d7e41e04ea5122009b40de19be0724e1ca4George Mount } 9627da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9637da54d7e41e04ea5122009b40de19be0724e1ca4George Mount @Override 9646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public int uploadBuffer(FloatBuffer buf) { 9656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return uploadBuffer(buf, Float.SIZE / Byte.SIZE); 9666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9677da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 9696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public int uploadBuffer(ByteBuffer buf) { 9706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return uploadBuffer(buf, 1); 9716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9727da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int uploadBuffer(Buffer buf, int elementSize) { 9746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int[] bufferIds = new int[1]; 97550b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glGenBuffers(bufferIds.length, bufferIds, 0); 9766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int bufferId = bufferIds[0]; 9776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mGL.glBindBuffer(GL11.GL_ARRAY_BUFFER, bufferId); 9786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mGL.glBufferData(GL11.GL_ARRAY_BUFFER, buf.capacity() * elementSize, buf, 9796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GL11.GL_STATIC_DRAW); 9806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return bufferId; 9817da54d7e41e04ea5122009b40de19be0724e1ca4George Mount } 9827da54d7e41e04ea5122009b40de19be0724e1ca4George Mount 9837da54d7e41e04ea5122009b40de19be0724e1ca4George Mount @Override 98464072a071151b55fcbf97f6204d3c2258db386faGeorge Mount public void recoverFromLightCycle() { 98564072a071151b55fcbf97f6204d3c2258db386faGeorge Mount // This is only required for GLES20 98664072a071151b55fcbf97f6204d3c2258db386faGeorge Mount } 98764072a071151b55fcbf97f6204d3c2258db386faGeorge Mount 98864072a071151b55fcbf97f6204d3c2258db386faGeorge Mount @Override 98964072a071151b55fcbf97f6204d3c2258db386faGeorge Mount public void getBounds(Rect bounds, int x, int y, int width, int height) { 99064072a071151b55fcbf97f6204d3c2258db386faGeorge Mount // This is only required for GLES20 99164072a071151b55fcbf97f6204d3c2258db386faGeorge Mount } 99250b33abe053ccab7be3d1bca2328e792507963d4George Mount 99350b33abe053ccab7be3d1bca2328e792507963d4George Mount @Override 99450b33abe053ccab7be3d1bca2328e792507963d4George Mount public GLId getGLId() { 99550b33abe053ccab7be3d1bca2328e792507963d4George Mount return mGLId; 99650b33abe053ccab7be3d1bca2328e792507963d4George Mount } 997f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 998