I tried to add a fairly simple extension on top of the Android OpenGL 2.0 sample project to add texturing to the main shapes. This one seems pretty simple, but on some devices (Samsung Nexus S, LG Optimus 3D, Samsung Galaxy S) the texture just doesn't display.
This is actually a problem that I am experiencing in a much larger project, but I was able to reproduce the problem with a simple project below, hoping that someone here has an idea of where my code represents the problems, or how specifically for GL texture textures for these devices (there may be problems with the devices).
To give an idea of how this object is used: In the GLSurfaceView.Renderer onSurfaceCreated method, I create an instance of the Square() object, and in the onDrawFrame method I call the Square draw() method. However, all the appropriate texture-processing code should appear in this square class, which almost exactly matches Google’s own example.
Many thanks in advance to everyone who hacked this.
class Square { private final String vertexShaderCode = // This matrix member variable provides a hook to manipulate // the coordinates of the objects that use this vertex shader "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "attribute vec2 a_TexCoordinate;" + "varying vec2 v_TexCoordinate;" + "void main() {" + // the matrix must be included as a modifier of gl_Position " gl_Position = vPosition * uMVPMatrix;" + " v_TexCoordinate = a_TexCoordinate;" + "}"; private final String fragmentShaderCode = "precision mediump float;" + "uniform sampler2D u_Texture;" + "varying vec2 v_TexCoordinate;" + "void main() {" + " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);" + "}"; private final FloatBuffer vertexBuffer; private final FloatBuffer textureBuffer; private final ShortBuffer drawListBuffer; private final int mProgram; private int mPositionHandle; private int mColorHandle; private int mMVPMatrixHandle; // number of coordinates per vertex in this array static final int COORDS_PER_VERTEX = 3; static float squareCoords[] = { -0.5f, 0.5f, 0.0f, // top left -0.5f, -0.5f, 0.0f, // bottom left 0.5f, -0.5f, 0.0f, // bottom right 0.5f, 0.5f, 0.0f }; // top right final float[] previewTextureCoordinateData = { 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f }; private int textureDataHandle; private int textureUniformHandle; private int textureCoordinateHandle; private final short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex // Set color with red, green, blue and alpha (opacity) values float color[] = { 0.2f, 0.709803922f, 0.898039216f, 1.0f }; private int loadTexture(final Context context, final int resourceId) { final int[] textureHandle = new int[1]; GLES20.glGenTextures(1, textureHandle, 0); if (textureHandle[0] != 0) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; // No pre-scaling // Read in the resource final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options); // Bind to the texture in OpenGL GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); // Set filtering GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); // Load the bitmap into the bound texture. GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); // Recycle the bitmap, since its data has been loaded into OpenGL. bitmap.recycle(); } if (textureHandle[0] == 0) { throw new RuntimeException("Error loading texture."); } return textureHandle[0]; } public Square(Context context) { // initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect( // (