How to create shaded mesh in opengles on android - 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);

Related

openGL ES - drawing empty pixels

I am in a situation where I need to render to a texture using FBO, and I need to remove some pixels from the buffer. That is, draw (0,0,0,0) color in a RGBA colored framebuffer. This will later allow me to later render this texture on top of another one and the 'zero pixels' will not be rendered since I use blending.
The problem is that I cannot draw such color on the screen because GL_BLEND is enabled while I am doing that and the zero pixels aren't rendered to the texture.
So I have tried disabling GL_BLEND just before rendering to the texture, and 1. It continued blending like nothing happened, 2.At some point it renders of all the graphics without blending although it clearly receives the glEnable(GL_BLEND) call.
Here is most of the code:
gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL11.GL_BLEND);
gl.glBindTexture(GL11.GL_TEXTURE_2D, 0);
gl.glFrontFace(GL11.GL_CW);
gl.glVertexPointer(3, GL11.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, textureBuffer);
gl.glPushMatrix();
gl.glTranslatef(start_x+adv_x/2+adv_x*(float)col_idx, start_y+adv_y/2+adv_y*(float)j, -1.0f);
gl.glScalef(adv_x/2, adv_y/2, 1.0f);
gl.glColor4f(0,0,0,0);
gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, vertex.length / 3);
gl.glColor4f(1f, 1f, 1f, 1f);
gl.glPopMatrix();
gl.glEnable(GL11.GL_BLEND);
gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
gl.glDisableClientState(GL11.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
This is code from an Android application, written in Java.
What can be the problem?

OpenGL conflicts when using both multi-texturing and GL_LINES

I have a scene in which I'd like to have some objects drawn using multi-texturing. I'd also like to draw some objects using only gl.glDrawArrays(GL10.GL_LINES...
However, whenever I add objects on-screen that have two textures applied, all objects that use GL_LINES or solid colors become faded.
I tried to put together a simple demo where all objects use the same draw method (hopefully I didn't create more confusion while trying to simplify).
I handle the multi-texturing in Model.java, with the relevant section here:
// Texture 1
gl.glClientActiveTexture(GL10.GL_TEXTURE0);
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexture[0]);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexCoordBuffer1);
gl.glEnable(GL10.GL_TEXTURE_2D);
// Texture 2
gl.glClientActiveTexture(GL10.GL_TEXTURE1);
gl.glActiveTexture(GL10.GL_TEXTURE1);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexture[1]);
gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_DECAL);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexCoordBuffer2);
gl.glEnable(GL10.GL_TEXTURE_2D);
Any help would be greatly appreciated.
Note: Without the multi-textured object, outlines on triangles 1 and 4 are solid. This is how I'd like the outlines to show.
Note: With the multi-textured object (triangle 3), outlines on triangles 1 and 4 are faded.
Found a solution in this previous question that I had thought was unrelated.
I don't understand why, but I needed to call:
gl.glActiveTexture(GL10.GL_TEXTURE0);
after the Texture 2 block.

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.

OpenGL issue on Galaxy S

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

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.

Categories

Resources