调用glDrawElements时出现Segfault



我有一个OpenGL应用程序正在macOS上开发。在我的代码中,我有一个对glDrawElements的调用,该调用会出错。我正在链接OpenGL.framework文件并包含<OpenGL/gl.h>。然而,如果我包含<OpenGL/gl3.h>,程序就不会出错,而且它或多或少都能正常工作(我仍然收到无效的操作调用,但网格会拖到屏幕上)。这是扩展加载问题吗?我没有使用GLEW或任何扩展加载库。我正在创建一个2.1版本的上下文。

这是我设置OpenGL数据的地方,这是我进行实际绘图的地方。我还将注意到,这是在Linux机器上运行的,没有任何问题。这似乎只是macOS,我有segfault。

这是堆栈跟踪:

(lldb) bt
* thread #1: tid = 0x206bb7, 0x00007fff92a330d0 libsystem_platform.dylib`_platform_memmove$VARIANT$Nehalem + 112, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x00007fff92a330d0 libsystem_platform.dylib`_platform_memmove$VARIANT$Nehalem + 112
frame #1: 0x00007fff78853c86 GeForceGLDriver`___lldb_unnamed_symbol5651$$GeForceGLDriver + 187
frame #2: 0x00007fff78855102 GeForceGLDriver`___lldb_unnamed_symbol5659$$GeForceGLDriver + 771
frame #3: 0x00007fff789710fe GeForceGLDriver`___lldb_unnamed_symbol10497$$GeForceGLDriver + 393
frame #4: 0x00007fff8227a15f GLEngine`glDrawElements_Exec + 271
frame #5: 0x0000000100030fb4 mcomp`GLRender::DrawModel(this=0x00007fff5fbff7f8, model=0x0000000100770e20) + 5956 at glrender.cc:202
frame #6: 0x0000000100003fa7 mcomp`Mcomp::Update(this=0x00007fff5fbff7b8) + 423 at mcomp.cc:27
frame #7: 0x0000000100007941 mcomp`Engine::Run(this=0x00007fff5fbff798) + 65 at engine.cc:22
frame #8: 0x00000001000026ea mcomp`main(argc=1, argv=0x00007fff5fbffa00) + 378 at main.cc:21
frame #9: 0x00007fff92826255 libdyld.dylib`start + 1
(lldb) 

我在这里看到了一些错误。

  • 当绑定了缓冲区对象(顶点属性应从中提取数据)时,必须调用glVertexAttribPointer()。我建议首先设置和配置顶点缓冲区(包括顶点属性),然后分别进行索引缓冲区。您目前正在对它们进行混合和匹配
  • 在调用glVertexAttribPointer()之后,您可能需要调用glEnableVertexAttribArray(),尽管我不完全记得标准是否需要这样做
  • "顶点阵列对象"将跟踪所设置的顶点属性。反过来,顶点属性会记住它们从哪个缓冲区对象中提取数据。因此,绘制时不需要显式绑定缓冲区对象
  • 当你设置的缓冲区对象太小,你试图绘制比索引缓冲区更多的索引,或者你的步幅偏离时,调用glDrawElements()通常会出现分段错误。因此,确保所有长度、大小等对你来说都有意义是一个好主意。当索引缓冲区引用越界值时也可能发生这种情况,但如果我记得正确的话,这可能取决于如何处理这种情况的实现

为了参考,以下是我通常设置VAO的顺序:

  1. 创建VAO
  2. 绑定VAO
  3. 创建缓冲区(顶点)
  4. 绑定缓冲区
  5. 用几何数据填充缓冲区
  6. 设置相关的顶点属性指针
  7. 启用顶点属性指针
  8. 创建缓冲区(索引)
  9. 绑定缓冲区
  10. 用索引填充缓冲区

这应该会设置所有内容。要绘制,请使用相关着色器程序,绑定VAO并调用glDrawElements()

编辑:你能概述一下为什么你要创建一个2.x上下文,而不是3.x或4.x上下文吗?使用缓冲区和VAO绘制是OpenGL的现代渲染方式。为什么不将上下文版本与该级别相匹配?

相关内容

  • 没有找到相关文章

最新更新