我有一个带有顶点(N * 3)和面(N * 3)的Eigen :: MatrixXf作为变量mvTemp2和mF。
如果我定期绘制顶点,它们会根据以下代码给出正确的输出:
using (ClassContext context = new ClassContext()){
((IObjectContextAdapter)context).ObjectContext.Connection.Open();
//SOMETHING TO DO......
((IObjectContextAdapter)context).ObjectContext.Connection.Close();
}
但是,如果我使用顶点缓冲区,我会得到垃圾输出:
while(1){
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_LIGHTING);
glShadeModel( GL_SMOOTH );
glEnable( GL_TEXTURE_2D );
glViewport( 0, 0, (float)renderWidth/1, (float)renderHeight/1. );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60, (float)renderWidth/(float)renderHeight, 0.1, 10000. );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glPushMatrix();
glTranslatef(0,-0.5,-0.5);
// glBindVertexArray(vao);
// glDrawElements(GL_TRIANGLES, indexdata.size(), GL_UNSIGNED_BYTE, (void*)0);
for(int i=0; i<smpl.mF.rows(); i++){
glBegin(GL_POLYGON);
for(int j=0; j<smpl.mF.cols(); j++){
indexdata.push_back(smpl.mF(i,j)+1);
}
glVertex3fv((const GLfloat*)&vertexdata[smpl.mF(i,0)].position);
glVertex3fv((const GLfloat*)&vertexdata[smpl.mF(i,1)].position);
glVertex3fv((const GLfloat*)&vertexdata[smpl.mF(i,2)].position);
glEnd();
}
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
glutMainLoopEvent();
}
我无法理解我做错了什么。我可以使用常规的旧glVertex正常绘制面部并且它可以工作,但速度太慢。所以我想使用顶点缓冲区,但代码总是提供垃圾输出。为什么会这样? 修改
我已经解决了这个问题,但是我的法线现在已经错了。如果我使用Vertex和Normal调用正常绘制它,它可以工作:
// Iterate v
for(int i=0; i<smpl.mVTemp2.rows(); i++){
Vertex v;
for(int j=0; j<smpl.mVTemp2.cols(); j++){
v.position[j] = smpl.mVTemp2(i,j);
}
vertexdata.push_back(v);
}
std::vector<GLubyte> indexdata;
// Iterate f
for(int i=0; i<smpl.mF.rows(); i++){
for(int j=0; j<smpl.mF.cols(); j++){
indexdata.push_back(smpl.mF(i,j));
}
}
// Create and bind a VAO
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create and bind a BO for vertex data
GLuint vbuffer;
glGenBuffers(1, &vbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);
// copy data into the buffer object
glBufferData(GL_ARRAY_BUFFER, vertexdata.size() * sizeof(Vertex), &vertexdata[0], GL_STATIC_DRAW);
// set up vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position)); // vertices
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, normal)); // normals
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texcoord)); // normals
// Create and bind a BO for index data
GLuint ibuffer;
glGenBuffers(1, &ibuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);
// copy data into the buffer object
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexdata.size() * sizeof(GLubyte), &indexdata[0], GL_STATIC_DRAW);
glBindVertexArray(0);
while(1){
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_LIGHTING);
glShadeModel( GL_SMOOTH );
glEnable( GL_TEXTURE_2D );
glViewport( 0, 0, (float)renderWidth/1, (float)renderHeight/1. );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 60, (float)renderWidth/(float)renderHeight, 0.1, 10000. );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glPushMatrix();
glTranslatef(0,-0.5,-0.5);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, indexdata.size(), GL_UNSIGNED_BYTE, (void*)0);
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
glutMainLoopEvent();
}
但是,如果我将它与顶点缓冲区一起使用,则不会:
std::vector<Vertex> vertexdata;
for(int i=0; i<object.vertices.size(); i++){
Vertex v;
v.position[0] = object.vertices.at(i).coords[0];
v.position[1] = object.vertices.at(i).coords[1];
v.position[2] = object.vertices.at(i).coords[2];
v.normal[0] = object.computedNormals.at(i).coords[0];
v.normal[1] = object.computedNormals.at(i).coords[1];
v.normal[2] = object.computedNormals.at(i).coords[2];
vertexdata.push_back(v);
}
std::vector<GLushort> indexdata;
for(int i=0; i<object.faces.size(); i++){
OBJFace& face = object.faces.at(i);
indexdata.push_back(face.items[0].vertexIndex);
indexdata.push_back(face.items[1].vertexIndex);
indexdata.push_back(face.items[2].vertexIndex);
glBegin(GL_POLYGON);
glNormal3fv(vertexdata[face.items[0].vertexIndex].normal);
glVertex3fv(vertexdata[face.items[0].vertexIndex].position);
glNormal3fv(vertexdata[face.items[1].vertexIndex].normal);
glVertex3fv(vertexdata[face.items[1].vertexIndex].position);
glNormal3fv(vertexdata[face.items[2].vertexIndex].normal);
glVertex3fv(vertexdata[face.items[2].vertexIndex].position);
glEnd();
}
答案 0 :(得分:1)
您没有使用着色器进行顶点处理。因此,不能使用通用顶点属性(由VertexAttrib
函数提供)。因此,您可以切换到使用着色器,或使用固定功能属性:
// set up vertex attributes
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, position)); // vertices
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, normal)); // normals
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, texcoord)); // normals
答案 1 :(得分:1)
除了Nicol Bolas的回答:
看起来索引的数量太多,无法用字节(GLubyte
)对它们进行编码。一个字节可以存储[0,255]范围内的数据,因此一个字节中只能编码256个索引。请改用GLushort
。 GLushort
的范围是[0,65535]:
std::vector<GLushort> indexdata;
....
GLuint ibuffer;
glGenBuffers(1, &ibuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexdata.size()*sizeof(GLushort),
indexdata.data(), GL_STATIC_DRAW);
....
glDrawElements(GL_TRIANGLES, indexdata.size(), GL_UNSIGNED_SHORT, (void*)0);