我目前正在遵循基本的OpenGL教程,目标是从.OBJ文件中读取数据,然后渲染模型。本教程位于此处-http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/。
当前,我的程序打开指定的OBJ文件,并使用此处教程中讨论的解析引擎-http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/#Reading_the_file对其进行解析。
我尝试渲染的对象是位于同一教程页面URL上的多维数据集。
我相信我的问题出在我的display(void)函数上。在main()中执行glutDisplayFunc(display);
之后,将显示一个黑色窗口,而不是渲染的模型。
这是我当前的display(void)函数:
void display(void)
{
GLuint vbo;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3) * 3, &vertices[0], GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLES, vertices.size() * sizeof(glm::vec3) * 3, GL_UNSIGNED_INT, &vertices[0]);
// check OpenGL error
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR)
{
printf("OpenGL error: %u", err);
}
glEnd();
glutSwapBuffers();
}
这是解析器读取的数据,也许是解析问题:
Success: GLEW_OKSuccess: Opened OBJ File cube.objRead in Vertices: 1.000000, -1.000000, -1.000000Read in Vertices: 1.000000, -1.000000, 1.000000Read in Vertices: -1.000000, -1.000000, 1.000000Read in Vertices: -1.000000, -1.000000, -1.000000Read in Vertices: 1.000000, 1.000000, -1.000000Read in Vertices: 0.999999, 1.000000, 1.000001Read in Vertices: -1.000000, 1.000000, 1.000000Read in Vertices: -1.000000, 1.000000, -1.000000Read in texture coordinate: 0.748573, 0.750412Read in texture coordinate: 0.749279, 0.501284Read in texture coordinate: 0.999110, 0.501077Read in texture coordinate: 0.999455, 0.750380Read in texture coordinate: 0.250471, 0.500702Read in texture coordinate: 0.249682, 0.749677Read in texture coordinate: 0.001085, 0.750380Read in texture coordinate: 0.001517, 0.499994Read in texture coordinate: 0.499422, 0.500239Read in texture coordinate: 0.500149, 0.750166Read in texture coordinate: 0.748355, 0.998230Read in texture coordinate: 0.500193, 0.998728Read in texture coordinate: 0.498993, 0.250415Read in texture coordinate: 0.748953, 0.250920Read in Normals: 0.000000, 0.000000, -1.000000Read in Normals: -1.000000, -0.000000, -0.000000Read in Normals: -0.000000, -0.000000, 1.000000Read in Normals: -0.000001, 0.000000, 1.000000Read in Normals: 1.000000, -0.000000, 0.000000Read in Normals: 1.000000, 0.000000, 0.000001Read in Normals: 0.000000, 1.000000, -0.000000Read in Normals: -0.000000, -1.000000, 0.000000Reached end of fileOut Vertices Size: 234
glGetError()一次都没有为我产生错误,因此无法以这种方式调试问题。
有什么建议/意见吗?
最佳答案
这些命令(包括glGetError (...)
)在glBegin (...)
和glEnd (...)
之间均无效。如果将呼叫移到glGetError
之后在glEnd
后面,则应该获得GL_INVALID_OPERATION
一次或多次。
删除glBegin
和glEnd
,它们在此代码中没有任何作用,只会使其余命令无效。
名称
glBegin
—界定一个图元或一组相似图元的顶点
C规格
void glBegin(GLenum模式);
描述
[...]
glBegin和glEnd之间只能使用GL命令的子集。命令是glVertex,glColor,glSecondaryColor,glIndex,glNormal,glFogCoord,glTexCoord,glMultiTexCoord,glVertexAttrib,glEvalCoord,glEvalPoint,glArrayElement,glMaterial和glEdgeFlag。同样,可以使用glCallList或glCallLists执行仅包含前面命令的显示列表。如果在glBegin和glEnd之间执行了其他任何GL命令,则会设置错误标志,并且该命令将被忽略。
关于其余的代码,您不应该在每一帧都生成一个新的缓冲区。在初始化期间执行一次,添加一个顶点指针,然后将绘制命令更改为glDrawArrays (...)
:
glDrawArrays (GL_TRIANGLES, 0, vertices.size());
glDrawElements (...)
仅在有索引缓冲区的情况下使用。除非我完全误解了数据的结构,否则vertices
是您的顶点数据,并且不存储索引列表。更新1:
阅读了您的问题所依据的教程之后,在加载.obj模型时需要进行以下更改:
GLuint buffers [3];
glGenBuffers(3, buffers);
// Position Buffer = 0
glBindBuffer(GL_ARRAY_BUFFER, buffers [0]);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glVertexPointer (3, GL_FLOAT, 0, NULL);
// ^^^^^^^^^^^^ Sources data from VBO bound to `GL_ARRAY_BUFFER`, so a NULL pointer is OK
glEnableClientState (GL_VERTEX_ARRAY); // Use this array for drawing
// Tex Coords = 1
glBindBuffer (GL_ARRAY_BUFFER, buffers [1]);
glBufferData (GL_ARRAY_BUFFER, uvs.size () * sizeof (glm::vec2), &uvs [0], GL_STATIC_DRAW);
glTexCoordPointer (2, GL_FLOAT, 0, NULL);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
// Normals = 2
glBindBuffer (GL_ARRAY_BUFFER, buffers [2]);
glBufferData (GL_ARRAY_BUFFER, normals.size () * sizeof (glm::vec3), &normals [0], GL_STATIC_DRAW);
glNormalPointer (GL_FLOAT, 0, NULL);
glEnableClientState (GL_NORMAL_ARRAY);
请记住,一旦学会使用着色器,就应该停止使用诸如
glVertexPointer (...)
和glEnableClientState (...)
之类的功能。您将期望使用glVertexAttribPointer (...)
和glEnableVertexAttribArray (...)
代替。我以这种方式编写了代码,因此您可以立即启动并运行它,但这不是现代的GL软件编写方式。
关于c++ - C++ OpenGL从文件渲染简单OBJ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29109857/