2014-05-14 65 views
0

當我嘗試從mtl文件加載紋理時,顯示單一顏色。我試圖通過改變照明來解決它,但它不起作用。我是Opengl的新手,並使用cpplusplusguy的opengl教程系列進行學習。 我正在使用的圖像! http://i.imgur.com/3QfAtnD.png?1 我得到的結果! http://i.imgur.com/BOiOhA0.png從obj文件加載時顯示單色而不是紋理

我的文件

SDL.cpp

#include "objloader.h" 

//Screen dimension constants 
const int SCREEN_WIDTH = 640; 
const int SCREEN_HEIGHT = 480; 
float angle = 0.0; 
//Starts up SDL, creates window, and initializes OpenGL 
bool init(); 

//Initializes matrices and clear color 
bool initGL(); 

//Per frame update 
void update(); 

//Renders quad to the screen 
void render(); 

//Frees media and shuts down SDL 
void close(); 

int loadObject(const char* filename); 
//The window we'll be rendering to 
SDL_Window* gWindow = NULL; 

//OpenGL context 
SDL_GLContext gContext; 

bool init() 
{ 
    //Initialization flag 
    bool success = true; 

    //Initialize SDL 
    if(SDL_Init(SDL_INIT_VIDEO) < 0) 
    { 
     printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError()); 
     success = false; 
    } 
    else 
    { 
     //Use OpenGL 2.1 
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); 
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); 

     //Create window 
     gWindow = SDL_CreateWindow("SDL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 
     if(gWindow == NULL) 
     { 
      printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); 
      success = false; 
     } 
     else 
     { 
      //Create context 
      gContext = SDL_GL_CreateContext(gWindow); 
      if(gContext == NULL) 
      { 
       printf("OpenGL context could not be created! SDL Error: %s\n", SDL_GetError()); 
       success = false; 
      } 
      else 
      { 
       //Use Vsync 
       if(SDL_GL_SetSwapInterval(1) < 0) 
       { 
        printf("Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError()); 
       } 

       //Initialize OpenGL 
       if(!initGL()) 
       { 
        printf("Unable to initialize OpenGL!\n"); 
        success = false; 
       } 
      } 
     } 
    } 

    return success; 
} 


int cube; 
objloader obj; 
bool initGL() 
{ 
    bool success = true; 
    GLenum error = GL_NO_ERROR; 
    glClearColor(0.0, 0.0, 0.0, 1.0); 
    //Initialize Projection Matrix 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(45.0,640.0/480.0,1.0,500.0); 

    //Check for error 
    error = glGetError(); 
    if(error != GL_NO_ERROR) 
    { 
     printf("Error initializing OpenGL! %s\n", gluErrorString(error)); 
     success = false; 
    } 

    //Initialize Modelview Matrix 
    glMatrixMode(GL_MODELVIEW); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_DEPTH_TEST); 
    cube=obj.load("test.obj"); 
    //cube = loadObject("test.obj"); 
    //glEnable(GL_LIGHTING); 
    //glEnable(GL_LIGHT0); 
    //glEnable(GL_FOG); 
    //glFogi(GL_FOG_MODE,GL_EXP); 
    //glFogf(GL_FOG_DENSITY,0.6); 
    //float col[] = {0.5,0.5,0.5,1.0}; 
    //glFogfv(GL_FOG_COLOR,col); 
    float col[] = {1.0,1.0,1.0,1.0}; 
    // glLightfv(GL_LIGHT0,GL_DIFFUSE,col); 



    //Check for error 
    error = glGetError(); 
    if(error != GL_NO_ERROR) 
    { 
     printf("Error initializing OpenGL! %s\n", gluErrorString(error)); 
     success = false; 
    } 


    //Check for error 
    error = glGetError(); 
    if(error != GL_NO_ERROR) 
    { 
     printf("Error initializing OpenGL! %s\n", gluErrorString(error)); 
     success = false; 
    } 

    return success; 
} 

void update() 
{ 
    //No per frame update needed 
} 

void render() 
{ 
    //Clear color buffer 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
     glLoadIdentity(); 
     float pos[]={0.0,10.0,-50.0,-5.0}; 
     //glLightfv(GL_LIGHT0,GL_POSITION,pos); 
     glTranslatef(0.0,0.5,-5.0); 
     //glRotatef(angle,1.0,1.0,1.0); 
     glCallList(cube); 
} 

void close() 
{ 
    //Destroy window 
    SDL_DestroyWindow(gWindow); 
    gWindow = NULL; 

    //Quit SDL subsystems 
    SDL_Quit(); 
} 

int main(int argc, char* args[]) 
{ 
    //Start up SDL and create window 
    if(!init()) 
    { 
     printf("Failed to initialize!\n"); 
    } 
    else 
    { 
     //Main loop flag 
     bool quit = false; 

     //Event handler 
     SDL_Event e; 


     //While application is running 
     while(!quit) 
     { 
      //Handle events on queue 
      while(SDL_PollEvent(&e) != 0) 
      { 
       //User requests quit 
       if(e.type == SDL_QUIT) 
       { 
        quit = true; 
       } 
       else if(e.type == SDL_KEYDOWN) 
       { 
        if(e.key.keysym.sym == SDLK_ESCAPE) 
        { 
         quit = true; 
        } 
       } 

      } 

      //Render quad 
      render(); 
      angle += 0.5; 
      if(angle > 360) 
      { 
       angle -= 360; 
      } 
      //Update screen 
      SDL_GL_SwapWindow(gWindow); 
     } 

    } 

    //Free resources and close SDL 
    close(); 

    return 0; 
} 

objloader.h

#ifndef OBJLOADER_H 
#define OBJLOADER_H 

#include <SDL.h> 
#include <SDL_opengl.h> 
#include <GL\GLU.h> 
#include <stdio.h> 
#include <cstdlib> 
#include <vector> 
#include <string> 
#include <algorithm> 
#include <fstream> 
#include <cstdio> 
#include<iostream> 
#include<SDL_image.h> 
#include <math.h> 

//This struct contain 3 floats and a constructor, it's used for vertexes and normal vectors 
struct coordinate{ 
    float x,y,z; 
    coordinate(float a,float b,float c); 
}; 

//This structure is store every property of a face 
struct face{ 
    int facenum; //the number of the face (it's start from 1 not 0, so if you use it as an index, subtract 1 from it), it's used for the normal vectors 
    bool four;  //if true, than it's a quad else it's a triangle 
    int faces[4]; //indexes for every vertex, which makes the face (it's start from 1 not 0, so if you use it as an index, subtract 1 from it) 
    int texcoord[4]; //indexes for every texture coorinate that is in the face (it's start from 1 not 0, so if you use it as an index, subtract 1 from it) 
    int mat;     //the index for the material, which is used by the face 
    face(int facen,int f1,int f2,int f3,int t1,int t2,int t3,int m); //constuctor for triangle 
    face(int facen,int f1,int f2,int f3,int f4,int t1,int t2,int t3,int t4,int m); //-"- for quad 
}; 

//this is a structure, which contain one material 
struct material{ 
    std::string name; //the name of the material 
    float alpha,ns,ni; //some property, alpha, shininess, and some other, which we not used 
    float dif[3],amb[3],spec[3]; //the color property (diffuse, ambient, specular) 
    int illum; //illum - we not use it 
    int texture; //the id for the texture, if there is no texture than -1 
    material(const char* na,float al,float n,float ni2,float* d,float* a,float* s,int i,int t); 
}; 

//texture coorinate (UV coordinate), nothing to explain here 
struct texcoord{ 
    float u,v; 
    texcoord(float a,float b); 
}; 

//the main class for the object loader 
class objloader{ 
    std::vector<std::string*> coord; //every line of code from the obj file 
    std::vector<coordinate*> vertex; //all vertexes 
    std::vector<face*> faces;     //all faces 
    std::vector<coordinate*> normals; //all normal vectors 
    std::vector<unsigned int> texture;//the id for all the textures (so we can delete the textures after use it) 
    std::vector<unsigned int> lists; //the id for all lists (so we can delete the lists after use it) 
    std::vector<material*> materials; //all materials 
    std::vector<texcoord*> texturecoordinate; //all texture coorinate (UV coordinate) 
    bool ismaterial,isnormals,istexture; //obvious 
    unsigned int loadTexture(const char* filename); //private load texture function 
    void clean(); //free all of the used memory 

    public: 
    objloader(); 
    ~objloader(); //free the textures and lists 
    int load(const char* filename); //the main model load function 
}; 


#endif // OBJLOADER_H 

objloader.cpp

#include "objloader.h" 
    //nothing to explain here 
    coordinate::coordinate(float a,float b,float c) 
    { 
     x=a; 
     y=b; 
     z=c; 
    } 
    //nothing to explain here 
    face::face(int facen,int f1,int f2,int f3,int t1,int t2,int t3,int m){ 
     facenum=facen; 
     faces[0]=f1; 
     faces[1]=f2; 
     faces[2]=f3; 
     texcoord[0]=t1; 
     texcoord[1]=t2; 
     texcoord[2]=t3; 
     mat=m; 
     four=false; 
    } 
    //nothing to explain here 
    face::face(int facen,int f1,int f2,int f3,int f4,int t1,int t2,int t3,int t4,int m){ 
     facenum=facen; 
     faces[0]=f1; 
     faces[1]=f2; 
     faces[2]=f3; 
     faces[3]=f4; 
     texcoord[0]=t1; 
     texcoord[1]=t2; 
     texcoord[2]=t3; 
     texcoord[3]=t4; 
     mat=m; 
     four=true; 
    } 

    //nothing to explain here 
    material::material(const char* na,float al,float n,float ni2,float* d,float* a,float* s,int i,int t) 
    { 
     name=na; 
     alpha=al; 
     ni=ni2; 
     ns=n; 
     dif[0]=d[0]; 
     dif[1]=d[1]; 
     dif[2]=d[2]; 

     amb[0]=a[0]; 
     amb[1]=a[1]; 
     amb[2]=a[2]; 

     spec[0]=s[0]; 
     spec[1]=s[1]; 
     spec[2]=s[2]; 

     illum=i; 
     texture=t; 
    } 

    //nothing to explain here 
    texcoord::texcoord(float a,float b) 
    { 
     u=a; 
     v=b; 
    } 

int objloader::load(const char* filename) 
{ 
    std::ifstream in(filename); //open the model file 
    if(!in.is_open()) 
    { 
     std::cout << "Nor oepened" << std::endl; //if it's not opened then error message, and return with -1 
     return -1; 
    } 
    char buf[256]; //temp buffer 
    int curmat=0; //the current (default) material is 0, it's used, when we read the faces 
    while(!in.eof()) 
    { 
     in.getline(buf,256); //while we are not in the end of the file, read everything as a string to the coord vector 
     coord.push_back(new std::string(buf)); 
    } 
    for(int i=0;i<coord.size();i++) //and then go through all line and decide what kind of line it is 
    { 
     if((*coord[i])[0]=='#') //if it's a comment 
      continue; //we don't have to do anything with it 
     else if((*coord[i])[0]=='v' && (*coord[i])[1]==' ') //if a vertex 
     { 
      float tmpx,tmpy,tmpz; 
      sscanf(coord[i]->c_str(),"v %f %f %f",&tmpx,&tmpy,&tmpz); //read the 3 floats, which makes up the vertex 
      vertex.push_back(new coordinate(tmpx,tmpy,tmpz)); //and put it in the vertex vector 
     }else if((*coord[i])[0]=='v' && (*coord[i])[1]=='n') //if it's a normal vector 
     { 
      float tmpx,tmpy,tmpz; 
      sscanf(coord[i]->c_str(),"vn %f %f %f",&tmpx,&tmpy,&tmpz); 
      normals.push_back(new coordinate(tmpx,tmpy,tmpz)); //basically do the same 
      isnormals=true; 
     }else if((*coord[i])[0]=='f') //if it's a face 
     { 
      int a,b,c,d,e; 
      if(count(coord[i]->begin(),coord[i]->end(),' ')==4) //if this is a quad 
      { 
       if(coord[i]->find("//")!=std::string::npos) //if it's contain a normal vector, but not contain texture coorinate 
       { 
        sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b,&e,&b); //read in this form 
        faces.push_back(new face(b,a,c,d,e,0,0,0,0,curmat)); //and put to the faces, we don't care about the texture coorinate in this case 
                                   //and if there is no material, it doesn't matter, what is curmat 
       }else if(coord[i]->find("/")!=std::string::npos) //if we have texture coorinate and normal vectors 
       { 
        int t[4]; //texture coorinates 
        //read in this form, and put to the end of the vector 
        sscanf(coord[i]->c_str(),"f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d",&a,&t[0],&b,&c,&t[1],&b,&d,&t[2],&b,&e,&t[3],&b); 
        faces.push_back(new face(b,a,c,d,e,t[0],t[1],t[2],t[3],curmat)); 
       }else{ 
        //else we don't have normal vectors nor texture coorinate 
        sscanf(coord[i]->c_str(),"f %d %d %d %d",&a,&b,&c,&d); 
        faces.push_back(new face(-1,a,b,c,d,0,0,0,0,curmat)); 
       } 
      }else{ //if it's a triangle 
          //do the same, except we use one less vertex/texture coorinate/face number 
        if(coord[i]->find("//")!=std::string::npos) 
        { 
         sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b); 
         faces.push_back(new face(b,a,c,d,0,0,0,curmat)); 
        }else if(coord[i]->find("/")!=std::string::npos) 
        { 
         int t[3]; 
         sscanf(coord[i]->c_str(),"f %d/%d/%d %d/%d/%d %d/%d/%d",&a,&t[0],&b,&c,&t[1],&b,&d,&t[2],&b); 
         faces.push_back(new face(b,a,c,d,t[0],t[1],t[2],curmat)); 
        }else{ 
         sscanf(coord[i]->c_str(),"f %d %d %d",&a,&b,&c); 
         faces.push_back(new face(-1,a,b,c,0,0,0,curmat)); 
        } 
      } 
    }else if((*coord[i])[0]=='u' && (*coord[i])[1]=='s' && (*coord[i])[2]=='e') //use material material_name 
    { 
     char tmp[200]; 
     sscanf(coord[i]->c_str(),"usemtl %s",tmp); //read the name of the material to tmp 
     for(int i=0;i<materials.size();i++) //go through all of the materials 
     { 
      if(strcmp(materials[i]->name.c_str(),tmp)==0) //and compare the tmp with the name of the material 
      { 
       curmat=i; //if it's equal then set the current material to that 
       break; 
      } 
     } 
    }else if((*coord[i])[0]=='m' && (*coord[i])[1]=='t' && (*coord[i])[2]=='l' && (*coord[i])[3]=='l') //material library, a file, which contain 
                                                      //all of the materials 
    { 
     char filen[200]; 
     sscanf(coord[i]->c_str(),"mtllib %s",filen); //read the filename 
     std::ifstream mtlin(filen); //open the file 
     if(!mtlin.is_open()) //if not opened error message, clean all memory, return with -1 
     { 
      std::cout << "connot open the material file" << std::endl; 
      clean(); 
      return -1; 
     } 
     ismaterial=true; //we use materials 
     std::vector<std::string> tmp;//contain all of the line of the file 
     char c[200]; 
     while(!mtlin.eof()) 
     { 
      mtlin.getline(c,200); //read all lines to tmp 
      tmp.push_back(c); 
     } 
     char name[200]; //name of the material 
     char filename[200]; //filename of the texture 
     float amb[3],dif[3],spec[3],alpha,ns,ni; //colors, shininess, and something else 
     int illum; 
     unsigned int texture; 
     bool ismat=false; //do we already have a material read in to these variables? 
     strcpy(filename,"\0"); //set filename to nullbyte character 
     for(int i=0;i<tmp.size();i++) //go through all lines of the mtllib file 
     { 
      if(tmp[i][0]=='#') //we don't care about comments 
       continue; 
      if(tmp[i][0]=='n' && tmp[i][1]=='e' && tmp[i][2]=='w') //new material 
      { 
       if(ismat) //if we have a material 
       { 
        if(strcmp(filename,"\0")!=0) //if we have a texture 
        { 
         materials.push_back(new material(name,alpha,ns,ni,dif,amb,spec,illum,texture)); //push back 
         strcpy(filename,"\0"); 
        }else{ 
          materials.push_back(new material(name,alpha,ns,ni,dif,amb,spec,illum,-1));  //push back, but use -1 to texture 
        } 
       } 
       ismat=false; //we start from a fresh material 
       sscanf(tmp[i].c_str(),"newmtl %s",name); //read in the name 
      }else if(tmp[i][0]=='N' && tmp[i][1]=='s') //the shininess 
      { 
       sscanf(tmp[i].c_str(),"Ns %f",&ns); 
       ismat=true; 
      }else if(tmp[i][0]=='K' && tmp[i][1]=='a') //the ambient 
      { 
       sscanf(tmp[i].c_str(),"Ka %f %f %f",&amb[0],&amb[1],&amb[2]); 
       ismat=true; 
      }else if(tmp[i][0]=='K' && tmp[i][1]=='d') //the diffuse 
      { 
       sscanf(tmp[i].c_str(),"Kd %f %f %f",&dif[0],&dif[1],&dif[2]); 
       ismat=true; 
      }else if(tmp[i][0]=='K' && tmp[i][1]=='s') //the specular 
      { 
       sscanf(tmp[i].c_str(),"Ks %f %f %f",&spec[0],&spec[1],&spec[2]); 
       ismat=true; 
      }else if(tmp[i][0]=='N' && tmp[i][1]=='i') //the I don't know what is this 
      { 
       sscanf(tmp[i].c_str(),"Ni %f",&ni); 
       ismat=true; 
      }else if(tmp[i][0]=='d' && tmp[i][1]==' ') //the alpha 
      { 
       sscanf(tmp[i].c_str(),"d %f",&alpha); 
       ismat=true; 
      }else if(tmp[i][0]=='i' && tmp[i][1]=='l') //the illum (don't ask) 
      { 
       sscanf(tmp[i].c_str(),"illum %d",&illum); 
       ismat=true; 
      }else if(tmp[i][0]=='m' && tmp[i][1]=='a') //and the texture 
      { 
       sscanf(tmp[i].c_str(),"map_Kd %s",filename); 
       texture=loadTexture(filename); //read the filename, and use the loadTexture function to load it, and get the id. 
       ismat=true; 
      } 
     } 
     if(ismat) //there is no newmat after the last newmat, so we have to put the last material 'manually' 
     { 
      if(strcmp(filename,"\0")!=0) 
      { 
       materials.push_back(new material(name,alpha,ns,ni,dif,amb,spec,illum,texture)); 
      }else{ 
        materials.push_back(new material(name,alpha,ns,ni,dif,amb,spec,illum,-1)); 
      } 
     } 
    }else if((*coord[i])[0]=='v' && (*coord[i])[1]=='t') //back to the obj file, texture coorinate 
    { 
     float u,v; 
     sscanf(coord[i]->c_str(),"vt %f %f",&u,&v); //read the uv coordinate 
     texturecoordinate.push_back(new texcoord(u,1-v)); 
     istexture=true; 
    } 
} 
    if(materials.size()==0) //if some reason the material file doesn't contain any material, we don't have material 
     ismaterial=false; 
    else //else we have 
     ismaterial=true; 
    std::cout << vertex.size() << " " << normals.size() << " " << faces.size() << " " << materials.size() << std::endl;  //test purposes 
    //draw 
    int num; 
    num=glGenLists(1); 
    glNewList(num,GL_COMPILE); 
    int last=-1; //the last material (default -1, which doesn't exist, so we use the first material) 
    for(int i=0;i<faces.size();i++) //go throught all faces 
    { 
     if(last!=faces[i]->mat && ismaterial) 
     { 
      //set all of the material property 
      float diffuse[]={materials[faces[i]->mat]->dif[0],materials[faces[i]->mat]->dif[1],materials[faces[i]->mat]->dif[2],1.0}; 
      float ambient[]={materials[faces[i]->mat]->amb[0],materials[faces[i]->mat]->amb[1],materials[faces[i]->mat]->amb[2],1.0}; 
      float specular[]={materials[faces[i]->mat]->spec[0],materials[faces[i]->mat]->spec[1],materials[faces[i]->mat]->spec[2],1.0}; 
      glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse); 
      glMaterialfv(GL_FRONT,GL_AMBIENT,ambient); 
      glMaterialfv(GL_FRONT,GL_SPECULAR,specular); 
      glMaterialf(GL_FRONT,GL_SHININESS,materials[faces[i]->mat]->ns); 
      last=faces[i]->mat; //set the current to last 
      if(materials[faces[i]->mat]->texture==-1) 
       glDisable(GL_TEXTURE_2D); 
      else{ 
       glEnable(GL_TEXTURE_2D); 
       glBindTexture(GL_TEXTURE_2D,materials[faces[i]->mat]->texture); //and use it 
      } 
     } 
     if(faces[i]->four) //if quad 
     { 
      glBegin(GL_QUADS); 
       if(isnormals) //if there are normals 
        glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z); //use them 

       if(istexture && materials[faces[i]->mat]->texture!=-1) //if there are textures 
        glTexCoord2f(texturecoordinate[faces[i]->texcoord[0]-1]->u,texturecoordinate[faces[i]->texcoord[0]-1]->v); //set the texture coorinate 

       glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z); 

       if(istexture && materials[faces[i]->mat]->texture!=-1) 
        glTexCoord2f(texturecoordinate[faces[i]->texcoord[1]-1]->u,texturecoordinate[faces[i]->texcoord[1]-1]->v); 

       glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z); 

       if(istexture && materials[faces[i]->mat]->texture!=-1) 
        glTexCoord2f(texturecoordinate[faces[i]->texcoord[2]-1]->u,texturecoordinate[faces[i]->texcoord[2]-1]->v); 

       glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z); 

       if(istexture && materials[faces[i]->mat]->texture!=-1) 
        glTexCoord2f(texturecoordinate[faces[i]->texcoord[3]-1]->u,texturecoordinate[faces[i]->texcoord[3]-1]->v); 

       glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z); 
      glEnd(); 
     }else{ 
      glBegin(GL_TRIANGLES); 
       if(isnormals) //if there are normals 
        glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z); 

       if(istexture && materials[faces[i]->mat]->texture!=-1) 
        glTexCoord2f(texturecoordinate[faces[i]->texcoord[0]-1]->u,texturecoordinate[faces[i]->texcoord[0]-1]->v); 


       glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z); 

       if(istexture && materials[faces[i]->mat]->texture!=-1) 
        glTexCoord2f(texturecoordinate[faces[i]->texcoord[1]-1]->u,texturecoordinate[faces[i]->texcoord[1]-1]->v); 

       glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z); 


       if(istexture && materials[faces[i]->mat]->texture!=-1) 
        glTexCoord2f(texturecoordinate[faces[i]->texcoord[2]-1]->u,texturecoordinate[faces[i]->texcoord[2]-1]->v); 

       glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z); 
      glEnd(); 
     } 
    } 
    glEndList(); 
    clean(); 
    lists.push_back(num); 
    return num; 
} 

void objloader::clean() 
{ 
    //delete all the dynamically allocated memory 
    for(int i=0;i<coord.size();i++) 
     delete coord[i]; 
    for(int i=0;i<faces.size();i++) 
     delete faces[i]; 
    for(int i=0;i<normals.size();i++) 
     delete normals[i]; 
    for(int i=0;i<vertex.size();i++) 
     delete vertex[i]; 
    for(int i=0;i<materials.size();i++) 
     delete materials[i]; 
    for(int i=0;i<texturecoordinate.size();i++) 
     delete texturecoordinate[i]; 
    //and all elements from the vector 
    coord.clear(); 
    faces.clear(); 
    normals.clear(); 
    vertex.clear(); 
    materials.clear(); 
    texturecoordinate.clear(); 
} 

objloader::~objloader() 
{ 
    //delete lists and textures 
    for(std::vector<unsigned int>::const_iterator it=texture.begin();it!=texture.end();it++) 
    { 
     glDeleteTextures(1,&(*it)); 
    } 
    for(std::vector<unsigned int>::const_iterator it=lists.begin();it!=lists.end();it++) 
    { 
     glDeleteLists(*it,1); 
    } 
    glDisable(GL_TEXTURE_2D); 
    glDisable(GL_BLEND); 
} 


unsigned int objloader::loadTexture(const char* filename) 
{ 
    unsigned int num; 
    int mode; 
    glGenTextures(1,&num); 
    SDL_Surface* img=IMG_Load(filename); 
    if(img==NULL) 
    { 
     std::cout << "Image error" << std::endl; 
    } 
    if (img->format->BytesPerPixel == 3) { 

       mode = GL_RGB; 

     } else if (img->format->BytesPerPixel == 4) { 

       mode = GL_RGBA; 

     } else { 

       SDL_FreeSurface(img); 
       return 0; 

     } 
    glBindTexture(GL_TEXTURE_2D,num); 
    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glTexImage2D(GL_TEXTURE_2D,0,mode,img->w,img->h,0,mode,GL_UNSIGNED_BYTE,img->pixels); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    return num; 
    texture.push_back(num); 
} 

objloader::objloader() 
{ 
    ismaterial=false; 
    isnormals=false; 
    istexture=false; 
} 

test.obj

# Blender v2.70 (sub 0) OBJ File: '' 
# www.blender.org 
mtllib test.mtl 
o Cube 
v 1.000000 -1.000000 -1.000000 
v 1.000000 -1.000000 1.000000 
v -1.000000 -1.000000 1.000000 
v -1.000000 -1.000000 -1.000000 
v 1.000000 1.000000 -0.999999 
v 0.999999 1.000000 1.000001 
v -1.000000 1.000000 1.000000 
v -1.000000 1.000000 -1.000000 
vn 0.000000 -1.000000 0.000000 
vn 0.000000 1.000000 0.000000 
vn 1.000000 0.000000 0.000000 
vn -0.000000 -0.000000 1.000000 
vn -1.000000 -0.000000 -0.000000 
vn 0.000000 0.000000 -1.000000 
usemtl Material 
s off 
f 1//1 2//1 3//1 4//1 
f 5//2 8//2 7//2 6//2 
f 1//3 5//3 6//3 2//3 
f 2//4 6//4 7//4 3//4 
f 3//5 7//5 8//5 4//5 
f 5//6 1//6 4//6 8//6 

test.mtl

# Blender MTL File: 'None' 
# Material Count: 1 

newmtl Material 
Ns 96.078431 
Ka 0.000000 0.000000 0.000000 
Kd 0.640000 0.640000 0.640000 
Ks 0.500000 0.500000 0.500000 
Ni 1.000000 
d 1.000000 
illum 2 
map_Kd a.png 

回答

0

紋理座標中缺少OBJ文件。

istexture最有可能的是而不是在加載後爲此obj文件設置。那裏沒有紋理(vt)座標。並且在(f)定義中也沒有設置。

f v1/t1/n1 v2/t2/n2 v3/t3/n3其中在該文件中TX是不存在這樣的座標進行紋理未設置每每個頂點和四元的顏色是(0,0)紋理座標的顏色。