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

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)

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.

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.

Adding a decal using multitexturing on an 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.

Animating a texture across a surface in OpenGL

I'm working with the iPhone OpenGLES implementation and I wish to endlessly scroll a texture across a simple surface (two triangles making up a rectangle). This should be straightforward, but it's not something I've done before and I must be missing something. I can rotate the texture fine, but translate does not work at all. Do I have a minor implementation issue or am I doing something fundamentally wrong?
// move texture
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
// increment offset - no reset for demo purposes
wallOffset += 1.0;
// move the texture - this does not work
glTranslatef(wallOffset,wallOffset,0.0);
// rotate the texture - this does work
//glRotatef(wallOffset, 1.0, 0.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glBindTexture(GL_TEXTURE_2D, WallTexture.name);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
// simple drawing code
glNormalPointer(GL_FLOAT, 0, normals);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// push matrix back
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
You're incrementing your texture offset by 1.0f; but textures coordinates are considered in the range [0, 1], so you're not actually changing the texture coordinates (assuming you've enabled some sort of wrapping).
Try changing that increment (try .01f, or maybe something depending on the framerate) and see if it works. If not, then it may have something to do with the texture parameters you've got enabled.