PDA

View Full Version : animating texture maps



omnivore
03-05-2010, 05:44 PM
I'm a complete noob, but have had some success with the tutorials by Jeff LaMarche.

I am using Open GL ES 1.1 on the iPhone. What I'm trying to do is have different rendering of the same geometry display different sections of the same texture map.

To make this more concrete: I have an array of 5 X 7 tiles -- much like Scrabble tiles. Each of the two main sides is supposed to display a letter. A texture map is divided into 64 areas, each with a letter.

I initialize and store 35 Cocoa objects that correspond to each tile. Each one has two objects that store information about the front and back face of the tile it represents. A randomizing routine guarantees that they are different from each other.

At run time, during rendering, I loop through two nested loops and retrieve the appropriate object and extract the coordinates it has calculated for the offset in the texture map. I push these into the appropriate slots in an Array called texCoords. This means that just before I call glDrawArrays, texCoords has the appropriate values in it that (as far as I can tell) ought to cause the corresponding section of the texture map to be drawn on the appropriate faces.

This is not what is happening. I initialize the texCoords array with values that will draw a certain letter on the faces of the tiles, and it is those initial values that are drawn. In other words, every tile has the same (initially set) letter on it, and it never changes.

Obviously, openGL needs to dump the old value that it is initially fed, and my code is not doing that. This is the core of the rendering process:




static GLfloat rot = 0.0;



glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);

...VARIOUS INITIALIZATIONS HERE ARE OMITTED.

glLoadIdentity();
glClearColor(0.7, 0.7, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//glVertexPointer(3, GL_FLOAT, 0, vertices);
glVertexPointer(3, GL_FLOAT, 0, allVerts);
glColorPointer(4, GL_FLOAT, 0, colors);
glNormalPointer(GL_FLOAT, 0, normals);


NSMutableArray *tempRow;
Cube *tempCube;
for (int i = 1; i <= cubes.tileRows; i++)
{
tempRow = [cubes rowAtIndex:i-1];
for (int j = 1; j <= cubes.tileCols; j++)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
tempCube = [tempRow objectAtIndex:j-1];
texCoords[12] = (GLfloat)tempCube.frontFace.left;
texCoords[13] = (GLfloat)tempCube.frontFace.top;
texCoords[14] = (GLfloat)tempCube.frontFace.left;
texCoords[15] = (GLfloat)tempCube.frontFace.bottom;
texCoords[16] = (GLfloat)tempCube.frontFace.right;
texCoords[17] = (GLfloat)tempCube.frontFace.top;
NSLog(@"frontface left: %f %f", tempCube.frontFace.left, texCoords[12]);



glLoadIdentity();
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glTranslatef(gridOffsetX + (tileSpacing * (GLfloat)i), gridOffsetY + (tileSpacing * (GLfloat)j), gridOffsetZ);
glRotatef(rot, 0.0, 1.0, 0);
glRotatef(90, 0.0, 0.0, 1.0);
//glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cubeFaces);
//glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_BYTE, cubeStripOne);
glDrawArrays(GL_TRIANGLES, 0, 36);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}
}

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
// glDisableClientState(GL_TEXTURE_COORD_ARRAY);


various arrays are given values in above the shown code: I haven't included them because they're pretty uncontentious.

Any Ideas?

mikau
03-06-2010, 12:05 AM
so your cube objects contain fields: left, right, top, bottom. Just one question, do their coordinates range from 0 to 1?

Yo may already know this but texture coordinates range from (0,0) to (1,1) where (0,0) is the upper left corner of the texture, and (1,1) is the bottom right corner of the texture.

I can't be sure, but it LOOKS like you are setting the texture coordinates equal to the coordinates of the actual vertices. If thats what you are doing, you need to create a function to convert it to an appropriate range within 0 and 1.

omnivore
03-06-2010, 03:31 PM
Mikau: I don't think the problem is with the coordinates, which definitely do get calculated as values in the correct range. I understand how mapping coordinates work, and the tiles do in fact show a mapped texture after they are initially set, outside the loop. What they don't do is change their texture to the values calculated/retrieved inside the loop. In the code provided, the NSLog is reading the values out of the texCoords array, and I can see the correct coordinates are coming up.

I am beginning to think that the use of glBegin and glEnd may be the answer here: I am following an example that is pretty minimal, and doesn't really address multiple objects. I suspect that what I'm doing is not allowing openGL to load new values: they get set in the initial part of the drawing routine from which the above code is excerpted, and that unless I do something to flush that data out, the updates won't affect the objects I'm drawing.

Bruce Wheaton
03-07-2010, 10:34 AM
Probably your intialization is relevant. Did you tell OpenGL that you intended to change the tex coord values with a DYNAMIC flag type?

Bruce

omnivore
03-12-2010, 12:27 PM
Actually, it all worked out in the end. I was retrieving values from a set of stored data, but then I was inserting it into the wrong places [12..17] in the texture coords array. Works fine, now I have other problems.

But at least this isn't one of them.