1b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui/* 2b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * Copyright (C) 2014 The Android Open Source Project 3b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * 4b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * Licensed under the Apache License, Version 2.0 (the "License"); 5b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * you may not use this file except in compliance with the License. 6b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * You may obtain a copy of the License at 7b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * 8b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * http://www.apache.org/licenses/LICENSE-2.0 9b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * 10b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * Unless required by applicable law or agreed to in writing, software 11b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * distributed under the License is distributed on an "AS IS" BASIS, 12b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * See the License for the specific language governing permissions and 14b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * limitations under the License. 15b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui */ 16b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 17b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuipackage com.android.test.hwui; 18b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 19b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.app.Activity; 20b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.app.ActivityManager; 21b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.content.Context; 22b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.content.pm.ConfigurationInfo; 23b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.graphics.Bitmap; 24b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.graphics.BitmapFactory; 253994371aa3bec727ee8dc5643bb4212c0525467fztenghuiimport android.opengl.EGL14; 263994371aa3bec727ee8dc5643bb4212c0525467fztenghuiimport android.opengl.EGLDisplay; 27b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.opengl.GLES20; 28b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.opengl.GLSurfaceView; 29b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.opengl.GLUtils; 30b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.opengl.Matrix; 31b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.os.Bundle; 32b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.os.SystemClock; 33b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport android.util.Log; 343994371aa3bec727ee8dc5643bb4212c0525467fztenghuiimport android.view.MotionEvent; 35b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 36b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport java.io.IOException; 37b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport java.io.InputStream; 38b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport java.nio.ByteBuffer; 39b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport java.nio.ByteOrder; 40b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport java.nio.FloatBuffer; 41b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 42b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport javax.microedition.khronos.egl.EGLConfig; 43b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuiimport javax.microedition.khronos.opengles.GL10; 44b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 45b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui/** 46b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * This sample shows how to check for OpenGL ES 2.0 support at runtime, and then 47b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * use either OpenGL ES 1.0 or OpenGL ES 2.0, as appropriate. 48b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui */ 49b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghuipublic class GLDepthTestActivity extends Activity { 50b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui @Override 51b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui protected void onCreate(Bundle savedInstanceState) { 52b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui super.onCreate(savedInstanceState); 53b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mGLSurfaceView = new GLSurfaceView(this); 54b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (detectOpenGLES20()) { 55b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // Tell the surface view we want to create an OpenGL ES 56b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // 2.0-compatible 57b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // context, and set an OpenGL ES 2.0-compatible renderer. 58b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mGLSurfaceView.setEGLContextClientVersion(2); 593994371aa3bec727ee8dc5643bb4212c0525467fztenghui mRenderer = new GLES20TriangleRenderer(this); 603994371aa3bec727ee8dc5643bb4212c0525467fztenghui mGLSurfaceView.setRenderer(mRenderer); 61b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } else { 62b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui throw new IllegalStateException("Can't find OGL ES2.0 context"); 63b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 64b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui setContentView(mGLSurfaceView); 65b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 66b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 67b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private boolean detectOpenGLES20() { 68b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui ActivityManager am = 69b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 70b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui ConfigurationInfo info = am.getDeviceConfigurationInfo(); 71b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui return (info.reqGlEsVersion >= 0x20000); 72b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 73b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 74b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui @Override 75b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui protected void onResume() { 76b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // Ideally a game should implement onResume() and onPause() 77b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // to take appropriate action when the activity looses focus 78b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui super.onResume(); 79b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mGLSurfaceView.onResume(); 80b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 81b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 82b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui @Override 83b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui protected void onPause() { 84b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // Ideally a game should implement onResume() and onPause() 85b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // to take appropriate action when the activity looses focus 86b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui super.onPause(); 87b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mGLSurfaceView.onPause(); 88b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 89b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 903994371aa3bec727ee8dc5643bb4212c0525467fztenghui @Override 913994371aa3bec727ee8dc5643bb4212c0525467fztenghui public boolean onTouchEvent(MotionEvent event) { 923994371aa3bec727ee8dc5643bb4212c0525467fztenghui Log.i("motion", event.toString()); 933994371aa3bec727ee8dc5643bb4212c0525467fztenghui if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 943994371aa3bec727ee8dc5643bb4212c0525467fztenghui mRenderer.toggleDepthTest(); 953994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 963994371aa3bec727ee8dc5643bb4212c0525467fztenghui return true; 973994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 983994371aa3bec727ee8dc5643bb4212c0525467fztenghui 99b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private GLSurfaceView mGLSurfaceView; 1003994371aa3bec727ee8dc5643bb4212c0525467fztenghui private GLES20TriangleRenderer mRenderer; 101b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 102b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui /* 103b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * Copyright (C) 2009 The Android Open Source Project Licensed under the 104b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * Apache License, Version 2.0 (the "License"); you may not use this file 105b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * except in compliance with the License. You may obtain a copy of the 106b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by 107b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * applicable law or agreed to in writing, software distributed under the 108b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 109b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * CONDITIONS OF ANY KIND, either express or implied. See the License for 110b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * the specific language governing permissions and limitations under the 111b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * License. 112b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui */ 113b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 114b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui class GLES20TriangleRenderer implements GLSurfaceView.Renderer { 1153994371aa3bec727ee8dc5643bb4212c0525467fztenghui private final static int REPEAT_RECTANGLES = 10; 1163994371aa3bec727ee8dc5643bb4212c0525467fztenghui private boolean mDepthTestEnabled = true; 1173994371aa3bec727ee8dc5643bb4212c0525467fztenghui private final static int FRAME_REPEAT_TIMES = 1; 118b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui public GLES20TriangleRenderer(Context context) { 119b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mContext = context; 120b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length 121b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 122b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mTriangleVertices.put(mTriangleVerticesData).position(0); 123b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 124b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 125b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 1263994371aa3bec727ee8dc5643bb4212c0525467fztenghui public void toggleDepthTest() { 1273994371aa3bec727ee8dc5643bb4212c0525467fztenghui mDepthTestEnabled = !mDepthTestEnabled; 1283994371aa3bec727ee8dc5643bb4212c0525467fztenghui Log.v(TAG, "mDepthTestEnabled is " + mDepthTestEnabled); 1293994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 130b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 1313994371aa3bec727ee8dc5643bb4212c0525467fztenghui public void onDrawFrame(GL10 glUnused) { 1323994371aa3bec727ee8dc5643bb4212c0525467fztenghui for (int j = 0 ; j < FRAME_REPEAT_TIMES; j ++) { 1333994371aa3bec727ee8dc5643bb4212c0525467fztenghui // Ignore the passed-in GL10 interface, and use the GLES20 1343994371aa3bec727ee8dc5643bb4212c0525467fztenghui // class's static methods instead. 1353994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 1363994371aa3bec727ee8dc5643bb4212c0525467fztenghui if (mDepthTestEnabled) { 1373994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 1383994371aa3bec727ee8dc5643bb4212c0525467fztenghui } else { 1393994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 1403994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 1413994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glUseProgram(mProgram); 1423994371aa3bec727ee8dc5643bb4212c0525467fztenghui if (mDepthTestEnabled) { 1433994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glEnable(GLES20.GL_DEPTH_TEST); 1443994371aa3bec727ee8dc5643bb4212c0525467fztenghui } else { 1453994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glDisable(GLES20.GL_DEPTH_TEST); 1463994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 1473994371aa3bec727ee8dc5643bb4212c0525467fztenghui checkGlError("glUseProgram"); 1483994371aa3bec727ee8dc5643bb4212c0525467fztenghui 1493994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 1503994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID); 1513994371aa3bec727ee8dc5643bb4212c0525467fztenghui 1523994371aa3bec727ee8dc5643bb4212c0525467fztenghui mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 1533994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 1543994371aa3bec727ee8dc5643bb4212c0525467fztenghui TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 1553994371aa3bec727ee8dc5643bb4212c0525467fztenghui checkGlError("glVertexAttribPointer maPosition"); 1563994371aa3bec727ee8dc5643bb4212c0525467fztenghui mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 1573994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glEnableVertexAttribArray(maPositionHandle); 1583994371aa3bec727ee8dc5643bb4212c0525467fztenghui checkGlError("glEnableVertexAttribArray maPositionHandle"); 1593994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, 1603994371aa3bec727ee8dc5643bb4212c0525467fztenghui TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 1613994371aa3bec727ee8dc5643bb4212c0525467fztenghui checkGlError("glVertexAttribPointer maTextureHandle"); 1623994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glEnableVertexAttribArray(maTextureHandle); 1633994371aa3bec727ee8dc5643bb4212c0525467fztenghui checkGlError("glEnableVertexAttribArray maTextureHandle"); 1643994371aa3bec727ee8dc5643bb4212c0525467fztenghui 1653994371aa3bec727ee8dc5643bb4212c0525467fztenghui for (int i = 0 ; i < REPEAT_RECTANGLES; i ++) { 1663994371aa3bec727ee8dc5643bb4212c0525467fztenghui float step = ((float)i) / REPEAT_RECTANGLES; 1673994371aa3bec727ee8dc5643bb4212c0525467fztenghui Matrix.setIdentityM(mMMatrix, 0); 1683994371aa3bec727ee8dc5643bb4212c0525467fztenghui Matrix.translateM(mMMatrix, 0, 0, step, step / 2); 1693994371aa3bec727ee8dc5643bb4212c0525467fztenghui Matrix.scaleM(mMMatrix, 0, 2.0f, 1.0f, 1.0f); 1703994371aa3bec727ee8dc5643bb4212c0525467fztenghui Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); 1713994371aa3bec727ee8dc5643bb4212c0525467fztenghui Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); 1723994371aa3bec727ee8dc5643bb4212c0525467fztenghui 1733994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); 1743994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glUniform4f(muOverlayHandle, step , step, step , step); 1753994371aa3bec727ee8dc5643bb4212c0525467fztenghui GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 1763994371aa3bec727ee8dc5643bb4212c0525467fztenghui checkGlError("glDrawArrays"); 1773994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 1783994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 179b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 180b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 181b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui public void onSurfaceChanged(GL10 glUnused, int width, int height) { 182b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // Ignore the passed-in GL10 interface, and use the GLES20 183b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // class's static methods instead. 184b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glViewport(0, 0, width, height); 185b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui float ratio = (float) width / height; 186b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 187b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 188b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 189b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { 190b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // Ignore the passed-in GL10 interface, and use the GLES20 191b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // class's static methods instead. 192b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mProgram = createProgram(mVertexShader, mFragmentShader); 193b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (mProgram == 0) { 194b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui return; 195b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 196b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); 197b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui checkGlError("glGetAttribLocation aPosition"); 198b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (maPositionHandle == -1) { 199b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui throw new RuntimeException("Could not get attrib location for aPosition"); 200b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 201b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord"); 202b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui checkGlError("glGetAttribLocation aTextureCoord"); 203b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (maTextureHandle == -1) { 204b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui throw new RuntimeException("Could not get attrib location for aTextureCoord"); 205b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 206b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 207b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 208b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui checkGlError("glGetUniformLocation uMVPMatrix"); 209b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (muMVPMatrixHandle == -1) { 210b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui throw new RuntimeException("Could not get attrib location for uMVPMatrix"); 211b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 212b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 2133994371aa3bec727ee8dc5643bb4212c0525467fztenghui muOverlayHandle = GLES20.glGetUniformLocation(mProgram, "uOverlay"); 2143994371aa3bec727ee8dc5643bb4212c0525467fztenghui checkGlError("glGetUniformLocation uOverlay"); 2153994371aa3bec727ee8dc5643bb4212c0525467fztenghui if (muOverlayHandle == -1) { 2163994371aa3bec727ee8dc5643bb4212c0525467fztenghui throw new RuntimeException("Could not get attrib location for muOverlayHandle"); 2173994371aa3bec727ee8dc5643bb4212c0525467fztenghui } 2183994371aa3bec727ee8dc5643bb4212c0525467fztenghui 219b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui /* 220b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * Create our texture. This has to be done each time the surface is 221b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui * created. 222b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui */ 223b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 224b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int[] textures = new int[1]; 225b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glGenTextures(1, textures, 0); 226b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 227b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui mTextureID = textures[0]; 228b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID); 229b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 230b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, 231b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.GL_NEAREST); 232b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 233b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.GL_TEXTURE_MAG_FILTER, 234b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.GL_LINEAR); 235b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 236b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, 237b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.GL_REPEAT); 238b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, 239b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.GL_REPEAT); 240b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 241b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui InputStream is = mContext.getResources() 242b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui .openRawResource(R.drawable.robot); 243b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Bitmap bitmap; 244b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui try { 245b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui bitmap = BitmapFactory.decodeStream(is); 246b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } finally { 247b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui try { 248b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui is.close(); 249b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } catch (IOException e) { 250b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // Ignore. 251b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 252b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 253b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 254b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 255b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui bitmap.recycle(); 256b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 257b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 2583994371aa3bec727ee8dc5643bb4212c0525467fztenghui 2593994371aa3bec727ee8dc5643bb4212c0525467fztenghui EGLDisplay display = EGL14.eglGetCurrentDisplay(); 2603994371aa3bec727ee8dc5643bb4212c0525467fztenghui EGL14.eglSwapInterval(display, 0); 2613994371aa3bec727ee8dc5643bb4212c0525467fztenghui 262b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 263b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 264b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private int loadShader(int shaderType, String source) { 265b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int shader = GLES20.glCreateShader(shaderType); 266b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (shader != 0) { 267b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glShaderSource(shader, source); 268b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glCompileShader(shader); 269b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int[] compiled = new int[1]; 270b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 271b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (compiled[0] == 0) { 272b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Log.e(TAG, "Could not compile shader " + shaderType + ":"); 273b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); 274b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glDeleteShader(shader); 275b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui shader = 0; 276b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 277b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 278b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui return shader; 279b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 280b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 281b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private int createProgram(String vertexSource, String fragmentSource) { 282b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); 283b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (vertexShader == 0) { 284b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui return 0; 285b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 286b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 287b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); 288b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (pixelShader == 0) { 289b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui return 0; 290b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 291b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 292b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int program = GLES20.glCreateProgram(); 293b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (program != 0) { 294b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glAttachShader(program, vertexShader); 295b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui checkGlError("glAttachShader"); 296b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glAttachShader(program, pixelShader); 297b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui checkGlError("glAttachShader"); 298b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glLinkProgram(program); 299b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int[] linkStatus = new int[1]; 300b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); 301b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui if (linkStatus[0] != GLES20.GL_TRUE) { 302b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Log.e(TAG, "Could not link program: "); 303b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Log.e(TAG, GLES20.glGetProgramInfoLog(program)); 304b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui GLES20.glDeleteProgram(program); 305b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui program = 0; 306b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 307b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 308b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui return program; 309b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 310b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 311b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private void checkGlError(String op) { 312b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui int error; 313b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 314b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui Log.e(TAG, op + ": glError " + error); 315b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui throw new RuntimeException(op + ": glError " + error); 316b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 317b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 318b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 319b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private static final int FLOAT_SIZE_BYTES = 4; 320b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; 321b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 322b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; 323b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private final float[] mTriangleVerticesData = { 324b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui // X, Y, Z, U, V 3253994371aa3bec727ee8dc5643bb4212c0525467fztenghui -1.0f, -1.0f, 0, 0.0f, 0.0f, 3263994371aa3bec727ee8dc5643bb4212c0525467fztenghui -1.0f, 1.0f, 0, 0.0f, 1.0f, 3273994371aa3bec727ee8dc5643bb4212c0525467fztenghui 1.0f, -1.0f, 0, 1.0f, 0.0f, 3283994371aa3bec727ee8dc5643bb4212c0525467fztenghui 1.0f, 1.0f, 0, 1.0f, 1.0f, }; 329b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 330b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private FloatBuffer mTriangleVertices; 331b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 332b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private final String mVertexShader = 333b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "uniform mat4 uMVPMatrix;\n" + 334b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "attribute vec4 aPosition;\n" + 335b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "attribute vec2 aTextureCoord;\n" + 336b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "varying vec2 vTextureCoord;\n" + 337b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "void main() {\n" + 338b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui " gl_Position = uMVPMatrix * aPosition;\n" + 339b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui " vTextureCoord = aTextureCoord;\n" + 340b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "}\n"; 341b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 342b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private final String mFragmentShader = 343b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "precision mediump float;\n" + 344b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "varying vec2 vTextureCoord;\n" + 345b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "uniform sampler2D sTexture;\n" + 3463994371aa3bec727ee8dc5643bb4212c0525467fztenghui "uniform vec4 uOverlay;\n" + 347b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "void main() {\n" + 3483994371aa3bec727ee8dc5643bb4212c0525467fztenghui " gl_FragColor = texture2D(sTexture, vTextureCoord) * uOverlay;\n" + 349b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui "}\n"; 350b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 351b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private float[] mMVPMatrix = new float[16]; 352b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private float[] mProjMatrix = new float[16]; 353b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private float[] mMMatrix = new float[16]; 354b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private float[] mVMatrix = new float[16]; 355b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 356b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private int mProgram; 357b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private int mTextureID; 358b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private int muMVPMatrixHandle; 359b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private int maPositionHandle; 360b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private int maTextureHandle; 3613994371aa3bec727ee8dc5643bb4212c0525467fztenghui private int muOverlayHandle; 362b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 363b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private Context mContext; 364b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui private static final String TAG = "GLES20TriangleRenderer"; 365b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui } 366b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui 367b4dabadd89f8a6928b51e809eec6425a3df9b593ztenghui} 368