OpenGL issue on Galaxy S - android

I've been trying to build myself a little game framework to toy around with writing some basic games for android. I had been testing on a Sony Arc and Galaxy SII without any issues, but recently I had someone with a Galaxy S do some testing for me and the results were bad.
First run I hadn't set my images sizes to be powers of 2 or square so the majority of the GUI was just big white boxes. So I resized all my images to be power of 2 AND square to get rid of any problems there, and that fixed it for some images, but I'm finding that some of the objects still show as a white texture. I can tell it's drawing in the appropriate spot because I can see the white box rotating and moving as it should for the game.
I thought it may have been an issue with the images being 32 bit, so I took all of my images and reduced them to 8 bit and the results are the same, only about half of the textures seem to be working. I also saw somewhere that mentioned the drawable-nodpi folder, so I moved all my images out of the other folders and put them in there to try that(same results)
I had been looking at this tutorial and it was what I used to base my drawing code off this
http://obviam.net/index.php/texture-mapping-opengl-android-displaying-images-using-opengl-and-squares/
But something I've added or changed must be messing things up, I've included my code below, does anything jump out at anyone that I missed or did wrong?
This is where my Renderer gets created
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
// for transparency
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
}
Here's where I'm loading the texture
public void loadGLTexture(GL10 gl, Context context, int resourceId)
{
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);
mImageWidth = bitmap.getWidth();
mImageHeight = bitmap.getHeight();
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// create nearest filtered texture
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);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);//i added
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);//i added
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
And this is where I do my Draw
public void draw(GL10 gl, float x, float y, float z, float angle, float percentageScale) {
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glTranslatef(x,y,z);
gl.glScalef(mXScale*percentageScale, mYScale*percentageScale, 1);
gl.glRotatef(angle, 0, 0, 1);
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glPopMatrix();
}
I have a base class (called textures) that does the drawing for all of my sprites, but for some reason some of them just never seem to get drawn on the Galaxy S and I end up with white boxes for them.
Any ideas?
PS advice on better ways to do this are certainly welcome, I'll be the first to admit that I'm new to OpenGL

Related

OpenGL: Textures seem not to blend correctly on top of translucent surface

I am drawing objects in OpenGL in this order and z-order:
A background quad,
background objects = images with titles (textures)
a translucent black quad which darkens the background objects (colored quad with low alpha value),
and foreground objects = images with titles (textures, but the one in the center has a white quad behind it)
Currently, it looks like this:
This is not as it's supposed to be - the 5 objects around "Chikinki" (Timid Tiger, The Bishops,...) should be as bright as the "Chikinki" picture. Also, all titles (including Chikinki's) are darker than the textures really are. It seems to me as though the white quad behind the "Chikinki" image somehow forces OpenGL to draw the pic in front of it rightly. Without the translucent black quad (which is there to darken all objects except the one in the middle and 5 around it), everything is fine. So I suspect that this translucent quad somehow bleeds through, although the other objects are drawn after it and have a higher z-value.
As mentioned, the objects are drawn back-to-front, and also laid out back-to-front z-wise. Blending is always enabled. The white rectangle has blending function: gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); and all images have function gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);. Depth-test is enabled.
Relevant texture-fill quad drawing code (too dim in the screenshot):
gl.glPushMatrix();
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureName);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
mFVertexBuffer.position(0);
mTexBuffer.position(0);
mIndexBuffer.position(0);
gl.glDisable(GL10.GL_TEXTURE_2D);
gl.glDisable(GL10.GL_BLEND);
gl.glPopMatrix();
Relevant color-fill quad drawing code (shown OK in the screenshot):
gl.glPushMatrix();
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
gl.glColor4f(mRed, mGreen, mBlue, mAlpha);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
mFVertexBuffer.position(0);
mIndexBuffer.position(0);
gl.glPopMatrix();
gl.glDisable(GL10.GL_BLEND);
Have you got any clue what could be causing the darkening of these objects which should by all means be fully opaque, considering that they are drawn AFTER the translucent quad and have a HIGHER z-value?
SOLUTION
Tim pointed out in the comments that texture drawing is affected by the current color buffer (its alpha value). Calling gl.glColor4f(1,1,1,1); before drawing the images did the trick, reverting the earlier call to gl.glColor4f() with a lower-than-1 alpha value.

Android OpenGL ES texture animation

I'm developing a game for android and this is my first experience with OpenGL.
When the application loads I create my vertices and texture buffers, I load images from drawable resources; using GLUtils.tex2Image2D to bind the image to a texture array.
I was wondering if glBindTexture() was the correct function to use when changing the texture to produce animation.
public void onDraw(GL10 gl){
sprite.animate();
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[sprite.frameNumber]);
sprite.draw(gl);
}
Code Explanation
sprite.animate() - changes the frame number depending on System.uptimeMillis()
sprite.draw() - does the actual drawing:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
The function does work, but I wanted to confirm it was the correct function to use, or if there is an alternative way to do this.
Binding a different texture to animate is one way to do what you want.
A more popular way of doing this is to have all your animations frames in a big texture (pack all the individual frames in a huge rectangle): to draw a different frame, just change the texture coordinates.
For example, pack four frames of animation in a big 2x2 square
1|2
3|4
Then you'll use for texture coordinates (0,0) (0.5,0) (0.5,0.5) (0,0.5) to display frame 1, and the rest should be obvious.

Problems displaying transparent textures with OpenGL ES on Android

I've invested now more than a day looking for a solution on how to render transparent textures with OpenGL on Android. Obviously others had more luck than I but after trying various solutions (e.g. Transparent texture in OpenGL ES for Android) offered I still cannot get it done.
Here is my basic setup:
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0.0f, 0.0f, 0.0f, 1);
gl.glShadeModel(GL10.GL_FLAT);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_LIGHTING);
gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
GL10.GL_MODULATE);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glViewport(0, 0, w, h);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluOrtho2D(gl, -ratio, ratio, -1, 1);
The textures are loaded via ...
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_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
GL10.GL_CLAMP_TO_EDGE);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
GL10.GL_MODULATE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
... and there are hints that this leads to problems due to pre-multiplied alpha. But ReplicaIsland does use the GLUtils function as well and the game does not seem to have problems with transparent images.
Now if I draw textures with alpha channel (PNG) they appear solidly black. Textures without alpha are drawn correctly in their respective color). I applied various glBlendFunc calls without luck, i.e.
gl.glShadeModel(GL10.GL_FLAT);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
I also gave this one a try
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
The result is always that the textures are no visible at all (fully transparent?).
Images for testing are used from the ReplicaIsland project, these are standard PNGs. This also means that the textures used conform to the power-of-2-rule - another solution offered in various posts. I see one difference which is that ReplicaIsland seems mostly to rely on the draw_texture extension whereas I have to use VBOs (in order to be able to apply rotations).
Help would be greatly appreciated!
Thanks
Ben
Ok, another day of debugging goes by and finally I found my error. It had nothing to do with the color scheme of the bitmap, glBlendFunc or something like this.
I turned out to be a sloppy use of GL_FIXED and GL_FLOAT in two texture function calls.

How to create shaded mesh in opengles on android

In my application I'm trying to create a mesh that is shaded by a single directional light. The problem I'm facing is that I can't seem to get the light to take my normals into account at all.
It works fine if I set the normals on a per-triangle-strip basis, but if I try to render a series of triangles with normals set using the glNormalPointer method the entire mesh is rendered using the same color (which is identical to the result I'm getting if I skip calling glNormalPointer all together).
My mesh render method looks like this:
public void render(GL10 gl) {
gl.glFrontFace(GL10.GL_CW);
gl.glNormalPointer(GL10.GL_FLOAT, 0, normalBuffer);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.capacity(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
}
You should call
glEnableClientState(GL_NORMAL_ARRAY);

Basic OpenGL ES Texture problem / Android

I'm having great difficulty getting basic textures to work in an OpenGL ES app on my Droid (2.1-update1). I trying to render a simple textured quad - four vertices, two faces, with normals and texture coords. When rendered, the texture is garbled and full of static, similar to TV noise.
Here's a pic showing the original texture map image, and then a screencap from my droid of the rendered textured quad : http://img686.imageshack.us/img686/6342/texturedquad.png
The basic colors are there, but obviously the texture isn't being read or applied correctly.
My texture load sequence is simple :
int[] textures = new int[1];
gl.glGenTextures(1, textures, 0);
Bitmap bmp = BitmapFactory.decodeResource(cx.getResources(), R.drawable.img);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
I've tried setting various parameters for glTexParameterf at texture load time, but to no avail :
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);
My render sequence is also very simple :
(setup)
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glDisable(GL10.GL_DITHER);
gl.glDisable(GL10.GL_FOG);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glDisable(GL10.GL_COLOR_MATERIAL);
gl.glShadeModel(GL10.GL_SMOOTH);
(render)
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_SHORT, 0, textureCoords);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);
gl.glDrawElements(GL10.GL_TRIANGLES, numIndices, GL10.GL_UNSIGNED_SHORT, indices);
...
I've tried various texture image file formats, all sized ^2, placed under the drawable-nodpi folder. PNG, BMP, GIF, JPEG all give me the same result. I've also tried 8 and 16 bit color depths. I'm running this on top of GLSurfaceView with the default EGL config.
Can anyone shed some light on why my texture is coming through garbled?
Below is my index/vertex/normal/texcoord data. I've been over it a dozen times but perhaps I missed something.
Adding vertex (vIndex 1) Vector3F(77.0492, 0.0, 0)
Adding vertex (vIndex 2) Vector3F(478.1715, 0.0, 0)
Adding vertex (vIndex 3) Vector3F(478.1715, 227.0969, 0)
Adding vertex (vIndex 4) Vector3F(77.0492, 227.0969, 0)
Adding normal Vector3F(0.0, 0.0, 1.0)
Adding normal Vector3F(0.0, 0.0, 1.0)
Adding normal Vector3F(0.0, 0.0, 1.0)
Adding normal Vector3F(0.0, 0.0, 1.0)
Adding textureCoords Vector3F(0.0, 0.0)
Adding textureCoords Vector3F(1.0, 0.0)
Adding textureCoords Vector3F(1.0, 1.0)
Adding textureCoords Vector3F(0.0, 1.0)
Adding face indexes 1,2,3
Adding face indexes 3,4,1
Ok disregard my question, I found the issue.
It turns out my texture coordinates were stored as 32-bit unsigned ints, and I was passing GL_SHORT into the glTexCoordPointer call (I needed to be using GL_FIXED). This explains the random static texture mapping you can see in the rendered result.

Categories

Resources