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.
Related
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.
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.
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.
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);
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.