Results 1 to 5 of 5

Thread: OBJ Model Texturing Problem

  1. #1
    Senior Member Regular Contributor
    Join Date
    May 2002
    Posts
    189

    OBJ Model Texturing Problem

    For some reason the texturing coordinates don't seem to be working with my obj class code. Does anybody see why? Thanks

    Here's the cpp file:

    Code :
    #include <stdio.h> // Header File For Input/Output
    #include <string.h> // Header for working with strings
    #include <stdarg.h>
    #include <iostream.h> // Header for C++ console input/output
    #include <fstream.h> // Header for C++ file I/O
    #include <math.h> // Header for sine and cosine
    #include <gl/glfw.h> // Header for GLFW, OpenGL and GLU
    #include <gl/gl.h> // Header file for OpenGL 
    #include <gl/glaux.h> // Header file for GLaux
    #include <gl/glu.h> // Header file for glu
    #include <gl/glut.h> // Header file for glut
    #include "objLoader.h" // Header file for the OBJ variables/class
    #include "loadTexture.h"
     
    void OBJ::displayModel() {
    for(int i = 0; i cout << texcordx[ faces.texCords[0] ] << texcordy[ faces[i].texCords[0] ] << endl;
    cout << texcordx[ faces[i].texCords[1] ] << texcordy[ faces[i].texCords[1] ] << endl;
    cout << texcordx[ faces[i].texCords[2] ] << texcordy[ faces[i].texCords[2] ] << endl;
    } 
    }
     
    void OBJ::readstr(FILE *f,char *string) // Reads A String From File (f)
    {
    do // Do This
    {
    fgets(string, 255, f); // Gets A String Of 255 Chars Max From f (File)
    } while ((string[0] == '/') &amp;#0124; &amp;#0124; (string[0] == '\n')); // Until End Of Line Is Reached
    return; // Return
    }
     
    void OBJ::drawOBJ(int mode) {
    if(mode==0) {
    glColor4f(1, 1, 1, 1);
    for(int i = 0; i if(faces[i].status==0 &amp;#0124; &amp;#0124; 4) {
    glBegin( GL_TRIANGLES );
    glVertex3f(vertx[faces[i].vertices[0]-1], verty[faces[i].vertices[0]-1], vertz[faces[i].vertices[0]-1]);
    glVertex3f(vertx[faces[i].vertices[1]-1], verty[faces[i].vertices[1]-1], vertz[faces[i].vertices[1]-1]);
    glVertex3f(vertx[faces[i].vertices[2]-1], verty[faces[i].vertices[2]-1], vertz[faces[i].vertices[2]-1]);
    glEnd();
    }
    else if(faces[i].status==1 &amp;#0124; &amp;#0124; 5) {
    glBegin( GL_QUADS );
    glVertex3f(vertx[faces[i].vertices[0]-1], verty[faces[i].vertices[0]-1], vertz[faces[i].vertices[0]-1]);
    glVertex3f(vertx[faces[i].vertices[1]-1], verty[faces[i].vertices[1]-1], vertz[faces[i].vertices[1]-1]);
    glVertex3f(vertx[faces[i].vertices[2]-1], verty[faces[i].vertices[2]-1], vertz[faces[i].vertices[2]-1]);
    glVertex3f(vertx[faces[i].vertices[3]-1], verty[faces[i].vertices[3]-1], vertz[faces[i].vertices[3]-1]);
    glEnd();
    }
    else if(faces[i].status==2 &amp;#0124; &amp;#0124; 6) {
    glBegin( GL_TRIANGLES );
     
    glTexCoord2f(texcordx[faces[i].texCords[0]-1], texcordy[faces[i].texCords[0]-1]); 
    glVertex3f(vertx[faces[i].vertices[0]-1], verty[faces[i].vertices[0]-1], vertz[faces[i].vertices[0]-1]);
     
    glTexCoord2f(texcordx[faces[i].texCords[1]-1], texcordy[faces[i].texCords[1]-1]); 
    glVertex3f(vertx[faces[i].vertices[1]-1], verty[faces[i].vertices[1]-1], vertz[faces[i].vertices[1]-1]);
     
    glTexCoord2f(texcordx[faces[i].texCords[2]-1], texcordy[faces[i].texCords[2]-1]); 
    glVertex3f(vertx[faces[i].vertices[2]-1], verty[faces[i].vertices[2]-1], vertz[faces[i].vertices[2]-1]);
     
    glEnd();
    }
    else if(faces[i].status==3 &amp;#0124; &amp;#0124; 7) {
    glBegin( GL_QUADS );
     
    glTexCoord2f(texcordx[faces[i].texCords[0]-1], texcordy[faces[i].texCords[0]-1]); 
    glVertex3f(vertx[faces[i].vertices[0]-1], verty[faces[i].vertices[0]-1], vertz[faces[i].vertices[0]-1]);
     
    glTexCoord2f(texcordx[faces[i].texCords[1]-1], texcordy[faces[i].texCords[1]-1]); 
    glVertex3f(vertx[faces[i].vertices[1]-1], verty[faces[i].vertices[1]-1], vertz[faces[i].vertices[1]-1]);
     
    glTexCoord2f(texcordx[faces[i].texCords[2]-1], texcordy[faces[i].texCords[2]-1]); 
    glVertex3f(vertx[faces[i].vertices[2]-1], verty[faces[i].vertices[2]-1], vertz[faces[i].vertices[2]-1]);
     
    glTexCoord2f(texcordx[faces[i].texCords[3]-1], texcordy[faces[i].texCords[3]-1]); 
    glVertex3f(vertx[faces[i].vertices[3]-1], verty[faces[i].vertices[3]-1], vertz[faces[i].vertices[3]-1]);
     
    glEnd();
    }
    }
    }
    }
     
    int OBJ::loadOBJ(const char *filename) {
     
    char strLine[255] = { 0 };
    // Check to make sure the extension is obj
    int length;
     
    char c; // a simple buffer
    char b; // another buffer
    char d; // yet another buffer
     
    int howmuch; // For parsing the f lines
    char type[10]; // What type is the current line
    int values[12]; // The ints being read in (f)
    float valuesf[3]; // The floats being read in (v, vt, & vn)
    int counter[4] = { 0, 0, 0, 0 }; // A counter for which line we are on
    char charbuffer[255];
    int percentRight = 0; // The percentage of values successfully matched
     
    length = strlen(filename);
    if( length < 5) {
    cout << "Filename given to loadOBJ is too short to be complete. Aborting" << endl;
    exit(-1);
    }
    if(FILE *inputfile = fopen(filename, "r")) {
    // Our first task will be to allocate all of the appropriate space for the vertices, texture cords, and lighting normals
    while(feof(inputfile)==0) {
    c = fgetc(inputfile);
    if(c=='v') {
    b = fgetc(inputfile);
    if(b==' ') { // Its a vertex
    verts++;
    }
    else if(b=='t') { // Its a texture cordinate
    cords++;
    }
    else if(b=='n'){ // If its niether then its a lighting normal
    normals++;
    }
    }
    if(c=='f') { // The actual polygon faces that are to be drawn
    facesn++;
    } // That should do it, we are done parsing the f lines and counting them up
    if(c=='g') {
    groups++;
    }
    }
    // Now establish memory for storing all of them
     
    vertx = new float [verts];
    verty = new float [verts];
    vertz = new float [verts];
     
    texcordx = new float [cords];
    texcordy = new float [cords];
     
    lightingx = new float [normals];
    lightingy = new float [normals];
    lightingz = new float [normals];
     
    faces = new polyface [facesn]; // Declare room for each polyface
     
     
    // Now read in all of the values to the memory after going back to the beginning for the second pass
    fseek(inputfile,0,SEEK_SET); // Reset to the beginning of the file
    while(feof(inputfile)==0) { 
    linenumber++;
    readstr(inputfile, charbuffer);
    sscanf(charbuffer, "%s %f %f %f", &amp;type, &amp;valuesf[0], &amp;valuesf[1], &amp;valuesf[2]);
     
    // Its a vertex or a normal
    if(strcmp(type, "v")==0) {
    vertx[counter[0]] = valuesf[0];
    verty[counter[0]] = valuesf[1];
    vertz[counter[0]] = valuesf[2];
    counter[0]++;
    }
    else if(strcmp(type, "vn")==0) {
    lightingx[counter[1]] = valuesf[0];
    lightingy[counter[1]] = valuesf[1];
    lightingz[counter[1]] = valuesf[2];
    counter[1]++;
    }
    else if(strcmp(type, "vt")==0) {
    texcordx[counter[2]] = valuesf[0];
    texcordy[counter[2]] = valuesf[1];
    counter[2]++;
    }
    else if(strcmp(type, "f")==0) {
    // if its a polygon face then we must parse it as follows
    howmuch = sscanf(charbuffer, "f %d %d %d %d", &amp;values[0], &amp;values[1], &amp;values[2], &amp;values[3]);
    if(howmuch==3) {
    // They are drawing a polygon face with no vertex cordinates or lighting normals but its a triangle
    faces[counter[3]].status = 0;
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[1];
    faces[counter[3]].vertices[2] = values[2];
    counter[3]++;
    }
    else if(howmuch==4) {
    // They are drawing a polygon face with no vertex cordinates or lighting normals but its a quad
    faces[counter[3]].status = 1;
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[1];
    faces[counter[3]].vertices[2] = values[2];
    faces[counter[3]].vertices[3] = values[3];
    counter[3]++;
    }
    else if(howmuch<3) {
    // In this situation the polygon face contains lighting normals and texture cordinates
    howmuch = sscanf(charbuffer, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d",
    &amp;values[0], &amp;values[1], &amp;values[2],
    &amp;values[3], &amp;values[4], &amp;values[5],
    &amp;values[6], &amp;values[7], &amp;values[8],
    &amp;values[9], &amp;values[10], &amp;values[11]);
    if(howmuch==12) {
    // Here we verify that the format of the f line is as displayed in the sscanf above
    // It would be a quad with 4 vertices, lighting normals, and texture cords
    faces[counter[3]].status = 5;
     
    // Assign vertices to memory
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[3];
    faces[counter[3]].vertices[2] = values[6];
    faces[counter[3]].vertices[3] = values[9];
     
    // Assign texture coordinates to memory
    faces[counter[3]].texCords[0] = values[1];
    faces[counter[3]].texCords[1] = values[4];
    faces[counter[3]].texCords[2] = values[7];
    faces[counter[3]].texCords[3] = values[10];
     
    // Assign lighting normals to memory
    faces[counter[3]].uvNormals[0] = values[2];
    faces[counter[3]].uvNormals[1] = values[5];
    faces[counter[3]].uvNormals[2] = values[8];
    faces[counter[3]].uvNormals[3] = values[11];
     
    counter[3]++;
    }
    else if(howmuch==9) {
    // Here we verify that the format of the f line is as displayed in the sscanf above
    // It would be a triangle with 3 vertices, texture cords, and lighting normals
    faces[counter[3]].status = 4;
     
    // Assign vertices to memory
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[3];
    faces[counter[3]].vertices[2] = values[6];
     
    // Assign texture coordinates to memory
    faces[counter[3]].texCords[0] = values[1];
    faces[counter[3]].texCords[1] = values[4];
    faces[counter[3]].texCords[2] = values[7];
     
    // Assign lighting normals to memory
    faces[counter[3]].uvNormals[0] = values[2];
    faces[counter[3]].uvNormals[1] = values[5];
    faces[counter[3]].uvNormals[2] = values[8];
     
    counter[3]++;
    }
    else if(howmuch==1) {
    /*
    This is run if the format above does not apply. 
    In this case the f line is *PROBABLY* in the format
    f v//vn v//vn v//vn v//vn etc
    As you can see the texture coordinates are being left out.
    While this isn't present in personwithgun.obj or foot.obj, we will
    add it in to help comply with the obj specification.
    */
    howmuch = sscanf(charbuffer, "f %d//%d %d//%d %d//%d %d//%d", 
    &amp;values[0], &amp;values[1],
    &amp;values[2], &amp;values[3],
    &amp;values[4], &amp;values[5],
    &amp;values[6], &amp;values[7]);
    if(howmuch==8) {
    faces[counter[3]].status = 7;
     
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[2];
    faces[counter[3]].vertices[2] = values[4];
    faces[counter[3]].vertices[3] = values[6];
     
    faces[counter[3]].uvNormals[0] = values[1];
    faces[counter[3]].uvNormals[1] = values[3];
    faces[counter[3]].uvNormals[2] = values[5];
    faces[counter[3]].uvNormals[3] = values[7];
     
    counter[3]++;
    }
    else if(howmuch==6) {
    faces[counter[3]].status = 6;
     
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[2];
    faces[counter[3]].vertices[2] = values[4];
     
    faces[counter[3]].uvNormals[0] = values[1];
    faces[counter[3]].uvNormals[1] = values[3];
    faces[counter[3]].uvNormals[2] = values[5];
     
    counter[3]++;
    }
    else if(howmuch==1) {
    howmuch = sscanf(charbuffer, "f %d/%d %d/%d %d/%d %d/%d",
    values[0], values[1],
    values[2], values[3],
    values[4], values[5],
    values[6], values[7]);
    if(howmuch==6) {
    // If this is the case the f line is a triangle with
    // no lighting normals.
    faces[counter[3]].status = 2;
     
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[2];
    faces[counter[3]].vertices[2] = values[4];
     
    faces[counter[3]].texCords[0] = values[1];
    faces[counter[3]].texCords[1] = values[3];
    faces[counter[3]].texCords[2] = values[5];
     
    counter[3]++;
    }
    else if(howmuch==8) {
    // For this condition the f line is a quad with no
    // lighting normals
    faces[counter[3]].status = 3;
     
    faces[counter[3]].vertices[0] = values[0];
    faces[counter[3]].vertices[1] = values[2];
    faces[counter[3]].vertices[2] = values[4];
    faces[counter[3]].vertices[3] = values[6];
     
    faces[counter[3]].texCords[0] = values[1];
    faces[counter[3]].texCords[1] = values[3];
    faces[counter[3]].texCords[2] = values[5];
    faces[counter[3]].texCords[3] = values[7];
     
    counter[3]++;
    } // else if
    } // else if
    } // else if
    } // else if
    } // if
    else {
    cout << "skipped line" << endl;
    } // else
    } // while
     
    cout << verts << " " << cords << " " << normals << " " << groups << endl;
    fclose(inputfile);
    return true;
    }
    else {
    return false;
    }
    }
     
     
    And the header file:
     
    #ifndef _OBJLOADER_H_
    #define _OBJLOADER_H_
     
    #include <stdio.h> // Header File For Input/Output
    #include <string.h> // Header for working with strings
    #include <stdarg.h>
    #include <iostream.h> // Header for C++ console input/output
    #include <fstream.h> // Header for C++ file I/O
     
    class OBJ {
    public:
    void displayModel();
    void readstr(FILE *f,char *string);
    void drawOBJ(int mode);
    int loadOBJ(const char *filename);
    private:
    int linenumber;
    struct polyface {
    int vertices[4];
    int texCords[4];
    int uvNormals[4];
    int status; 
    };
    /*
    In reference to the status variable, if it is 0 it means its a triangle with 3 vertices, no tex
    cords, and no lighting normals. If it is 1 then it means that its a quad with 4 vertices, no
    tex cords, and no lighting normals. If it is 2 then it means that its a triangle with 3
    vertices, 3 texture cordinates, and no lighting normals. If it is a 3 then it means its a quad
    with 4 vertices, 4 tex cords, and no lighting normals. If it is a 4 then it means that its a
    triangle with 3 tex cords, vertices, and lighting normals. If its a 5 then it means its a quad
    with 4 tex cords, vertices, and lighting normals. If its a 6 then it means its a 
    triangle with 3 vertices and 3 lighting normals but if its a 7 its a quad. Sounds simple eh?
    */
     
    /* 
    Here's all the memory used for storing the obj data. Please note the data is shared
    between loadOBJ and drawOBJ. Obviously this program needs a more object oriented structure
    however for now this gets the job done
    */
    // Vertice memory
    float *vertx;
    float *verty;
    float *vertz;
     
    // Texture Coordinate memory
    float *texcordx;
    float *texcordy;
     
    // Lighting normal memory
    float *lightingx;
    float *lightingy;
    float *lightingz;
     
    int verts; // how many vertices
    int cords; // how many texture coordinates
    int normals; // how many normals
    int groups; // how many groups
    int facesn; // how many face lines
     
    // Pointer for f lines
    polyface *faces;
     
    };
     
    #endif

  2. #2
    Senior Member OpenGL Guru Relic's Avatar
    Join Date
    Apr 2000
    Posts
    2,450

    Re: OBJ Model Texturing Problem

    1.) "for(int i = 0; i if(faces[i].status==0 &#0124; &#0124; 4) {"

    Does your code compile?

    2.) "if(faces[i].status==0 &#0124; &#0124; 4)"

    Evaluates always to TRUE because of the "&#0124; &#0124; 4", and will never touch the else-if?

    For performance and readability you should try to put vertx, verty, vertz into float vert[][3] arrays and call glVertex3fv(vert[faces[i].vertices[0]-1]);

  3. #3
    Senior Member Regular Contributor
    Join Date
    May 2002
    Posts
    189

    Re: OBJ Model Texturing Problem

    Whoa you were right! I assumed that the &#0124; &#0124; operator was smarter than that but I guess not. I made your first suggested changes and now it draws it perfectly! However it still doesn't texture. Very strange...

  4. #4
    Senior Member OpenGL Guru Relic's Avatar
    Join Date
    Apr 2000
    Posts
    2,450

    Re: OBJ Model Texturing Problem

    Did you call glEnable(GL_TEXTURE_2D) somewhere?
    (Read the RedBook and have a look at switch-case statements in C.)

  5. #5
    Senior Member Regular Contributor
    Join Date
    May 2002
    Posts
    189

    Re: OBJ Model Texturing Problem

    I'm pretty sure its enabled correctly. It looks as though the model is textured with only one texture coordinate as the model changes colors. I have the color as glColor3f(1, 1, 1) but the color is NOT white. Any ideas?

Similar Threads

  1. texturing a car model
    By nick2price in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 12-05-2008, 01:04 PM
  2. how to do model clothing & multi-model texturing.
    By Deepak Roy Chittajallu in forum OpenGL: Advanced Coding
    Replies: 6
    Last Post: 11-19-2004, 07:26 PM
  3. GLUT texturing solid model...
    By Cybernet_X in forum OpenGL: Linux
    Replies: 3
    Last Post: 07-16-2002, 08:30 AM
  4. texturing a md2 model
    By eckiller in forum OpenGL: Advanced Coding
    Replies: 1
    Last Post: 04-09-2000, 05:08 PM
  5. texturing problem
    By eckiller in forum OpenGL: Advanced Coding
    Replies: 2
    Last Post: 03-23-2000, 06:17 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean