Adding a decal using multitexturing on an iPhone - iphone

I'm trying to overlay one image on top of another onto a simple quad. I set my bottom image as texture unit 0, and then my top image (which has a variable alpha) as texture unit 1. Unit 2 has mode GL_DECAL, which means the bottom texture should show up when the alpha is 0, and the top texture should show when the alpha is 1. But, only the top texture shows up and the bottom one doesn't appear at all. It's just white where the bottom texture should show through.
glGetError() doesn't report any problems. Any help is appreciated. Thanks!
glVertexPointer(3, GL_FLOAT, 0, boxVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, boxTextureCoords);
glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, boxTextureCoords);
glClientActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glClientActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glClientActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, one.texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glClientActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, two.texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

Since you're using vertex arrays, you need to use glClientActiveTexture instead of glActiveTexture when setting your texture coords.

Related

Changing Alpha Value of OpenGL ES Object - GL_BLEND - iPhone

I have a textured object in my OpenGL ES scene (version 1.1) for which I want to change the alpha to 0.5.
I am trying the following code :
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, 0.5);
glVertexPointer(3, GL_FLOAT, 0, vertexes);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0, textures);
GLfloat ambientAndDiffuse[] = kAmbience;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, ambientAndDiffuse);
GLfloat specular[] = kSpecular;
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, kShininess);
GLfloat emission[] = kEmission;
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission);
glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, indices);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
The problem is that the transparency of the model is not changing. The model is displayed on the screen correctly, however the alpha is still 1.
EDIT
My textures are jpgs. Do I need to save these as PNGs ?
Can anyone spot how I can correct this ?
Thank you.
Ah think I've solved it - you need to turn off the lighting and then it seems to work.
glDisable(GL_LIGHTING);
Have you set the texture environment variable to modulate? Like this:
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
That tells OpenGL to multiply the object's color by the texture's color. Also, I don't remember if you need to use a GL_COLOR_ARRY with glDrawElements() instead of just setting the current color.

opengl es 2.0 textures the right way

i am new to opengl es 2.0 on ios, i am trying to create few objects (made from vertices) and assign each a different texture, i found out i can do that by binding then drawing in the render function like this:
inside render():
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _Texture1);
glUniform1i(_textureUniform, 0);
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
i repeat the code above for every texture with only changing _Texture1 in glBindTexture to _Texture2 etc..
before all this i setup the textures as follows:
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
i would like to know what is the right way to give textures to different vertices, should it even be done inside the render function?
this doesn't seem the right way to do it.
(here is the full code if i didnt explain myself fully: http://codetidy.com/1709/ )
You are doing it the correct way. OpenGL is a "state machine", so you have to set the state for the render pipe line each frame drawn. Essentially all your drawing will be done inside your render function.

iPhone OpenGL-ES: Adding a texture to one face of a cube

building a 3D environment, So far I have fully textured cubes and colored cubes. What I want to do is add a texture to one of the Coloured cube faces
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &colourCubeVertexFaces[0]);
glColor4ub(colourCubeFaceColors[colorIndex], colourCubeFaceColors[colorIndex+1], colourCubeFaceColors[colorIndex+2], colourCubeFaceColors[colorIndex+3]);glColor4ub(colourCubeFaceColors[colorIndex], colourCubeFaceColors[colorIndex+1], colourCubeFaceColors[colorIndex+2], colourCubeFaceColors[colorIndex+3]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &colourCubeVertexFaces[6]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &colourCubeVertexFaces[12]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &colourCubeVertexFaces[18]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &colourCubeVertexFaces[24]);
I thought it would be as easy as turning on (and off)
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Then Bind a texture
glBindTexture(GL_TEXTURE_2D, ([[coordsArray objectAtIndex:4] floatValue]));
and then plotting it
glTexCoordPointer(2, GL_FLOAT, 0, texturedCubeCoord);
But it just seems to slow down alot and not show anything. My other fully textured cubes are fine.
You need to glEnable(GL_TEXTURE_2D)

Separately rotating 2 texture coordinates sets for the same object

I've given this a go for a while, but I haven't been able to get favorable results. Basically, I have a sphere with 2 textures. One is blended on top with other and the idea is to have it be a face environment mapping. I want one texture to rotate with the sphere and the other to stay fixed to the initial texture coordinates.
I have tried rotating the GL_TEXTURE matrix of one texture and resetting the other, but this doesn't really do the trick because the texture mapping isn't right when it's rotated certain ways.
Anyone know how i can rotate only one set of texture coordinates and keep the other fixed?
Here's my render code at the moment:
glColor4f(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glClientActiveTexture( GL_TEXTURE0);
glActiveTexture( GL_TEXTURE0);
glBindTexture( GL_TEXTURE_2D, tex[0]);
glEnableClientState( GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &SphereVertexData[0].texCoord);
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glTranslatef(0, 0, -4.5f);
glRotatef(.00001, .00001, .0, .0);
glClientActiveTexture( GL_TEXTURE1);
glActiveTexture( GL_TEXTURE1);
glEnable( GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, tex[1]);
glEnableClientState( GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &SphereVertexData[0].texCoord);
glPopMatrix();
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0, 0, -4.5f);
glVertexPointer(3, GL_FLOAT, sizeof(TexturedVertexData3D), &SphereVertexData[0].vertex);
glNormalPointer(GL_FLOAT, sizeof(TexturedVertexData3D), &SphereVertexData[0].normal);
glDrawArrays(GL_TRIANGLES, 0, kSphereNumberOfVertices);
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
rotation += .0001;
If anyone needs to see more of what is going on just let me know.
You could use two spheres and only issue the glRotatef() to the sphere with the texture that you want rotating. The other sphere would just receive the corresponding glTranslatef() commands. If you are using the alpha channel to blend the textures it should work the same.

OpenGL-ES variable texture alpha (2D)?

I have a texture with transparency (the white triangle with that lighting information), and just can't make it's alpha variable.
alt text http://gotoandplay.freeblog.hu/files/alpha_help.png
The drawing code, with the missing piece:
//Place polygon vertices to the bottom left within the view.
glLoadIdentity();
glTranslatef(centerX, centerY, 0);
//Draw "diffuse" layer.
glBindTexture(GL_TEXTURE_2D, spriteTexture[0]); //Bind.
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//Offset during development only.
glLoadIdentity();
glTranslatef(centerX-10, centerY+10, 0);
//Draw "specular" layer.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, spriteTexture[1]); //Bind.
//Some smart alpha scaling code needs here...
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Could somebody please help me out with the appropriate lines of code?
Some glBlendFunc, or maybe glTextEnvi stuff I suppose.
Ok, I got it even if I don't understand what I did exactly.
//Place polygon vertices to the bottom left within the view.
glLoadIdentity();
glTranslatef(centerX, centerY, 0);
//--1
//Draw "diffuse" layer.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, spriteTexture[0]); //Bind.
//Blending.
glBlendFunc(GL_ONE, GL_ONE);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//--2
//Draw "specular" layer.
glBindTexture(GL_TEXTURE_2D, spriteTexture[1]); //Bind.
//Blending.
glColor4f(opacity, opacity, opacity, opacity);
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
I tried another way before...
glColor4f(1.0f, 1.0f, 1.0f, opacity);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
...but the second map was somehow "weaker".