本文介绍了OpenGL:设置索引/顶点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我一直在尝试在c ++中编写一个非常简单的.obj模型加载器,但在我的两个方法中,模型不能正确显示,我也想知道这两个方法中哪一个更快/更好,为什么。这是我的第一个方法: //顶点和索引是类Model的私有成员 //与size和indexCount相同 void Model :: loadModel(std :: string source) { using namespace std; string name = source.substr(0,source.find('。')); cout<<=== LOADING:<<< name<<===< 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跳过空格 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<<顶点数量:<<<<<< endl; cout<<Index of indexes:<<< indexCountForFilling<< endl; cout<<=== ENDED LOADING:<<< name<<===< file.close(); } 这是使用stringstreams的第二种方法: void Model :: loadModel2(std :: string source) { using namespace std; string name = source.substr(0,source.find(。)); cout<<+++ LOADING ::<<< name<<+++< 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(line); string type; 在>>类型中; if(type ==v) { float x,y,z; 在>> x>> y>> z; vertices [count ++] = x; vertices [count ++] = y; vertices [count ++] = z; } else if(type ==f) { float x,y,z; 在>> x>> y>> z; indices [index ++] = x; indices [index ++] = y; indices [index ++] = z; } } file.close(); cout<<+++ ENDED LOADING:<<< name<<+++< } 这两个都是初始化的代码: 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 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 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 正如你可以看到,它几乎完美加载,直到最后几个三角形 所以总而言之,我的两个问题是: - 这两种方法中的哪一种是从txt文件加载的最好的方法? - 我做渲染的错误吗? 编辑:我的猜测是,我使用错误的索引,简单文件与较少的顶点/索引,并比较每个数字的输出,似乎我已经正确地复制数据到我的应用程序。所以我的猜测是,我在我的初始化代码为openGL的错误,任何人都可以找到错误?一切都编译好... 解决方案不要这样做 while(file.good()){...} while(std :: getline(...)){...} 这是因为之后的标志( eof / 坏 / etc。 / em>输入操作失败。这意味着你会循环,因为一切都会好起来,但是 std :: getline 失败,因为它在文件的结尾,但你仍然试图解析wasn' t阅读。 I have been trying to write a very simple .obj model loader in c++ but in both of my methods the model doesn't get displayed correctly and I would also like to know which of the 2 methods is faster/better and why. this is my first method: //vertices&indices are private members of the class "Model" //same with size and indexCountvoid 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();}This is the second method using 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;}This is the code where both are initialized: 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);And finally this is the code where it is being rendered: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);This is the result i should get:http://imgur.com/OGGDLFqThis is the result i get:http://imgur.com/U9ZTGsGAs you can see it loads almost perfectly until the last few trianglesSo in conclusion my 2 questions are:- Which of the 2 methods is the best way to load from a txt file?- Am I doing something wrong with the rendering?EDIT: My guess is that i'm use the wrong indices, however i've loaded a more simple file with fewer vertices/indices and compared the output of each number and it seems i've correctly copied the data into my application. So my guess is that i did something wrong in my initialization code for openGL, could anyone find the error? Everything compiles fine... 解决方案 Don't do e.g.while (file.good()) { ... }or similar, it will not do what you think it does.Instead dowhile (std::getline(...)) { ... }It's because the flags (eof/bad/etc.) will not be set until after the input operation fails. This means that you will loop because everything will look good, but then std::getline fails because it's at the end of the file but you still try to parse data that wasn't read. 这篇关于OpenGL:设置索引/顶点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-30 05:35