16eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount/* 26eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * Copyright (C) 2012 The Android Open Source Project 36eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * 46eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * Licensed under the Apache License, Version 2.0 (the "License"); 56eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * you may not use this file except in compliance with the License. 66eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * You may obtain a copy of the License at 76eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * 86eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * http://www.apache.org/licenses/LICENSE-2.0 96eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * 106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * Unless required by applicable law or agreed to in writing, software 116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * distributed under the License is distributed on an "AS IS" BASIS, 126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * See the License for the specific language governing permissions and 146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount * limitations under the License. 156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount */ 16a4eae1abb4f2547dfbda84301ee764ce35464881John Reckpackage com.android.gallery3d.glrenderer; 176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport android.graphics.Bitmap; 1964072a071151b55fcbf97f6204d3c2258db386faGeorge Mountimport android.graphics.Rect; 206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport android.graphics.RectF; 216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport android.opengl.GLES20; 226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport android.opengl.GLUtils; 236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport android.opengl.Matrix; 246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport android.util.Log; 256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport com.android.gallery3d.util.IntArray; 276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport java.nio.Buffer; 296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport java.nio.ByteBuffer; 306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport java.nio.ByteOrder; 316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport java.nio.FloatBuffer; 326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport java.util.ArrayList; 336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mountimport java.util.Arrays; 346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3550b33abe053ccab7be3d1bca2328e792507963d4George Mountpublic class GLES20Canvas implements GLCanvas { 366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // ************** Constants ********************** 376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String TAG = GLES20Canvas.class.getSimpleName(); 386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int FLOAT_SIZE = Float.SIZE / Byte.SIZE; 396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final float OPAQUE_ALPHA = 0.95f; 406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int COORDS_PER_VERTEX = 2; 426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int VERTEX_STRIDE = COORDS_PER_VERTEX * FLOAT_SIZE; 436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int COUNT_FILL_VERTEX = 4; 456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int COUNT_LINE_VERTEX = 2; 466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int COUNT_RECT_VERTEX = 4; 476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int OFFSET_FILL_RECT = 0; 486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int OFFSET_DRAW_LINE = OFFSET_FILL_RECT + COUNT_FILL_VERTEX; 496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int OFFSET_DRAW_RECT = OFFSET_DRAW_LINE + COUNT_LINE_VERTEX; 506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final float[] BOX_COORDINATES = { 526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 0, 0, // Fill rectangle 536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1, 0, 546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 0, 1, 556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1, 1, 566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 0, 0, // Draw line 576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1, 1, 586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 0, 0, // Draw rectangle outline 596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 0, 1, 606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1, 1, 616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1, 0, 626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount }; 636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6464072a071151b55fcbf97f6204d3c2258db386faGeorge Mount private static final float[] BOUNDS_COORDINATES = { 6564072a071151b55fcbf97f6204d3c2258db386faGeorge Mount 0, 0, 0, 1, 6664072a071151b55fcbf97f6204d3c2258db386faGeorge Mount 1, 1, 0, 1, 6764072a071151b55fcbf97f6204d3c2258db386faGeorge Mount }; 6864072a071151b55fcbf97f6204d3c2258db386faGeorge Mount 696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String POSITION_ATTRIBUTE = "aPosition"; 706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String COLOR_UNIFORM = "uColor"; 716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String MATRIX_UNIFORM = "uMatrix"; 726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String TEXTURE_MATRIX_UNIFORM = "uTextureMatrix"; 736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String TEXTURE_SAMPLER_UNIFORM = "uTextureSampler"; 746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String ALPHA_UNIFORM = "uAlpha"; 756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String TEXTURE_COORD_ATTRIBUTE = "aTextureCoordinate"; 766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String DRAW_VERTEX_SHADER = "" 786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform mat4 " + MATRIX_UNIFORM + ";\n" 796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "attribute vec2 " + POSITION_ATTRIBUTE + ";\n" 806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "void main() {\n" 816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n" 826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " gl_Position = " + MATRIX_UNIFORM + " * pos;\n" 836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "}\n"; 846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String DRAW_FRAGMENT_SHADER = "" 866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "precision mediump float;\n" 876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform vec4 " + COLOR_UNIFORM + ";\n" 886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "void main() {\n" 896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " gl_FragColor = " + COLOR_UNIFORM + ";\n" 906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "}\n"; 916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String TEXTURE_VERTEX_SHADER = "" 936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform mat4 " + MATRIX_UNIFORM + ";\n" 946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform mat4 " + TEXTURE_MATRIX_UNIFORM + ";\n" 956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "attribute vec2 " + POSITION_ATTRIBUTE + ";\n" 966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "varying vec2 vTextureCoord;\n" 976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "void main() {\n" 986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n" 996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " gl_Position = " + MATRIX_UNIFORM + " * pos;\n" 1006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " vTextureCoord = (" + TEXTURE_MATRIX_UNIFORM + " * pos).xy;\n" 1016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "}\n"; 1026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String MESH_VERTEX_SHADER = "" 1046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform mat4 " + MATRIX_UNIFORM + ";\n" 1056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "attribute vec2 " + POSITION_ATTRIBUTE + ";\n" 1066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "attribute vec2 " + TEXTURE_COORD_ATTRIBUTE + ";\n" 1076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "varying vec2 vTextureCoord;\n" 1086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "void main() {\n" 1096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " vec4 pos = vec4(" + POSITION_ATTRIBUTE + ", 0.0, 1.0);\n" 1106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " gl_Position = " + MATRIX_UNIFORM + " * pos;\n" 1116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " vTextureCoord = " + TEXTURE_COORD_ATTRIBUTE + ";\n" 1126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "}\n"; 1136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String TEXTURE_FRAGMENT_SHADER = "" 1156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "precision mediump float;\n" 1166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "varying vec2 vTextureCoord;\n" 1176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform float " + ALPHA_UNIFORM + ";\n" 1186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform sampler2D " + TEXTURE_SAMPLER_UNIFORM + ";\n" 1196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "void main() {\n" 1206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " gl_FragColor = texture2D(" + TEXTURE_SAMPLER_UNIFORM + ", vTextureCoord);\n" 121bdb71cc6acbd78d5aa02d2e142b792247fb6e0bdGeorge Mount + " gl_FragColor *= " + ALPHA_UNIFORM + ";\n" 1226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "}\n"; 1236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final String OES_TEXTURE_FRAGMENT_SHADER = "" 1256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "#extension GL_OES_EGL_image_external : require\n" 1266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "precision mediump float;\n" 1276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "varying vec2 vTextureCoord;\n" 1286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform float " + ALPHA_UNIFORM + ";\n" 1296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "uniform samplerExternalOES " + TEXTURE_SAMPLER_UNIFORM + ";\n" 1306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "void main() {\n" 1316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + " gl_FragColor = texture2D(" + TEXTURE_SAMPLER_UNIFORM + ", vTextureCoord);\n" 132bdb71cc6acbd78d5aa02d2e142b792247fb6e0bdGeorge Mount + " gl_FragColor *= " + ALPHA_UNIFORM + ";\n" 1336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount + "}\n"; 1346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INITIAL_RESTORE_STATE_SIZE = 8; 1366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int MATRIX_SIZE = 16; 1376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Keep track of restore state 1396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private float[] mMatrices = new float[INITIAL_RESTORE_STATE_SIZE * MATRIX_SIZE]; 1406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private float[] mAlphas = new float[INITIAL_RESTORE_STATE_SIZE]; 1416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private IntArray mSaveFlags = new IntArray(); 1426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mCurrentAlphaIndex = 0; 1446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mCurrentMatrixIndex = 0; 1456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Viewport size 1476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mWidth; 1486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mHeight; 1496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Projection matrix 1516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private float[] mProjectionMatrix = new float[MATRIX_SIZE]; 1526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Screen size for when we aren't bound to a texture 1546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mScreenWidth; 1556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mScreenHeight; 1566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // GL programs 1586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mDrawProgram; 1596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mTextureProgram; 1606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mOesTextureProgram; 1616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mMeshProgram; 1626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // GL buffer containing BOX_COORDINATES 1646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mBoxCoordinates; 1656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Handle indices -- common 1676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INDEX_POSITION = 0; 1686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INDEX_MATRIX = 1; 1696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Handle indices -- draw 1716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INDEX_COLOR = 2; 1726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Handle indices -- texture 1746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INDEX_TEXTURE_MATRIX = 2; 1756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INDEX_TEXTURE_SAMPLER = 3; 1766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INDEX_ALPHA = 4; 1776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Handle indices -- mesh 1796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static final int INDEX_TEXTURE_COORD = 2; 1806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private abstract static class ShaderParameter { 1826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public int handle; 1836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount protected final String mName; 1846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public ShaderParameter(String name) { 1866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mName = name; 1876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 1886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public abstract void loadHandle(int program); 1906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 1916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static class UniformShaderParameter extends ShaderParameter { 1936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public UniformShaderParameter(String name) { 1946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount super(name); 1956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 1966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 1976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 1986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void loadHandle(int program) { 1996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount handle = GLES20.glGetUniformLocation(program, mName); 2006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 2016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 2026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 2036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static class AttributeShaderParameter extends ShaderParameter { 2056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public AttributeShaderParameter(String name) { 2066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount super(name); 2076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 2086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 2106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void loadHandle(int program) { 2116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount handle = GLES20.glGetAttribLocation(program, mName); 2126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 2136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 2146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 2156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ShaderParameter[] mDrawParameters = { 2176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION 2186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX 2196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(COLOR_UNIFORM), // INDEX_COLOR 2206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount }; 2216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ShaderParameter[] mTextureParameters = { 2226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION 2236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX 2246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(TEXTURE_MATRIX_UNIFORM), // INDEX_TEXTURE_MATRIX 2256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER 2266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA 2276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount }; 2286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ShaderParameter[] mOesTextureParameters = { 2296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION 2306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX 2316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(TEXTURE_MATRIX_UNIFORM), // INDEX_TEXTURE_MATRIX 2326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER 2336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA 2346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount }; 2356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ShaderParameter[] mMeshParameters = { 2366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new AttributeShaderParameter(POSITION_ATTRIBUTE), // INDEX_POSITION 2376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(MATRIX_UNIFORM), // INDEX_MATRIX 2386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new AttributeShaderParameter(TEXTURE_COORD_ATTRIBUTE), // INDEX_TEXTURE_COORD 2396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(TEXTURE_SAMPLER_UNIFORM), // INDEX_TEXTURE_SAMPLER 2406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount new UniformShaderParameter(ALPHA_UNIFORM), // INDEX_ALPHA 2416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount }; 2426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final IntArray mUnboundTextures = new IntArray(); 2446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final IntArray mDeleteBuffers = new IntArray(); 2456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Keep track of statistics for debugging 2476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mCountDrawMesh = 0; 2486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mCountTextureRect = 0; 2496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mCountFillRect = 0; 2506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int mCountDrawLine = 0; 2516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Buffer for framebuffer IDs -- we keep track so we can switch the attached 2536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // texture. 2546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int[] mFrameBuffer = new int[1]; 2556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Bound textures. 2576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private ArrayList<RawTexture> mTargetTextures = new ArrayList<RawTexture>(); 2586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Temporary variables used within calculations 2606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final float[] mTempMatrix = new float[32]; 2616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final float[] mTempColor = new float[4]; 2626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final RectF mTempSourceRect = new RectF(); 2636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final RectF mTempTargetRect = new RectF(); 2646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final float[] mTempTextureMatrix = new float[MATRIX_SIZE]; 2656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private final int[] mTempIntArray = new int[1]; 2666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 26750b33abe053ccab7be3d1bca2328e792507963d4George Mount private static final GLId mGLId = new GLES20IdImpl(); 26850b33abe053ccab7be3d1bca2328e792507963d4George Mount 2696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public GLES20Canvas() { 2706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.setIdentityM(mTempTextureMatrix, 0); 2716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.setIdentityM(mMatrices, mCurrentMatrixIndex); 2726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mAlphas[mCurrentAlphaIndex] = 1f; 2736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTargetTextures.add(null); 2746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount FloatBuffer boxBuffer = createBuffer(BOX_COORDINATES); 2766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mBoxCoordinates = uploadBuffer(boxBuffer); 2776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int drawVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, DRAW_VERTEX_SHADER); 2796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int textureVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, TEXTURE_VERTEX_SHADER); 2806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int meshVertexShader = loadShader(GLES20.GL_VERTEX_SHADER, MESH_VERTEX_SHADER); 2816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int drawFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, DRAW_FRAGMENT_SHADER); 2826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int textureFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, TEXTURE_FRAGMENT_SHADER); 2836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int oesTextureFragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, 2846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount OES_TEXTURE_FRAGMENT_SHADER); 2856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mDrawProgram = assembleProgram(drawVertexShader, drawFragmentShader, mDrawParameters); 2876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTextureProgram = assembleProgram(textureVertexShader, textureFragmentShader, 2886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTextureParameters); 2896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mOesTextureProgram = assembleProgram(textureVertexShader, oesTextureFragmentShader, 2906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mOesTextureParameters); 2916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mMeshProgram = assembleProgram(meshVertexShader, textureFragmentShader, mMeshParameters); 292bdb71cc6acbd78d5aa02d2e142b792247fb6e0bdGeorge Mount GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); 293bdb71cc6acbd78d5aa02d2e142b792247fb6e0bdGeorge Mount checkError(); 2946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 2956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 2966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static FloatBuffer createBuffer(float[] values) { 2976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // First create an nio buffer, then create a VBO from it. 2986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int size = values.length * FLOAT_SIZE; 2996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount FloatBuffer buffer = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder()) 3006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount .asFloatBuffer(); 3016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount buffer.put(values, 0, values.length).position(0); 3026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return buffer; 3036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int assembleProgram(int vertexShader, int fragmentShader, ShaderParameter[] params) { 3066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int program = GLES20.glCreateProgram(); 3076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (program == 0) { 3096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount throw new RuntimeException("Cannot create GL program: " + GLES20.glGetError()); 3106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glAttachShader(program, vertexShader); 3126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glAttachShader(program, fragmentShader); 3146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glLinkProgram(program); 3166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int[] mLinkStatus = mTempIntArray; 3186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, mLinkStatus, 0); 3196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (mLinkStatus[0] != GLES20.GL_TRUE) { 3206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Log.e(TAG, "Could not link program: "); 3216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Log.e(TAG, GLES20.glGetProgramInfoLog(program)); 3226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDeleteProgram(program); 3236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount program = 0; 3246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount for (int i = 0; i < params.length; i++) { 3266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount params[i].loadHandle(program); 3276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return program; 3296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static int loadShader(int type, String shaderCode) { 3326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 3336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 3346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int shader = GLES20.glCreateShader(type); 3356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // add the source code to the shader and compile it 3376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glShaderSource(shader, shaderCode); 3386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glCompileShader(shader); 3406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return shader; 3436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 3466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void setSize(int width, int height) { 3476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mWidth = width; 3486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mHeight = height; 3496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glViewport(0, 0, mWidth, mHeight); 3506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.setIdentityM(mMatrices, mCurrentMatrixIndex); 3526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.orthoM(mProjectionMatrix, 0, 0, width, 0, height, -1, 1); 3536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (getTargetTexture() == null) { 3546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mScreenWidth = width; 3556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mScreenHeight = height; 3566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.translateM(mMatrices, mCurrentMatrixIndex, 0, height, 0); 3576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.scaleM(mMatrices, mCurrentMatrixIndex, 1, -1, 1); 3586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 3626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void clearBuffer() { 3636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glClearColor(0f, 0f, 0f, 1f); 3646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 3666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 3706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void clearBuffer(float[] argb) { 3716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glClearColor(argb[1], argb[2], argb[3], argb[0]); 3726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 3746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 3756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 3786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public float getAlpha() { 3796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return mAlphas[mCurrentAlphaIndex]; 3806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 3836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void setAlpha(float alpha) { 3846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mAlphas[mCurrentAlphaIndex] = alpha; 3856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 3886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void multiplyAlpha(float alpha) { 3896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setAlpha(getAlpha() * alpha); 3906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 3936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void translate(float x, float y, float z) { 3946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.translateM(mMatrices, mCurrentMatrixIndex, x, y, z); 3956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 3966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 3976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // This is a faster version of translate(x, y, z) because 3986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // (1) we knows z = 0, (2) we inline the Matrix.translateM call, 3996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // (3) we unroll the loop 4006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void translate(float x, float y) { 4026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int index = mCurrentMatrixIndex; 4036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float[] m = mMatrices; 4046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount m[index + 12] += m[index + 0] * x + m[index + 4] * y; 4056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount m[index + 13] += m[index + 1] * x + m[index + 5] * y; 4066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount m[index + 14] += m[index + 2] * x + m[index + 6] * y; 4076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount m[index + 15] += m[index + 3] * x + m[index + 7] * y; 4086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void scale(float sx, float sy, float sz) { 4126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.scaleM(mMatrices, mCurrentMatrixIndex, sx, sy, sz); 4136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void rotate(float angle, float x, float y, float z) { 4176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (angle == 0f) { 4186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return; 4196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float[] temp = mTempMatrix; 4216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.setRotateM(temp, 0, angle, x, y, z); 4226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float[] matrix = mMatrices; 4236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int index = mCurrentMatrixIndex; 4246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.multiplyMM(temp, MATRIX_SIZE, matrix, index, temp, 0); 4256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount System.arraycopy(temp, MATRIX_SIZE, matrix, index, MATRIX_SIZE); 4266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void multiplyMatrix(float[] matrix, int offset) { 4306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float[] temp = mTempMatrix; 4316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float[] currentMatrix = mMatrices; 4326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int index = mCurrentMatrixIndex; 4336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.multiplyMM(temp, 0, currentMatrix, index, matrix, offset); 4346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount System.arraycopy(temp, 0, currentMatrix, index, 16); 4356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void save() { 4396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount save(SAVE_FLAG_ALL); 4406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void save(int saveFlags) { 4446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount boolean saveAlpha = (saveFlags & SAVE_FLAG_ALPHA) == SAVE_FLAG_ALPHA; 4456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (saveAlpha) { 4466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float currentAlpha = getAlpha(); 4476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCurrentAlphaIndex++; 4486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (mAlphas.length <= mCurrentAlphaIndex) { 4496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mAlphas = Arrays.copyOf(mAlphas, mAlphas.length * 2); 4506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mAlphas[mCurrentAlphaIndex] = currentAlpha; 4526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount boolean saveMatrix = (saveFlags & SAVE_FLAG_MATRIX) == SAVE_FLAG_MATRIX; 4546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (saveMatrix) { 4556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int currentIndex = mCurrentMatrixIndex; 4566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCurrentMatrixIndex += MATRIX_SIZE; 4576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (mMatrices.length <= mCurrentMatrixIndex) { 4586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mMatrices = Arrays.copyOf(mMatrices, mMatrices.length * 2); 4596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount System.arraycopy(mMatrices, currentIndex, mMatrices, mCurrentMatrixIndex, MATRIX_SIZE); 4616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mSaveFlags.add(saveFlags); 4636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void restore() { 4676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int restoreFlags = mSaveFlags.removeLast(); 4686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount boolean restoreAlpha = (restoreFlags & SAVE_FLAG_ALPHA) == SAVE_FLAG_ALPHA; 4696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (restoreAlpha) { 4706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCurrentAlphaIndex--; 4716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount boolean restoreMatrix = (restoreFlags & SAVE_FLAG_MATRIX) == SAVE_FLAG_MATRIX; 4736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (restoreMatrix) { 4746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCurrentMatrixIndex -= MATRIX_SIZE; 4756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) { 4806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount draw(GLES20.GL_LINE_STRIP, OFFSET_DRAW_LINE, COUNT_LINE_VERTEX, x1, y1, x2 - x1, y2 - y1, 4816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount paint); 4826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountDrawLine++; 4836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 4866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawRect(float x, float y, float width, float height, GLPaint paint) { 4876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount draw(GLES20.GL_LINE_LOOP, OFFSET_DRAW_RECT, COUNT_RECT_VERTEX, x, y, width, height, paint); 4886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountDrawLine++; 4896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void draw(int type, int offset, int count, float x, float y, float width, float height, 4926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLPaint paint) { 4936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount draw(type, offset, count, x, y, width, height, paint.getColor(), paint.getLineWidth()); 4946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 4956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 4966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void draw(int type, int offset, int count, float x, float y, float width, float height, 4976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int color, float lineWidth) { 4986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount prepareDraw(offset, color, lineWidth); 4996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount draw(mDrawParameters, type, count, x, y, width, height); 5006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void prepareDraw(int offset, int color, float lineWidth) { 5036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glUseProgram(mDrawProgram); 5046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (lineWidth > 0) { 5066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glLineWidth(lineWidth); 5076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float[] colorArray = getColor(color); 5106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount boolean blendingEnabled = (colorArray[3] < 1f); 5116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount enableBlending(blendingEnabled); 5126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (blendingEnabled) { 5136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBlendColor(colorArray[0], colorArray[1], colorArray[2], colorArray[3]); 5146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glUniform4fv(mDrawParameters[INDEX_COLOR].handle, 1, colorArray, 0); 5186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setPosition(mDrawParameters, offset); 5196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private float[] getColor(int color) { 5236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float alpha = ((color >>> 24) & 0xFF) / 255f * getAlpha(); 5246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float red = ((color >>> 16) & 0xFF) / 255f * alpha; 5256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float green = ((color >>> 8) & 0xFF) / 255f * alpha; 5266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float blue = (color & 0xFF) / 255f * alpha; 5276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempColor[0] = red; 5286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempColor[1] = green; 5296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempColor[2] = blue; 5306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempColor[3] = alpha; 5316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return mTempColor; 5326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void enableBlending(boolean enableBlending) { 5356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (enableBlending) { 5366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glEnable(GLES20.GL_BLEND); 5376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } else { 5396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDisable(GLES20.GL_BLEND); 5406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void setPosition(ShaderParameter[] params, int offset) { 5456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBoxCoordinates); 5466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glVertexAttribPointer(params[INDEX_POSITION].handle, COORDS_PER_VERTEX, 5486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.GL_FLOAT, false, VERTEX_STRIDE, offset * VERTEX_STRIDE); 5496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 55064072a071151b55fcbf97f6204d3c2258db386faGeorge Mount GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 55164072a071151b55fcbf97f6204d3c2258db386faGeorge Mount checkError(); 5526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void draw(ShaderParameter[] params, int type, int count, float x, float y, float width, 5556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float height) { 5566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setMatrix(params, x, y, width, height); 5576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int positionHandle = params[INDEX_POSITION].handle; 5586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glEnableVertexAttribArray(positionHandle); 5596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDrawArrays(type, 0, count); 5616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDisableVertexAttribArray(positionHandle); 5636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void setMatrix(ShaderParameter[] params, float x, float y, float width, float height) { 5676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.translateM(mTempMatrix, 0, mMatrices, mCurrentMatrixIndex, x, y, 0f); 5686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.scaleM(mTempMatrix, 0, width, height, 1f); 5696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Matrix.multiplyMM(mTempMatrix, MATRIX_SIZE, mProjectionMatrix, 0, mTempMatrix, 0); 5706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glUniformMatrix4fv(params[INDEX_MATRIX].handle, 1, false, mTempMatrix, MATRIX_SIZE); 5716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 5726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 5756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void fillRect(float x, float y, float width, float height, int color) { 5766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount draw(GLES20.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, COUNT_FILL_VERTEX, x, y, width, height, 5776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount color, 0f); 5786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountFillRect++; 5796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 5826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawTexture(BasicTexture texture, int x, int y, int width, int height) { 5836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (width <= 0 || height <= 0) { 5846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return; 5856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount copyTextureCoordinates(texture, mTempSourceRect); 5876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTargetRect.set(x, y, x + width, y + height); 5886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount convertCoordinate(mTempSourceRect, mTempTargetRect, texture); 5896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount drawTextureRect(texture, mTempSourceRect, mTempTargetRect); 5906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 5916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 5926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static void copyTextureCoordinates(BasicTexture texture, RectF outRect) { 5936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int left = 0; 5946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int top = 0; 5956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int right = texture.getWidth(); 5966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int bottom = texture.getHeight(); 5976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (texture.hasBorder()) { 5986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount left = 1; 5996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount top = 1; 6006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount right -= 1; 6016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount bottom -= 1; 6026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount outRect.set(left, top, right, bottom); 6046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 6076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawTexture(BasicTexture texture, RectF source, RectF target) { 6086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (target.width() <= 0 || target.height() <= 0) { 6096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return; 6106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempSourceRect.set(source); 6126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTargetRect.set(target); 6136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount convertCoordinate(mTempSourceRect, mTempTargetRect, texture); 6156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount drawTextureRect(texture, mTempSourceRect, mTempTargetRect); 6166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 6196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawTexture(BasicTexture texture, float[] textureTransform, int x, int y, int w, 6206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int h) { 6216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (w <= 0 || h <= 0) { 6226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return; 6236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTargetRect.set(x, y, x + w, y + h); 6256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount drawTextureRect(texture, textureTransform, mTempTargetRect); 6266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void drawTextureRect(BasicTexture texture, RectF source, RectF target) { 6296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setTextureMatrix(source); 6306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount drawTextureRect(texture, mTempTextureMatrix, target); 6316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void setTextureMatrix(RectF source) { 6346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTextureMatrix[0] = source.width(); 6356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTextureMatrix[5] = source.height(); 6366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTextureMatrix[12] = source.left; 6376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTextureMatrix[13] = source.top; 6386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // This function changes the source coordinate to the texture coordinates. 6416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // It also clips the source and target coordinates if it is beyond the 6426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // bound of the texture. 6436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static void convertCoordinate(RectF source, RectF target, BasicTexture texture) { 6446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int width = texture.getWidth(); 6456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int height = texture.getHeight(); 6466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int texWidth = texture.getTextureWidth(); 6476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int texHeight = texture.getTextureHeight(); 6486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Convert to texture coordinates 6496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount source.left /= texWidth; 6506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount source.right /= texWidth; 6516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount source.top /= texHeight; 6526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount source.bottom /= texHeight; 6536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount // Clip if the rendering range is beyond the bound of the texture. 6556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float xBound = (float) width / texWidth; 6566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (source.right > xBound) { 6576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount target.right = target.left + target.width() * (xBound - source.left) / source.width(); 6586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount source.right = xBound; 6596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float yBound = (float) height / texHeight; 6616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (source.bottom > yBound) { 6626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount target.bottom = target.top + target.height() * (yBound - source.top) / source.height(); 6636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount source.bottom = yBound; 6646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void drawTextureRect(BasicTexture texture, float[] textureMatrix, RectF target) { 6686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ShaderParameter[] params = prepareTexture(texture); 6696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setPosition(params, OFFSET_FILL_RECT); 6706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glUniformMatrix4fv(params[INDEX_TEXTURE_MATRIX].handle, 1, false, textureMatrix, 0); 6716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 67244a1b22eb7098819ac0251764b9fa686d8339d66George Mount if (texture.isFlippedVertically()) { 67344a1b22eb7098819ac0251764b9fa686d8339d66George Mount save(SAVE_FLAG_MATRIX); 67444a1b22eb7098819ac0251764b9fa686d8339d66George Mount translate(0, target.centerY()); 67544a1b22eb7098819ac0251764b9fa686d8339d66George Mount scale(1, -1, 1); 67644a1b22eb7098819ac0251764b9fa686d8339d66George Mount translate(0, -target.centerY()); 67744a1b22eb7098819ac0251764b9fa686d8339d66George Mount } 6786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount draw(params, GLES20.GL_TRIANGLE_STRIP, COUNT_FILL_VERTEX, target.left, target.top, 6796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount target.width(), target.height()); 68044a1b22eb7098819ac0251764b9fa686d8339d66George Mount if (texture.isFlippedVertically()) { 68144a1b22eb7098819ac0251764b9fa686d8339d66George Mount restore(); 68244a1b22eb7098819ac0251764b9fa686d8339d66George Mount } 6836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountTextureRect++; 6846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 6866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private ShaderParameter[] prepareTexture(BasicTexture texture) { 6876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ShaderParameter[] params; 6886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int program; 6896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (texture.getTarget() == GLES20.GL_TEXTURE_2D) { 6906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount params = mTextureParameters; 6916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount program = mTextureProgram; 6926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } else { 6936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount params = mOesTextureParameters; 6946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount program = mOesTextureProgram; 6956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount prepareTexture(texture, program, params); 6976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return params; 6986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 6996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void prepareTexture(BasicTexture texture, int program, ShaderParameter[] params) { 7016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glUseProgram(program); 7026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount enableBlending(!texture.isOpaque() || getAlpha() < OPAQUE_ALPHA); 7046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 7056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount texture.onBind(this); 7076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindTexture(texture.getTarget(), texture.getId()); 7086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glUniform1i(params[INDEX_TEXTURE_SAMPLER].handle, 0); 7106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glUniform1f(params[INDEX_ALPHA].handle, getAlpha()); 7126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 7166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawMesh(BasicTexture texture, int x, int y, int xyBuffer, int uvBuffer, 7176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int indexBuffer, int indexCount) { 7186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount prepareTexture(texture, mMeshProgram, mMeshParameters); 7196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 7216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, xyBuffer); 7246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int positionHandle = mMeshParameters[INDEX_POSITION].handle; 7266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 7276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount VERTEX_STRIDE, 0); 7286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, uvBuffer); 7316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int texCoordHandle = mMeshParameters[INDEX_TEXTURE_COORD].handle; 7336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glVertexAttribPointer(texCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, 7346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount false, VERTEX_STRIDE, 0); 7356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 73664072a071151b55fcbf97f6204d3c2258db386faGeorge Mount GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 73764072a071151b55fcbf97f6204d3c2258db386faGeorge Mount checkError(); 7386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glEnableVertexAttribArray(positionHandle); 7406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glEnableVertexAttribArray(texCoordHandle); 7426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setMatrix(mMeshParameters, x, y, 1, 1); 7456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, indexCount, GLES20.GL_UNSIGNED_BYTE, 0); 7466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDisableVertexAttribArray(positionHandle); 7496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDisableVertexAttribArray(texCoordHandle); 7516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); 7536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 7546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountDrawMesh++; 7556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 7586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawMixed(BasicTexture texture, int toColor, float ratio, int x, int y, int w, int h) { 7596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount copyTextureCoordinates(texture, mTempSourceRect); 7606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTempTargetRect.set(x, y, x + w, y + h); 7616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount drawMixed(texture, toColor, ratio, mTempSourceRect, mTempTargetRect); 7626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 7656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void drawMixed(BasicTexture texture, int toColor, float ratio, RectF source, RectF target) { 7666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (target.width() <= 0 || target.height() <= 0) { 7676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return; 7686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount save(SAVE_FLAG_ALPHA); 7706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float currentAlpha = getAlpha(); 7726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float cappedRatio = Math.min(1f, Math.max(0f, ratio)); 7736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float textureAlpha = (1f - cappedRatio) * currentAlpha; 7756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setAlpha(textureAlpha); 7766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount drawTexture(texture, source, target); 7776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount float colorAlpha = cappedRatio * currentAlpha; 7796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setAlpha(colorAlpha); 7806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount fillRect(target.left, target.top, target.width(), target.height(), toColor); 7816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount restore(); 7836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 7866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public boolean unloadTexture(BasicTexture texture) { 7876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount boolean unload = texture.isLoaded(); 7886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (unload) { 7896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount synchronized (mUnboundTextures) { 7906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mUnboundTextures.add(texture.getId()); 7916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return unload; 7946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 7956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 7966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 7976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void deleteBuffer(int bufferId) { 7986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount synchronized (mUnboundTextures) { 7996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mDeleteBuffers.add(bufferId); 8006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 8046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void deleteRecycledResources() { 8056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount synchronized (mUnboundTextures) { 8066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount IntArray ids = mUnboundTextures; 8076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (mUnboundTextures.size() > 0) { 80850b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glDeleteTextures(null, ids.size(), ids.getInternalArray(), 0); 8096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ids.clear(); 8106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ids = mDeleteBuffers; 8136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (ids.size() > 0) { 81450b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glDeleteBuffers(null, ids.size(), ids.getInternalArray(), 0); 8156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount ids.clear(); 8166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 8216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void dumpStatisticsAndClear() { 8226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount String line = String.format("MESH:%d, TEX_RECT:%d, FILL_RECT:%d, LINE:%d", mCountDrawMesh, 8236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountTextureRect, mCountFillRect, mCountDrawLine); 8246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountDrawMesh = 0; 8256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountTextureRect = 0; 8266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountFillRect = 0; 8276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mCountDrawLine = 0; 8286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Log.d(TAG, line); 8296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 8326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void endRenderTarget() { 8336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount RawTexture oldTexture = mTargetTextures.remove(mTargetTextures.size() - 1); 8346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount RawTexture texture = getTargetTexture(); 8356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setRenderTarget(oldTexture, texture); 8366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount restore(); // restore matrix and alpha 8376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 8406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void beginRenderTarget(RawTexture texture) { 8416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount save(); // save matrix and alpha and blending 8426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount RawTexture oldTexture = getTargetTexture(); 8436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount mTargetTextures.add(texture); 8446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setRenderTarget(oldTexture, texture); 8456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private RawTexture getTargetTexture() { 8486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return mTargetTextures.get(mTargetTextures.size() - 1); 8496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private void setRenderTarget(BasicTexture oldTexture, RawTexture texture) { 8526eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (oldTexture == null && texture != null) { 8536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glGenFramebuffers(1, mFrameBuffer, 0); 8546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 8556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffer[0]); 8566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 8576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } else if (oldTexture != null && texture == null) { 8586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 8596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 8606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glDeleteFramebuffers(1, mFrameBuffer, 0); 8616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 8626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8636eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (texture == null) { 8656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setSize(mScreenWidth, mScreenHeight); 8666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } else { 8676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount setSize(texture.getWidth(), texture.getHeight()); 8686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (!texture.isLoaded()) { 8706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount texture.prepare(this); 8716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, 8746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount texture.getTarget(), texture.getId(), 0); 8756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 8766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkFramebufferStatus(); 8786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 8816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static void checkFramebufferStatus() { 8826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); 8836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) { 8846eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount String msg = ""; 8856eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount switch (status) { 8866eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount case GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 8876eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount msg = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; 8886eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount break; 8896eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount case GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 8906eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount msg = "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; 8916eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount break; 8926eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount case GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 8936eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount msg = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; 8946eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount break; 8956eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount case GLES20.GL_FRAMEBUFFER_UNSUPPORTED: 8966eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount msg = "GL_FRAMEBUFFER_UNSUPPORTED"; 8976eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount break; 8986eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 8996eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount throw new RuntimeException(msg + ":" + Integer.toHexString(status)); 9006eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9016eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9026eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9036eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 9046eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void setTextureParameters(BasicTexture texture) { 9056eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int target = texture.getTarget(); 9066eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindTexture(target, texture.getId()); 9076eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 9086eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 9096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glTexParameteri(target, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 9106eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 9116eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glTexParameterf(target, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 9126eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9136eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9146eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 9156eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void initializeTextureSize(BasicTexture texture, int format, int type) { 9166eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int target = texture.getTarget(); 9176eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindTexture(target, texture.getId()); 9186eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 9196eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int width = texture.getTextureWidth(); 9206eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int height = texture.getTextureHeight(); 9216eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glTexImage2D(target, 0, format, width, height, 0, format, type, null); 9226eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9236eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9246eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 9256eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void initializeTexture(BasicTexture texture, Bitmap bitmap) { 9266eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int target = texture.getTarget(); 9276eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindTexture(target, texture.getId()); 9286eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 9296eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLUtils.texImage2D(target, 0, bitmap, 0); 9306eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9316eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9326eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 9336eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public void texSubImage2D(BasicTexture texture, int xOffset, int yOffset, Bitmap bitmap, 9346eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int format, int type) { 9356eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int target = texture.getTarget(); 9366eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindTexture(target, texture.getId()); 9376eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 9386eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLUtils.texSubImage2D(target, 0, xOffset, yOffset, bitmap, format, type); 9396eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9406eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9416eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 9426eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public int uploadBuffer(FloatBuffer buf) { 9436eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return uploadBuffer(buf, FLOAT_SIZE); 9446eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9456eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9466eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @Override 9476eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount public int uploadBuffer(ByteBuffer buf) { 9486eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return uploadBuffer(buf, 1); 9496eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9506eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9516eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private int uploadBuffer(Buffer buffer, int elementSize) { 95250b33abe053ccab7be3d1bca2328e792507963d4George Mount mGLId.glGenBuffers(1, mTempIntArray, 0); 9536eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 9546eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int bufferId = mTempIntArray[0]; 9556eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, bufferId); 9566eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 9576eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffer.capacity() * elementSize, buffer, 9586eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount GLES20.GL_STATIC_DRAW); 9596eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount checkError(); 9606eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount return bufferId; 9616eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9626eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 96364072a071151b55fcbf97f6204d3c2258db386faGeorge Mount public static void checkError() { 9646eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount int error = GLES20.glGetError(); 9656eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (error != 0) { 9666eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Throwable t = new Throwable(); 9676eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Log.e(TAG, "GL error: " + error, t); 9686eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9696eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9706eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 9716eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount @SuppressWarnings("unused") 9726eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount private static void printMatrix(String message, float[] m, int offset) { 9736eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount StringBuilder b = new StringBuilder(message); 9746eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount for (int i = 0; i < MATRIX_SIZE; i++) { 9756eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount b.append(' '); 9766eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount if (i % 4 == 0) { 9776eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount b.append('\n'); 9786eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9796eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount b.append(m[offset + i]); 9806eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9816eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount Log.v(TAG, b.toString()); 9826eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount } 9836eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount 98464072a071151b55fcbf97f6204d3c2258db386faGeorge Mount @Override 98564072a071151b55fcbf97f6204d3c2258db386faGeorge Mount public void recoverFromLightCycle() { 98664072a071151b55fcbf97f6204d3c2258db386faGeorge Mount GLES20.glViewport(0, 0, mWidth, mHeight); 98764072a071151b55fcbf97f6204d3c2258db386faGeorge Mount GLES20.glDisable(GLES20.GL_DEPTH_TEST); 988bdb71cc6acbd78d5aa02d2e142b792247fb6e0bdGeorge Mount GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); 989bdb71cc6acbd78d5aa02d2e142b792247fb6e0bdGeorge Mount checkError(); 99064072a071151b55fcbf97f6204d3c2258db386faGeorge Mount } 99164072a071151b55fcbf97f6204d3c2258db386faGeorge Mount 99264072a071151b55fcbf97f6204d3c2258db386faGeorge Mount @Override 99364072a071151b55fcbf97f6204d3c2258db386faGeorge Mount public void getBounds(Rect bounds, int x, int y, int width, int height) { 99464072a071151b55fcbf97f6204d3c2258db386faGeorge Mount Matrix.translateM(mTempMatrix, 0, mMatrices, mCurrentMatrixIndex, x, y, 0f); 99564072a071151b55fcbf97f6204d3c2258db386faGeorge Mount Matrix.scaleM(mTempMatrix, 0, width, height, 1f); 99664072a071151b55fcbf97f6204d3c2258db386faGeorge Mount Matrix.multiplyMV(mTempMatrix, MATRIX_SIZE, mTempMatrix, 0, BOUNDS_COORDINATES, 0); 99764072a071151b55fcbf97f6204d3c2258db386faGeorge Mount Matrix.multiplyMV(mTempMatrix, MATRIX_SIZE + 4, mTempMatrix, 0, BOUNDS_COORDINATES, 4); 99864072a071151b55fcbf97f6204d3c2258db386faGeorge Mount bounds.left = Math.round(mTempMatrix[MATRIX_SIZE]); 99964072a071151b55fcbf97f6204d3c2258db386faGeorge Mount bounds.right = Math.round(mTempMatrix[MATRIX_SIZE + 4]); 100064072a071151b55fcbf97f6204d3c2258db386faGeorge Mount bounds.top = Math.round(mTempMatrix[MATRIX_SIZE + 1]); 100164072a071151b55fcbf97f6204d3c2258db386faGeorge Mount bounds.bottom = Math.round(mTempMatrix[MATRIX_SIZE + 5]); 100264072a071151b55fcbf97f6204d3c2258db386faGeorge Mount bounds.sort(); 100364072a071151b55fcbf97f6204d3c2258db386faGeorge Mount } 100450b33abe053ccab7be3d1bca2328e792507963d4George Mount 100550b33abe053ccab7be3d1bca2328e792507963d4George Mount @Override 100650b33abe053ccab7be3d1bca2328e792507963d4George Mount public GLId getGLId() { 100750b33abe053ccab7be3d1bca2328e792507963d4George Mount return mGLId; 100850b33abe053ccab7be3d1bca2328e792507963d4George Mount } 10096eb33768a15e2b4cc647bc55474568cf710876dbGeorge Mount} 1010