Test GL Texture with rotation and glDrawTexfOES
address issue mentioned in https://groups.google.com/group/android-developers/browse_thread/thread/9c0ccb1a215586a8/2f28259213340eab?hl=en&lnk=gst&q=opengl+galaxy#2f28259213340eab
Change-Id: I98ce3c0250b83eccb62de2997bf8c4a7ec5cea51
diff --git a/tests/tests/openglperf/AndroidManifest.xml b/tests/tests/openglperf/AndroidManifest.xml
index d687246..e47c0bc 100644
--- a/tests/tests/openglperf/AndroidManifest.xml
+++ b/tests/tests/openglperf/AndroidManifest.xml
@@ -42,6 +42,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:name="android.openglperf.cts.TextureTestActivity" />
</application>
</manifest>
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java b/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java
new file mode 100644
index 0000000..6a0a14e
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/GlTextureCoordTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.openglperf.cts;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+/**
+ * check TextureTestRenderer for details
+ */
+public class GlTextureCoordTest extends
+ ActivityInstrumentationTestCase2<TextureTestActivity> {
+
+ public GlTextureCoordTest() {
+ super(TextureTestActivity.class);
+ }
+
+ public void testTextureCoord() throws InterruptedException {
+ getActivity();
+ Thread.sleep(3000); // give some time to render some frames
+ }
+}
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java
new file mode 100644
index 0000000..4d7d641
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.openglperf.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class TextureTestActivity extends Activity {
+ private GLSurfaceView mGLView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mGLView = new TextureTestSurfaceView(this);
+ setContentView(mGLView);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mGLView.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mGLView.onResume();
+ }
+}
+
+class TextureTestSurfaceView extends GLSurfaceView {
+
+ public TextureTestSurfaceView(Context context){
+ super(context);
+ setRenderer(new TextureTestRenderer());
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java
new file mode 100644
index 0000000..96b2e44
--- /dev/null
+++ b/tests/tests/openglperf/src/android/openglperf/cts/TextureTestRenderer.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.openglperf.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+
+import junit.framework.Assert;
+
+/**
+ * This test is for checking an issue
+ * mentioned in https://groups.google.com/group/android-developers/browse_thread/thread/
+ * 9c0ccb1a215586a8/2f28259213340eab?hl=en&lnk=gst&q=opengl+galaxy#2f28259213340eab
+ * The GPU driver seems to change texture coordinates inside glDrawTexfOES, and
+ * texture inside following drawing does not work as expected.
+ * The thread also mentions texture malfunctioning with rotation,
+ * but that was not observed, but the case will cover both.
+ */
+public class TextureTestRenderer implements GLSurfaceView.Renderer {
+ private static final String TAG = "TextureTest";
+ private static final float[] mVerticesData = {
+ // X, Y, Z, s, t
+ -1.0f, -1.0f, 0, 0.6f, 0.f,
+ 1.0f, -1.0f, 0, 0.7f, 0.f,
+ -1.0f, 1.0f, 0, 0.6f, 0.1f,
+ 1.0f, 1.0f, 0, 0.7f, 0.1f,
+ };
+ private static final int FLOAT_SIZE_BYTES = 4;
+ private static final int GEOMETRY_STRIDE = 20;
+
+ private final FloatBuffer mVertices;
+ private final Bitmap mBitmap;
+ private int mTextureID;
+ private boolean mOesDrawTextureSupported = false;
+ private int mWidth;
+ private int mHeight;
+ private float mRotationAngle = 0f;
+
+ public TextureTestRenderer() {
+ mVertices = ByteBuffer.allocateDirect(mVerticesData.length
+ * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mVertices.put(mVerticesData).position(0);
+ // 4x4 texture with 4 colors
+ int[] colors = {
+ Color.RED, Color.RED, Color.BLUE, Color.BLUE,
+ Color.RED, Color.RED, Color.BLUE, Color.BLUE,
+ Color.GREEN, Color.GREEN, Color.CYAN, Color.CYAN,
+ Color.GREEN, Color.GREEN, Color.CYAN, Color.CYAN
+ };
+ mBitmap = Bitmap.createBitmap(colors, 4, 4, Bitmap.Config.ARGB_8888);
+ }
+
+ public void onDrawFrame(GL10 gl) {
+ // Redraw background color
+ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+
+ gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+ GL10.GL_REPLACE);
+
+ // Set GL_MODELVIEW transformation mode
+ gl.glMatrixMode(GL10.GL_MODELVIEW);
+ gl.glLoadIdentity(); // reset the matrix to its default state
+
+ // When using GL_MODELVIEW, you must set the view point
+ GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+ gl.glActiveTexture(GL10.GL_TEXTURE0);
+ gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+ gl.glEnable(GL10.GL_TEXTURE_2D);
+
+ // red for default color
+ gl.glColor4f(1.0f, 0f, 0f, 1.0f);
+ gl.glVertexPointer(3, GL10.GL_FLOAT, GEOMETRY_STRIDE, mVertices);
+ gl.glTexCoordPointer(2, GL10.GL_FLOAT, GEOMETRY_STRIDE, mVertices
+ .duplicate().position(3));
+ if (mOesDrawTextureSupported) {
+ // left / bottom / width / height (negative w/h flip the image)
+ int crop[] = new int[] { 0, 0, 4, 4 };
+
+ ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
+ GL11Ext.GL_TEXTURE_CROP_RECT_OES, crop, 0);
+ // 4x4 drawing in left-bottom corner
+ ((GL11Ext) gl).glDrawTexfOES(0, 0, 0, 4, 4);
+ }
+ gl.glPushMatrix();
+ gl.glRotatef(mRotationAngle, 0f, 0f, 1f);
+ mRotationAngle += 10f;
+ if (mRotationAngle > 360f) {
+ mRotationAngle = 0f;
+ }
+ gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
+ gl.glPopMatrix();
+ // for one pixel
+ IntBuffer pixel = ByteBuffer.allocateDirect(4).asIntBuffer();
+ gl.glReadPixels(mWidth / 2, mHeight / 2, 1, 1, GL10.GL_RGBA,
+ GL10.GL_UNSIGNED_BYTE, pixel);
+ pixel.position(0);
+ Log.i(TAG, "pixel read " + Integer.toHexString(pixel.get(0)));
+
+ Assert.assertEquals(0x0000ffff, pixel.get(0)); // BLUE in RGBA
+
+ checkGlError(gl, "onDrawFrame");
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ gl.glViewport(0, 0, width, height);
+
+ // make adjustments for screen ratio
+ float ratio = (float) width / height;
+ gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
+ gl.glLoadIdentity(); // reset the matrix to its default state
+ gl.glFrustumf(-2 * ratio, 2 * ratio, -2, 2, 3, 7);
+ checkGlError(gl, "onSurfaceChanged");
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
+ Log.i(TAG, "extensions: " + extensions);
+ if (extensions.contains("GL_OES_draw_texture")) {
+ mOesDrawTextureSupported = true;
+ }
+ // Set the background frame color
+ gl.glClearColor(0f, 0f, 0f, 1.0f);
+ gl.glEnable(GL10.GL_TEXTURE_2D);
+
+ gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+ gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+ int[] textures = new int[1];
+ gl.glGenTextures(1, textures, 0);
+
+ mTextureID = textures[0];
+ gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
+
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
+ GL10.GL_NEAREST);
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
+ GL10.GL_NEAREST); // necessary due to low resolution texture
+
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+ GL10.GL_CLAMP_TO_EDGE);
+ gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+ GL10.GL_CLAMP_TO_EDGE);
+ GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
+ checkGlError(gl, "onSurfaceCreated");
+ }
+
+ private void checkGlError(GL10 gl, String op) {
+ int error;
+ while ((error = gl.glGetError()) != GL10.GL_NO_ERROR) {
+ Log.e(TAG, op + ": glError " + error);
+ throw new IllegalStateException(op + ": glError " + error);
+ }
+ }
+}