Hi all, I'm having a pickle of a problem with some fairly simple opengl texture mapping.
I have a situation where I want to tile a texture across a surface larger than the texture bitmap.. pretty standard stuff. I have a simple triangle "grid" that I use to setup the vertices etc (code pasted below). The problem is that the code works perfectly for some textures, and weirdly for others. Interestingly it behaves differently for the same bitmap in different cases. When the texture is corrupt, it looks like my vertices have been setup in the wrong order or something because the triangle pairs look backwards, and distorted.. see the two images below: Texture OK: http://img829.imageshack.us/i/textureok.png/ Texture Corrupt http://img20.imageshack.us/i/texturecorrupt.png/ You can see in the corrupt version that the individual "stones" are split diagonally and sort of distorted into a rhomboid shape. Plus there's some funky pixels along the bottom. The only difference in these two cases is the dimensions of the surface onto which the texture is mapped. I also get the same problem on "some" textures which are mapping to surfaces of a size identical to the size of the bitmap (i.e not tiling).. but again, it works for some and not others. It works all the time on the emulator, but fails on a real device (HTC Desire in my case). Here's the code I'm using (paraphrased): ================================================= .... // Load bitmap Bitmap bitmap = null; InputStream is = context.getResources().openRawResource(resourceId); ... try { // sBitmapOptions is just sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565; bitmap = BitmapFactory.decodeStream(is, null, sBitmapOptions); } finally { is.close(); } .... // Bind texture // mTextureNameWorkspace is just an int array // mTextureHash is a simple data structure holding texture refs gl.glGenTextures(mTextureHash.size(), mTextureNameWorkspace, 0); // textureName is just an int taken from the mTextureNameWorkspace above gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName); 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_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT); gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); .... // Setup gl gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); gl.glClearColor(0,0,0, 1); gl.glShadeModel(GL10.GL_FLAT); gl.glDisable(GL10.GL_DEPTH_TEST); gl.glDisable(GL10.GL_DITHER); gl.glDisable(GL10.GL_LIGHTING); gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnable(GL10.GL_TEXTURE_2D); .... // create the texture grid // width & height are the dimensions of the sprite (as floats).. not the texture. float hW = width / 2.0f; float hH = height / 2.0f; // Use the dims to create the vertices. vertices = new float[] { -hW, hH, 0.0f, // 0, Top Left -hW, -hH, 0.0f, // 1, Bottom Left hW, -hH, 0.0f, // 2, Bottom Right hW, hH, 0.0f, // 3, Top Right }; // a float is 4 bytes, therefore we multiply the number if // vertices with 4. ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); vbb.order(ByteOrder.nativeOrder()); vertexBuffer = vbb.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); // short is 2 bytes, therefore we multiply the number if // vertices with 2. ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indices); indexBuffer.position(0); // textureWidth and textureHeight are basically the dimensions of the bitmap (as floats) if(textureWidth > 0) { // create the texture buffer. // We need to tile the texture so we dont stretch the bitmap float u = width / textureWidth; float v = height / textureHeight; texVerts = new float[] { 0.0f,0.0f, // 0, Top Left 0.0f,v, // 1, Bottom Left u,v, // 2, Bottom Right u,0.0f, // 3, Top Right }; ByteBuffer tbb = ByteBuffer.allocateDirect(texVerts.length * 4); tbb.order(ByteOrder.nativeOrder()); textureBuffer = tbb.asFloatBuffer(); textureBuffer.put(texVerts); textureBuffer.position(0); } // Do the draw // Counter-clockwise winding. gl.glFrontFace(GL10.GL_CCW); // Enable face culling. gl.glEnable(GL10.GL_CULL_FACE); // What faces to remove with the face culling. gl.glCullFace(GL10.GL_BACK); // Specifies the location and data format of an array of vertex // coordinates to use when rendering. gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); // Disable face culling. gl.glDisable(GL10.GL_CULL_FACE); // Tear down.. blah blah... ================================================= Sorry for pasting so much code.. but just not sure where the problem is... Am I winding up the triangles wrongly or something? Any help GREATLY appreciated. Cheers, Jason. -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

