2013-08-21 2 views
0

OpenGL 앱에서 .obj 파일을로드하는 데 문제가 있습니다. 다른 섹션으로 만들어진 차 모델입니다 (유리, 바퀴 등 다른 재료를 사용합니다).멀티 텍스쳐 .obj 파일 (C++/opengl)로드하기

저는 WavefrontSection 클래스가 있습니다.이 클래스에는 고유 한 정점, 법선, 재료 및 텍사스 좌표.

class WavefrontSection 
{ 
    public: 
     WavefrontSection(string mat_name = ""){ material = NULL; } 
     void ConstructVAO(); 
     void Render(); 

    std::vector<float> vert; 
    std::vector<float> tex_coord; 
    std::vector<float> norm; 

     /* these are the indexes used to build the VAO */ 
     std::vector<int> vert_index; 
    std::vector<int> norm_index; 
    std::vector<int> tex_index; 

     /* This is the material, containing ambient, diffuse and specular materials, 
      and texture */ 
    Material *material; 

     /* This is the VAO */ 
     VAO vao; 
}; 

재료, 법선 및 정점 여기에 잘로드 화면입니다 : 내가로드 텍스처 (섹션 당 하나)를 적용 할 때

http://postimg.org/image/ubkm0nrjj/

문제는 온다. 다음은 로더 코드입니다 :

int WavefrontModel::load(string file,string _mtlFile) 
{ 
    gl3WriteOnStream("Loading model "+file,log_stream); 

    ifstream model(file.c_str()); 

    if(!model) 
    { 
     cerr<<"Cannot open file "<<file<<endl; 
     gl3WriteOnStream("Cannot open file "+file,error_stream); 
     return -1; 
    } 

    char buf[256]; 
    char *curr_tok = NULL; 

    /* These vectors stores all the vertices,normals and texture coord. 
     Later each section will just copy in their arrays their vertices, normals 
     and coords. To get the right order, i store the .obj face index information 
     in WavefrontSections::*_index vector */ 

    std::vector<float> vert; 
    std::vector<float> norm; 
    std::vector<float> tex; 

    mtlHeader.Open(_mtlFile); /* I open the material file, to parse all the materials */ 

    int curr_section = 0; 

    while(!model.eof()) 
    { 
     model.getline(buf,256); 

     curr_tok = strtok(buf,WHITESPACE); 

     if(!curr_tok || curr_tok[0] == '#') 
     { 
      continue; 
     } 
     else if(strcmp(curr_tok,"v") == 0) 
     { 
      vert.push_back(atof(strtok(NULL,WHITESPACE))); 
      vert.push_back(atof(strtok(NULL,WHITESPACE))); 
      vert.push_back(atof(strtok(NULL,WHITESPACE))); 
     } 
    else if(strcmp(curr_tok,"vn") == 0) 
    { 
     norm.push_back(atof(strtok(NULL,WHITESPACE))); 
     norm.push_back(atof(strtok(NULL,WHITESPACE))); 
     norm.push_back(atof(strtok(NULL,WHITESPACE))); 
    } 
    else if(strcmp(curr_tok,"vt") == 0) 
    { 
     tex.push_back(atof(strtok(NULL,WHITESPACE))); 
     tex.push_back(atof(strtok(NULL,WHITESPACE))); 
    } 
    else if(strcmp(curr_tok,"usemtl") == 0) 
    { 
     char *mtl = strtok(NULL,WHITESPACE); 
     bool already_pres = false; 

      /*I check if a sections already uses that material, 
       if so, i add the new indexes to that section, 
       otherwise I just create a new section */ 

     for(int i = 0;i < sections.size();i++) 
     { 
      if(strcmp(mtl,sections[i]->material->name.c_str()) == 0) 
      { 
       curr_section = i; 
       already_pres = true; 
       break; 
      } 
     } 


     if(!already_pres) 
     { 
      curr_section = sections.size(); 
      sections.push_back(new WavefrontSection(mtl)); 
      sections[curr_section]->material = mtlHeader.parseMaterial(mtl); 
     } 
    } 
    else if(strcmp(curr_tok,"f") == 0) 
    { 
     char *tmp_tok = NULL; 
     char *temp = NULL; 

      /* Here I parse model's faces. I added a '-1' to the indexes, because in the .obj 
      file they start from 1, but in my vectors they start from 0 */ 

     while((tmp_tok = strtok(NULL,WHITESPACE))) 
     { 
      sections[curr_section]->vert_index.push_back(atoi(tmp_tok)-1); 

      if((temp = strstr(tmp_tok,"//"))) ///no texture 
      { 
       temp++; 
       sections[curr_section]->norm_index.push_back(atoi(++temp)-1); 
      } 
      else if((temp = strstr(tmp_tok,"/"))) ///with texture 
      { 
      sections[curr_section]->tex_index.push_back(atoi(++temp)-1); 

      if((temp = strstr(temp,"/"))) 
      { 
       sections[curr_section]->norm_index.push_back(atoi(++temp)-1); 
      } 
      } 
     } 
    } 

    } 


    cout<<"This model has got "<<sections.size()<<" sections"<<endl; 

    /* Now I add vertices, normals and texture coords to each section, 
     using the indexes that I previously stored in each section */ 

    for(int i = 0;i < sections.size();i++) 
    { 
     for(int j = 0;j < sections[i]->vert_index.size();j++) 
     { 
     sections[i]->vert.push_back(vert[sections[i]->vert_index[j]*3]); //x component 
     sections[i]->vert.push_back(vert[sections[i]->vert_index[j]*3+1]); //y component 
     sections[i]->vert.push_back(vert[sections[i]->vert_index[j]*3+2]); //z component 
     } 

     for(int j = 0;j < sections[i]->tex_index.size();j++) 
     { 
     sections[i]->tex_coord.push_back(tex[sections[i]->tex_index[j]*2]); //u component 
     sections[i]->tex_coord.push_back(tex[sections[i]->tex_index[j]*2+1]); //v component 
     } 

     for(int j = 0;j < sections[i]->norm_index.size();j++) 
     { 
     sections[i]->norm.push_back(norm[sections[i]->norm_index[j]*3]);  //x component 
     sections[i]->norm.push_back(norm[sections[i]->norm_index[j]*3+1]); //y component 
     sections[i]->norm.push_back(norm[sections[i]->norm_index[j]*3+2]); //z component 
     } 

     sections[i]->ConstructVAO(); //I construct the VAO for each section 

     printf("Section %i has %i verts, %i normals, %i tex coords\n",i,sections[i]->vert.size()/3,sections[i]->norm.size()/3,sections[i]->tex_coord.size()/2); 
    } 


} 

그리고 여기에 전체 모델 렌더링하는 코드이다 :

void WavefrontModel::render(GLenum render_mode,bool normals,bool textured) 
{ 
    glPolygonMode(GL_FRONT_AND_BACK,render_mode); 

    glModelMatrix.LoadIdentity(); 
    glModelMatrix.translate(pos); 
    glModelMatrix.rotate(angle,rot.x,rot.y,rot.z); 
    glModelMatrix.scale(scaleVec); 

    shader->sendUniformMatrix4fv(shader->getUniformLocation("projMat"),1,GL_FALSE,GLXSDLRenderPipeline::glProjectionMatrix); 
    shader->sendUniformMatrix4fv(shader->getUniformLocation("viewMat"),1,GL_FALSE,GLXSDLRenderPipeline::glViewMatrix); 
    shader->sendUniformMatrix4fv(shader->getUniformLocation("modMat"),1,GL_FALSE,glModelMatrix); 
    shader->sendUniform1i(shader->getUniformLocation("texture"),0); 


    for(int i = 0;i < sections.size();i++) 
    { 
     if(sections[i]->material) 
     { 
     sections[i]->material->sendMaterialUniforms(shader); 
     sections[i]->material->texture.bind_unit(0); 
     } 
     shader->bind(); 
     sections[i]->Render(); 
     shader->unbind(); 

     if(sections[i]->material) 
     sections[i]->material->texture.unbind(); 


    } 
} 

각 WavefrontSection 인스턴스() 렌더링 호출합니다. (믹서기 렌더링 :

void WavefrontSection::Render() 
{ 
    vao.DrawArrays(GL_TRIANGLES,0,vert.size()); 
} 

이 내가 무엇을 얻을

(ConstructVAO를 호출, 내가 옛날 법선과 질감이 너무 좌표 버퍼를 생성) 다음과 같이 WavefrontSection이 :) (렌더링 방법은 구현 어떻게해야, 다른 사람은)는

blender renders and engine renders

조언 내 엔진에서 어떻게 렌더링되어 있습니까?

답변

0

해결했습니다. 문제는 내가

else if(strcmp(curr_tok,"vt") == 0) 
{ 
     tex.push_back(atof(strtok(NULL,WHITESPACE))); 
     tex.push_back(1-atof(strtok(NULL,WHITESPACE))); 
} 
로 대체 여기

else if(strcmp(curr_tok,"vt") == 0) 
{ 
     tex.push_back(atof(strtok(NULL,WHITESPACE))); 
     tex.push_back(atof(strtok(NULL,WHITESPACE))); 
} 

했다