2013-08-08 5 views
-1

Я пытаюсь написать очень простой .obj-загрузчик модели в C++, но в обоих моих методах модель не отображается правильно, и я также хотел бы знать, какой из 2 методы быстрее/лучше и почему. это мой первый метод:OpenGL: настройка индексов/вершин

//vertices&indices are private members of the class "Model" 
    //same with size and indexCount 

void Model::loadModel(std::string source) 
{ 
    using namespace std; 

    string name = source.substr(0,source.find('.')); 
    cout<<"===LOADING: "<<name<<"==="<<endl; 

    ifstream file; 
    file.open(source); 
    string line,v0="",v1="",v2=""; 
    string v3="",v4="",v5=""; 
    int indexCount = 0; 
    while(file.good()) 
    { 
     getline(file,line); 
     if(line[0] =='v') size++; 
     if(line[0] =='f') indexCount++; 
    } 
    file.close(); 
    size *= 3; 
    vertices = new float[size]; 
    indexSize = indexCount*3; 
    indices = new short[indexSize]; 
    int count = 0; 
    int indexCountForFilling =0; 
    file.open(source); 
    while(file.good()) 
    { 
     getline(file,line); 
     if(line[0] == 'v') 
     { 
      line = line.substr(2,line.length()); 
      int oldindex =0; 

      v0 = line.substr(0,line.find(" ")); 
      v1 = line.substr(line.find(" "),line.rfind(" ",line.find(" "))); 
      v2 = line.substr(line.rfind(" ",line.find(" ")),line.length()); 
      v2 = v2.substr(line.find(" ")+2,v2.length()); 

      //1 
      float temp = atof(v0.c_str()); 
      vertices[count] = temp; 
      count++; 
      //2 
      temp = atof(v1.c_str()); 
      vertices[count] = temp; 
      count++; 
      //3 
      temp = atof(v2.c_str()); 
      vertices[count] = temp; 
      count++; 
     } 
     else if(line[0] == 'f') 
     { 
      line = line.substr(2,line.length()); 

      int firstIndex = line.find(" "); 
      v3 = line.substr(0,firstIndex); 
      line = line.substr(firstIndex+1,line.length()); //+1 to skip space 

      int secondIndex = line.find(" "); 
      v4 = line.substr(0,secondIndex); 
      line = line.substr(secondIndex,line.length()); 

      if(secondIndex+1>=line.length()) 
       v5 = line.substr(0,line.length()); 
      else 
       v5 = line.substr(1,line.length()); //zelfde 
      //1 
      short temp = atof(v3.c_str()); 
      indices[indexCountForFilling] = temp; 
      indexCountForFilling++; 
      //2 
      temp = atof(v4.c_str()); 
      indices[indexCountForFilling] = temp; 
      indexCountForFilling++; 
      //3 
      temp = atof(v5.c_str()); 
      indices[indexCountForFilling] = temp; 
      indexCountForFilling++; 
     } 
    } 
    cout<<"Amount of vertices: "<<size<<endl; 
    cout<<"Amount of indexes: "<<indexCountForFilling<<endl; 
    cout<<"===ENDED LOADING: "<<name<<"==="<<endl; 
    file.close(); 
} 

Это второй способ с использованием stringstreams:

void Model::loadModel2(std::string source) 
{ 
    using namespace std; 
    string name = source.substr(0,source.find(".")); 
    cout<<"+++LOADING::"<<name<<"+++"<<endl; 

    ifstream file; 
    file.open(source); 
    string line; 
    while(file.good()) 
    { 
     getline(file,line); 
     if(line[0]=='v') size++; 
     if(line[0]=='f') indexSize++; 
    } 
    size *= 3; 
    vertices = new GLfloat[size]; 
    indexSize *= 3; 
    indices = new GLshort[indexSize]; 
    cout<<"\tSize: "<<size<<endl; 
    cout<<"\tIndexSize:"<<indexSize<<endl; 
    file.close(); 
    file.open(source); 
    int count = 0; 
    int index = 0; 
    while(file.good()) 
    { 
     getline(file,line); 
     istringstream in(line); 
     string type; 
     in>>type; 
     if(type=="v") 
     { 
      float x,y,z; 
      in >> x >> y >> z; 
      vertices[count++] = x; 
      vertices[count++] = y; 
      vertices[count++] = z; 
     } 
     else if(type == "f") 
     { 
      float x,y,z; 
      in >> x >> y >> z; 
      indices[index++] = x; 
      indices[index++] = y; 
      indices[index++] = z; 
     } 
    } 
    file.close(); 

    cout<<"+++ENDED LOADING:"<<name<<"+++"<<endl; 
} 

Это код, где оба инициализируются:

glGenBuffers(1,&vbo); 
    glBindBuffer(GL_ARRAY_BUFFER,vbo); 
    GLfloat model_test[834]; //834 
    memset(model_test,0.0f,sizeof(model_test)); 
    for(unsigned int i=0;i<834;i++) model_test[i] = model.getIndex(i); 
    glBufferData(GL_ARRAY_BUFFER,sizeof(model_test),&model_test,GL_STATIC_DRAW); 

    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,BUFFER_OFFSET(0)); 
    glEnableVertexAttribArray(0); 

    GLuint ibo; 
    glGenBuffers(1,&ibo); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo); 
    GLshort indices[1656];//1656 
    memset(indices,0,sizeof(indices)); 
    for(int i=0;i<1656;i++) indices[i] = model.getVertexIndex(i); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),&indices,GL_STATIC_DRAW); 

И, наконец, это код где это делается:

glBindVertexArray(vao); 
    if(rasterize)glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
    else glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 
    glDrawElements(GL_TRIANGLES,model.getIndexSize(),GL_UNSIGNED_SHORT,0); 

Это результат я должен получить:

http://imgur.com/OGGDLFq

Это результат я получаю:

http://imgur.com/U9ZTGsG

Как вы можете видеть это не загружает почти полностью до последних нескольких треугольников

Итак, в заключение мои 2 вопроса:

- Which of the 2 methods is the best way to load from a txt file? 

- Am I doing something wrong with the rendering? 

EDIT: Я предполагаю, что я использую неправильные индексы, однако я загрузил более простой файл с меньшим количеством вершин/индексов и сравнил вывод каждого числа, и, похоже, я правильно скопировал данные в свои заявление. Поэтому я предполагаю, что я сделал что-то не так в моем коде инициализации для openGL, может ли кто-нибудь найти ошибку? Все компилируется нормально ...

ответ

1

Не делайте, например.

while (file.good()) { ... } 

или аналогичный, он не будет делать то, что вы думаете.

Вместо делать

while (std::getline(...)) { ... } 

Это потому, что флаги (eof/bad/др.) Не будет установлен до после сбоя операции ввода. Это означает, что вы будете зацикливаться, потому что все будет выглядеть хорошо, но тогда std::getline терпит неудачу, потому что он находится в конце файла, но вы по-прежнему пытаетесь проанализировать данные, которые не были прочитаны.

+0

Я изменил его, но он ничего не изменил. –

+0

@AntonD Попробуйте загрузить гораздо более простую модель, а затем последовательно введите код загрузки в отладчик. Затем вы можете проверить, что код загрузки работает так, как должен или нет. Если это так, то это еще одна проблема. –

+0

Это была одна из первых вещей, которые я пробовал, я распечатал каждый поплавок и сравнил каждую из них с моим файлом. Все они точно совпадали (как индексы, так и вершины). Вы думаете, что что-то не так с моим кодом openGL? –

Смежные вопросы