从obj文件加载时显示单色而不是纹理



当我尝试从mtl文件加载纹理时,显示单一颜色。我试图通过改变照明来修复它,但它不起作用。我是Opengl的新手,使用cpplusplusguy的Opengl教程系列来学习。我正在使用的图像!https://i.stack.imgur.com/wwx44.png我得到的结果!https://i.stack.imgur.com/6gljw.png

我的文件

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: %sn", 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: %sn", SDL_GetError() );
            success = false;
        }
        else
        {
            //Create context
            gContext = SDL_GL_CreateContext( gWindow );
            if( gContext == NULL )
            {
                printf( "OpenGL context could not be created! SDL Error: %sn", SDL_GetError() );
                success = false;
            }
            else
            {
                //Use Vsync
                if( SDL_GL_SetSwapInterval( 1 ) < 0 )
                {
                    printf( "Warning: Unable to set VSync! SDL Error: %sn", 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! %sn", 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! %sn", gluErrorString( error ) );
        success = false;
    }

    //Check for error
    error = glGetError();
    if( error != GL_NO_ERROR )
    {
        printf( "Error initializing OpenGL! %sn", 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 <GLGLU.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,"");  //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)    //if we have a texture
                    {
                        materials.push_back(new material(name,alpha,ns,ni,dif,amb,spec,illum,texture)); //push back
                        strcpy(filename,"");
                    }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)
            {
                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

纹理坐标在OBJ文件中丢失

istexture很可能在加载后为这个obj文件设置而不是。那里没有纹理(vt)坐标。而且在(f)定义中也没有设置。

f v1/t1/n1 v2/t2/n2 v3/t3/n3在文件tX不存在,所以纹理的坐标不是每个顶点设置的,并且四边形的颜色是(0,0)纹理坐标的颜色

最新更新