Applying texture to a triangle mesh

I am using “TRIANGLE_FAN” to make a cone.

To apply image texture to the cone should i use cube_map texture?

I was successful while i applied image texture to a single triangle, but while applying to the cone in simillar way the application crashed.

So i had to use cube map texturing to apply the texture to the cone. Is this the right way? Does it mean for any 3D object i need to use cub maps to apply texture?

Any reply to this would be helpful.

Thank you.

No, you do not need a cube map to texture a normal object. Cube maps are intended for things like environment mapping (ie “reflections”).

The crash sounds like a bug in your application - care to post the source code?

OK,

I could solve the problem, but now i dont know why it works.

Please find below my code, the blue block followed by the red block. If executed in the same sequence it is successful. If i just exchange, i.e red block first and then blue block, it crashes at glDrawarray !

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 5 * (sizeof(GLbyte) * 3), vertices, GL_STATIC_DRAW);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_BYTE, sizeof(GLbyte) * 3, 0);

glScalef( 0.01f, 0.01f, 0.01f );
glRotatef((GLfloat)(subtestcase*10), 0.0f, 1.0f, 0.0f);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);

glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glScalef( 0.01f,0.01f,0.01f );
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_BYTE, sizeof(GLbyte) * 4, 0);

glDrawArrays(GL_TRIANGLE_FAN, 0, 5);

No wonder it’s crashing if you swap the two blocks around, you’re feeding a NULL-pointer as texture coordinates. Because there’s no buffer object bound yet, the pointer-parameter to glTexCoordPointer is treated as an absolute pointer, and you pass 0. If you order the blocks the other way around (ie. the way they are in your post), a buffer object with ALMOST sufficient data is bound before setting the pointer. The fact that the code as it is now runs without crashing, is pure luck :wink:

If buffer object 0 is bound all vertex attribute pointers are absolute. If not, they are relative to the currently bound buffer object. Which leads to the next problem - you haven’t made a vbo or filled in sufficient data into the vbo named “buffer”. Since you pass a stride of sizeof(GLbyte) * 4 to glTexCoordPointer, you need sizeof(GLbyte) * 4 * vertex count of data, but you only fill in sizeof(GLbyte) * 3 * vertex count in the buffer object called “buffer”. My guess is that you’d either want a separate buffer object for the texture coordinates (this is the easiest), or interleave the vertex positions and the texture coordinates inside the same buffer object (this is a bit harder, but also usually a bit faster).

Now that i know why it crashes, the second point is not very clear to me.

My understanding was a bit different.

The “size” argument of glvertexpointer was calculated as : vertex_count (5) * co-ordinate size (1byte) * co-ordinate count (3 : xyz). I think this is sufficient to store the vertices.

The “stride” argument of glTexCoordPointer was calculated as : texture is in RGBA format with 1 byte each for color and alpha component. I though that “glTexImage2D” would upload the actual texture.

Please correct my understanding.

There’s a big difference between textures and texture coordinates. The former is typically an image, the latter are per-vertex attributes used to define which part of a texture should be mapped to a triangle. You need both for texturing.

I still dont get the textures on all the faces of a cube.

Please find below my code, if i dont use texCoords then the texture is rendered only on the front face and gets distorted on other faces of the cube.

GLubyte indices[36] = {0, 1, 2, 0, 2, 3,
0, 3, 4, 0, 4, 5,
0, 5, 6, 0, 6, 1,
7, 6, 1, 7, 1, 2,
7, 4, 5, 7, 5, 6,
7, 2, 3, 7, 3, 4
};

GLfloat texCoords[] = {
//FRONT
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
// BACK
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
// LEFT
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
// RIGHT
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
// TOP
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
// BOTTOM
1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f
};

glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 8 * (sizeof(GLfloat) * 4), cube, GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 3, 0);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);

glDrawElements(GL_TRIANGLES, sizeof(indices),GL_UNSIGNED_BYTE, indices);

Thank you.

Indices refer to all vertex attributes, so if you have an array of 24 texcoords you should also have an array of 24 positions as well, not just 8. And the indices should range from 0 to 23. You cannot share vertices between faces if the texture coordinates aren’t also shared.

Thank you very much for the reply.

I modified my code to have 8 texture coordinates, since the cube has 8 vertex coordinates. The vertices are shared. The indices range from 0 to 7. But still the program hangs after executing “glDrawElements”.
and i am using Opengl es 1.1 library.

GLubyte indices[36] = {
0, 1, 2, 0, 2, 3,
0, 3, 4, 0, 4, 5,
0, 5, 6, 0, 6, 1,
7, 6, 1, 7, 1, 2,
7, 4, 5, 7, 5, 6,
7, 2, 3, 7, 3, 4
};

GLfloat texCoords[] = {
1, 0, 0, 0, 0, 1, 1, 1,
0, 0, 0, 1, 1, 1, 1, 0,
};

glBufferData(GL_ARRAY_BUFFER, 8 * (sizeof(GLfloat) * 4), cube, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, sizeof(GLfloat) * 3, 0);

glTexCoordPointer(2, GL_FLOAT, sizeof(GLfloat) * 3, texCoords);

glDrawElements(GL_TRIANGLES, sizeof(indices),GL_UNSIGNED_BYTE, indices);

Please help me.

If you’re not using a buffer object for the texcoords (which is indicated by the fact that you pass a pointer (texCoords) as the last parameter to glTexCoordPointer, you need to unbind the current buffer object before calling glTexCoordPointer. Alternatively, you could either make two buffer objects, or even better - interleave the positions and texture coordinates inside one buffer object.

For performance-reasons, you should also consider putting the indices in a buffer object.

Edit: unbinding the current buffer object would in this case be done by calling “glBindBuffer(GL_ARRAY_BUFFER, 0)”

Thank you very much for the reply.

I used the interleaving technique suggested by you, and i was successful in getting the faces right, even though the textures are not still fitting right. I would experiment on that.

I really did not know that the buffer objects influenced texture co-ordinates, thank you very much for letting me know.