blob: 96b2e440df640b6618fc91e8359338566c04aff8 [file] [log] [blame]
/*
* 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);
}
}
}