Search code examples
c++opengltexture-mapping3d-rendering

Texturing 3d Object with UV Map OpenGL


I have a problem with rendering of a 3D Object with UV Map.

First of all my object is in Wavefront model.I use a parser that splits the whole file to vertices,normals,faces and texCoords. After parsing the file.obj i have all of them.

The problem is that texture does not appear to the final result but the object without texturing.

This is the init function:

int init()
{
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
    cout << "SDL error: " << SDL_GetError() << endl;
    return false;
}

// SDL Window crap
createWindow(screenWidth, screenHeight, 32, false, "WaveFront Object Loader");
reshape(screenWidth, screenHeight);

// OpenGL init
// Stuff
glShadeModel(GL_SMOOTH);
glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

// Face culling (for textures)
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); 
glEnable(GL_DEPTH_TEST);

// Lighting
GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glShadeModel(GL_SMOOTH);

// Object loader
if(!model.load("BallForRenderl.obj"))
{
    cout << "Could not load model" << endl;
    return false;
}


return true;
 }

This is the function that draws the scene:

void draw(){

    glPushMatrix();

// clear the screen & depth buffer
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

// set the perspective projection
glCallList(g_persp);

// set the camera position
gluLookAt(  0, 1, -20,  //  eye pos
            0, 0, 0,    //  aim point
            0, 1, 0);   //  up direction

glRotatef(angle, 0.0, 0.5, 1.0);
glColor4f(1.0, 1.0, 1.0, 1.0);


glScalef(0.2,0.2,0.2);

model.draw();

// set the orthographic projection
glCallList(g_ortho);

// 2D/text  *****************************************

glPopMatrix();

// Commented out because we call it in our idle() function - maintains framerate independance
// SDL_GL_SwapBuffers();
}

And this is the function that draws the model:

void WFObject::draw(){

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
glEnable(GL_TEXTURE_2D); 
glColor3f(1.0,1.0,1.0); 
glBegin(GL_TRIANGLES);

for(int f = 0; f < faces.size(); f++)
{
    glNormal3f(normals[faces[f].vn1 - 1].x, normals[faces[f].vn1 - 1].y, normals[faces[f].vn1 - 1].z);
    glVertex3f(vertices[faces[f].v1 - 1].x, vertices[faces[f].v1 - 1].y, vertices[faces[f].v1 - 1].z);
    glTexCoord2f(texCoords[faces[f].vt1 - 1].u,texCoords[faces[f].vt1 - 1].v);
    //printf("%f %f \n",texCoords[faces[f].vt1 - 1].u,texCoords[faces[f].vt1 - 1].v);
    glNormal3f(normals[faces[f].vn2 - 1].x, normals[faces[f].vn2 - 1].y, normals[faces[f].vn2 - 1].z);
    glVertex3f(vertices[faces[f].v2 - 1].x, vertices[faces[f].v2 - 1].y, vertices[faces[f].v2 - 1].z);
    glTexCoord2f(texCoords[faces[f].vt2 - 1].u,texCoords[faces[f].vt2 - 1].v);
    //printf("%f %f \n",texCoords[faces[f].vt2 - 1].u,texCoords[faces[f].vt2 - 1].v);
    glNormal3f(normals[faces[f].vn3 - 1].x, normals[faces[f].vn3 - 1].y, normals[faces[f].vn3 - 1].z);
    glVertex3f(vertices[faces[f].v3 - 1].x, vertices[faces[f].v3 - 1].y, vertices[faces[f].v3 - 1].z);
    glTexCoord2f(texCoords[faces[f].vt3 - 1].u,texCoords[faces[f].vt3 - 1].v);
    //printf("%f %f \n",texCoords[faces[f].vt3 - 1].u,texCoords[faces[f].vt3 - 1].v);
    //printf("\n");
}

glEnd();
glDisable(GL_TEXTURE_2D);

}

I know that maybe i miss something but i cannot solve this although i read a lot of tutorials.

Can anyone help me with this?


Solution

  • glNormal3f(...);
    glVertex3f(...);
    glTexCoord2f(...);  // this will affect the *next* vertex
    

    Wrong order.

    glVertex commands are used within glBegin/glEnd pairs to specify point, line, and polygon vertices. The current color, normal, texture coordinates, and fog coordinate are associated with the vertex when glVertex is called.

    You need to call glTexCoord() before the glVertex() you want it to belong to:

    glNormal3f(...);
    glTexCoord2f(...);
    glVertex3f(...);
    

    You also never seem to bind a texture object (via glBindTexture()) anywhere. You need to bind a texture object so OpenGL knows which texture to sample from.