如何将这个简单的OpenGL代码(在“宽松”的3.3和4.2版本中工作)运行在严格的3.2和4.2核心版本中?

7

我有一些3D代码,发现在严格的核心档案中无法渲染,但在“普通”(不是明确要求仅使用核心档案的)配置环境中运行良好。为了分离问题,我编写了一个最简单的OpenGL程序,只画一个三角形和一个矩形:

enter image description here

我已经将该OpenGL程序作为Gist发布在此处

当变量useStrictCoreProfile设置为false时,该程序不会向控制台输出任何错误消息,并根据上面的截图绘制一个四边形和一个三角形,在Intel HD OpenGL 3.3和具有OpenGL 4.2的GeForce上都绘制成功。

然而,当useStrictCoreProfile设置为true时,它会清除背景色但不绘制三角形和四边形,控制台输出如下:

GLCONN: OpenGL 3.2.0 @ NVIDIA Corporation GeForce GT 640M LE/PCIe/SSE2 (GLSL: 1.50 NVIDIA via Cg compiler)
LASTERR: OpenGL error at step 'render.VertexAttribPointer()': GL_INVALID_OPERATION
LASTERR: OpenGL error at step 'render.DrawArrays()': GL_INVALID_OPERATION
LASTERR: OpenGL error at step 'render.VertexAttribPointer()': GL_INVALID_OPERATION
LASTERR: OpenGL error at step 'render.DrawArrays()': GL_INVALID_OPERATION
LASTERR: OpenGL error at step '(post loop)': GL_INVALID_OPERATION
EXIT

如果请求的是4.2严格核心配置文件而不是3.2,则会出现相同的问题。适用于3个不同的NVIDIA GPU,因此我认为我没有正确符合严格的核心配置文件。我做错了什么,我该如何解决?
请注意,在上面的Gist中,您不会找到glEnableVertexAttribArray调用,因为我正在导入{{link1:glutil包}} - 但是这将在要点的compileShaders()函数的最后一步被调用。

1
你尝试过使用GL_ARB_debug_output扩展来获取比“GL_INVALID_OPERATION”更有用的错误消息吗?它需要一些设置的麻烦,但绝对值得。 - postgoodism
请分享一个最简单的Go OpenGL程序示例,如果您能提供一个,将会得到加1分。 - ANisus
说实话,这并不是“Go语言中最简单最小的OpenGL程序”,说实话...我们可以再精简一下 ;) - metaleap
1个回答

15
您没有使用glGenVertexArrays()glBindVertexArray()创建/绑定顶点数组对象。VAO封装了一堆顶点属性状态,包括哪些属性被启用,详细的每个属性信息等。当该功能最初引入时,它们是可选的,但现在根据OpenGL核心规范第10.4节,在严格/核心上下文中它们是必需的:

任何修改、绘制或查询顶点数组状态的命令都会生成INVALID_OPERATION错误,当没有绑定顶点数组时。这发生在初始GL状态中,并可能是由于BindVertexArray或DeleteVertexArrays的副作用而发生。

下面是VAO如何使用的非常简单的示例:
// At initialization time:
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Set up your vertex attribute state:
//  - glBindBuffer(GL_ARRAY_BUFFER,...);
//  - glEnableVertexAttribArray(...);
//  - glVertexAttribPointer(...);
//  - etc. -- Refer to OpenGL docs to see what is/isn't included in the VAO!
glBindVertexArray(0); // unbinds vao

// At draw time:
glBindVertexArray(vao); // automatically sets up previously-bound vertex attribute state
glDrawArrays(...);
glBindVertexArray(0); // unbinds vao

哇,根据你的回答我又深入了解了一些,你所说的似乎真的是这样... 我会尝试并回报的! - metaleap
没错!就是这样。今后在开发过程中将坚持使用核心配置文件以更早地捕获此类问题。 - metaleap
太好了!我想看到的是一些官方的OpenGL文档(而不是论坛/SE帖子),确认兼容性和核心GL上下文之间的差异(以及其他差异),但到目前为止我还没有找到。 - postgoodism
1
说实话,严格核心配置文件的规范PDF完全提到了这一点,我认为它非常完整。但像我这样的原始编码人员会不断地进行调整,并在论坛上询问数天,然后花费半个小时来研究和检查相关部分... ;)) - metaleap
嘿,你说得对,就在那里!让我用实际的规范引用更新我的答案... - postgoodism
+1 给“穴居人编程”。我相信你刚刚创造了一个新词。 - Qix - MONICA WAS MISTREATED

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接