I have a mesh loaded by an obj file (wavefront), complete with normals and texture coordinates per face, and its relative texture available. In my C++ / OpenGL code (assignment for a computer graphics class) I bind correctly the texture, but fail at correctly mapping texture coordinates with face vertexes. Below I show the code for texture binding and the chain of calls to rasterize the object. I also show images for the expected result and the actual results (2 of them, one for each render setting). To be specific, it seems that the first render "tessellates" the plain image on the rasterized shape of the whole object, while the second maps the image once on the shape of the object.

What is going on here?

Expected result Result #1 Result #2 (don't mind the background)

Bind procedure:

SDL_Surface *s = IMG_Load(filename.c_str());

glBindTexture(GL_TEXTURE_2D, textureIndex);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB,
        s->w, s->h, GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
        GL_LINEAR );

Raster procedure (pseudo code intended):

// gl pushMatrix, Traslation and rotations;
glBindTexture(GL_TEXTURE_2D, textureIndex);
for (face f in faces) {
  glNormal3d(faceNormal.x, faceNormal.y, faceNormal.z);
  for (i = 0, i < 3, ++i) {
    glTexCoord3d(texturePoint[i].x, texturePoint[i].y, 0);
    glVertex3d(vertex[i].x, vertex[i].y, vertex[i].z);
// gl PopMatrix to exit from traslation / rotation context.
  • $\begingroup$ What's your GL_TEXTURE_MATRIX set to? Perhaps it has some scaling in it? (Also, what's the matrix mode for this code? You push the current matrix, but don't appear to be setting the mode before doing so.) $\endgroup$ – user1118321 Jun 19 '16 at 23:54
  • $\begingroup$ Before the bind code: glMatrixMode(GL_PROJECTION ); glLoadIdentity(); gluPerspective(70, 3.0/4, 0.2, 1000 ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); No scaling of sort (actually there was, but when you mentioned it I removed it and it didn't change the result by much). $\endgroup$ – phagio Jun 20 '16 at 19:44

I see you use glEnable(GL_TEXTURE_GEN_S); but also use glTexCoord(...) to load coordinates. These are mutually exclusive features IIRC. If you are supplying your own texture coordinates you should not need to use glEnable(GL_TEXTURE_GEN_n).

  • $\begingroup$ You're right! I just tried to delete those lines and the first example now behaves like the second one. At this point I think the second example has just a "rotated texture" issue, I'll try and let you know. $\endgroup$ – phagio Jul 7 '16 at 11:33
  • $\begingroup$ Yep, I confirm, that did the trick. Thank you immensely! $\endgroup$ – phagio Jul 7 '16 at 12:20
for (i = 0, i < 3, ++i)
    glTexCoord3d(texturePoint[i].x, texturePoint[i].y, 0);
    glVertex3d(v[i]->x(), v[i]->y(), v[i]->z());

This code calls glTexCoord3d three times and glVertex3d only once. You need more braces around your for loop.

  • $\begingroup$ Hi and thank you :) sorry, it is a typo: the cycle is correct (otherwise i would be out of scope). I'm adding the necessary braces. $\endgroup$ – phagio Jun 17 '16 at 13:29

Your geometry may be prepared for Direct3D, which has texture space origin placed differently (top-left vs bottom-left corner). Try flipping either the texture's Y coordinates (i.e. load it from the bottom to the top), or the V texture coordinate (glTexCoord3d(texturePoint[i].x, 1.0f - texturePoint[i].y, 0);).

  • $\begingroup$ Tried that and didn't work. I think it's not the case of Direct3D geometry, because I'm on Ubuntu - isn't Direct3D a Microsoft exclusive? $\endgroup$ – phagio Jun 20 '16 at 19:38
  • $\begingroup$ Update: it actually had something to do with that, although it was a minor fault. $\endgroup$ – phagio Jul 21 '16 at 7:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.