2015-12-15 1 views
0

J'ai un code pour obj et les fichiers .mtl de chargement, il y a eu erreur d'assertion si je mets certains affirment les fonctions et l'erreur est à cette partie du code:échec Assertion chargement d'un fichier

assert(!mtlin.is_open(),"2"); 
      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; 
      } 

I 'ai essayé avec plusieurs fichiers .mtl, mais tous donnent une erreur d'assertion! Voici le code complet juste au cas où:

#include <stdlib.h> 
#include "glut.h" 
#include <GL/gl.h> 
#include <GL/glu.h> 
#include "objloader.h" 
#include <assert.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 
      { 
       assert(strcmp(materials[i]->name.c_str(),tmp)==0,"1"); 
        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 
      assert(!mtlin.is_open(),"2"); 
      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));  //I push back 1-v instead of normal v, because obj file use the upper left corner as 0,0 coorinate 
      //but OpenGL use bottom left corner as 0,0, so I convert it 
      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);  //I generate a unique identifier for the list 
    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) //if we have a meterial AND the last material is not the same 
      { 
        //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)  //if we don't have texture, disable it, else enable it 
          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); 
    } 
    } 

    //load the filename textures (only BMP, R5G6B5 format) 
    unsigned int objloader::loadTexture(const char* filename) 
    { 
    //nothing new in here 
    unsigned int num; 
    glGenTextures(1,&num); 
    SDL_Surface* img=SDL_LoadBMP(filename); 
    glBindTexture(GL_TEXTURE_2D,num); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,img->w,img->h,0,GL_RGB,GL_UNSIGNED_SHORT,img->pixels); 
    glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL_MODULATE);  //maybe just this 
    SDL_FreeSurface(img); 
    texture.push_back(num); 
    return num; 
    } 

    objloader::objloader() 
     { 
    //at default we set all booleans to false, so we don't use anything 
    ismaterial=false; 
    isnormals=false; 
    istexture=false; 
    } 
+0

'assert (de mtlin.is_open(), "2"!),' Ne jamais échouer (en supposant que vous utilisez le [assert] standard (http: //en.cppreference.com/w/cpp/error/assert) macro). – IInspectable

Répondre

1

La seule macro assert prend un paramètre.

Le compilateur évaluera

!mtlin.is_open(),"2" 

comme une expression. Selon le comma operator, le résultat de l'expression la plus à droite est ce qui est retourné.

Ainsi, votre assert équivaut à:

assert("2")