C++OpenGL从文件中绘制简单OBJ
C++ OpenGL Rendering Simple OBJ From File
我目前正在学习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上的多维数据集。
我相信我的问题在于我的显示(无效)功能。在我的main()中执行glutDisplayFunc(display);
之后,我会看到一个黑色窗口,而不是我的渲染模型。
这是我当前的显示(无效)功能:
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_OK
Success: Opened OBJ File cube.obj
Read in Vertices: 1.000000, -1.000000, -1.000000
Read in Vertices: 1.000000, -1.000000, 1.000000
Read in Vertices: -1.000000, -1.000000, 1.000000
Read in Vertices: -1.000000, -1.000000, -1.000000
Read in Vertices: 1.000000, 1.000000, -1.000000
Read in Vertices: 0.999999, 1.000000, 1.000001
Read in Vertices: -1.000000, 1.000000, 1.000000
Read in Vertices: -1.000000, 1.000000, -1.000000
Read in texture coordinate: 0.748573, 0.750412
Read in texture coordinate: 0.749279, 0.501284
Read in texture coordinate: 0.999110, 0.501077
Read in texture coordinate: 0.999455, 0.750380
Read in texture coordinate: 0.250471, 0.500702
Read in texture coordinate: 0.249682, 0.749677
Read in texture coordinate: 0.001085, 0.750380
Read in texture coordinate: 0.001517, 0.499994
Read in texture coordinate: 0.499422, 0.500239
Read in texture coordinate: 0.500149, 0.750166
Read in texture coordinate: 0.748355, 0.998230
Read in texture coordinate: 0.500193, 0.998728
Read in texture coordinate: 0.498993, 0.250415
Read in texture coordinate: 0.748953, 0.250920
Read in Normals: 0.000000, 0.000000, -1.000000
Read in Normals: -1.000000, -0.000000, -0.000000
Read in Normals: -0.000000, -0.000000, 1.000000
Read in Normals: -0.000001, 0.000000, 1.000000
Read in Normals: 1.000000, -0.000000, 0.000000
Read in Normals: 1.000000, 0.000000, 0.000001
Read in Normals: 0.000000, 1.000000, -0.000000
Read in Normals: -0.000000, -1.000000, 0.000000
Reached end of file
Out 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、glMultiTexCoor、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++中用vector填充一个简单的动态数组
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 一种在C++中读取TXT配置文件的简单方法
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 显示错误输出的简单数组排序程序
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 退出简单while循环时出现问题
- 为什么简单的算术减法在"if"条件下不起作用?
- C++-字符串是否包含一个带有简单循环的单词
- 关于 c++ 函数中指针赋值的简单问题
- 从函数返回任意简单类型的数据
- 如何在没有函数的情况下编写此代码并使C++更简单?
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 如何在.obj文件上运行IlDasm?
- C++OpenGL从文件中绘制简单OBJ
- 为什么当我创建一个对象数组时调用默认构造函数,但当我将obj创建为简单变量时却出错