英文:
How do I make this simple OpenGL code (works in a "lenient" 3.3 and 4.2 profile) work in a strict 3.2 and 4.2 core profile?
问题
我有一些3D代码,我注意到它在严格的核心配置文件中无法渲染,但在“正常”(没有明确要求为核心配置文件的)配置文件上可以正常工作。为了隔离问题,我编写了最简单的OpenGL程序,只绘制了一个三角形和一个矩形:
我已经将该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调用,因为它在我导入的glutil包中 - 但是这在Gist的**compileShaders()**函数的最后一步中被调用。
英文:
I had some 3D code that I noticed wouldn't render in a strict core profile but fine in a "normal" (not explicitly requested-as-core-only) profile context. To isolate the issue, I have written the smallest simplest possible OpenGL program drawing just a triangle and a rectangle:
I have posted that OpenGL program as a Gist here.
With the useStrictCoreProfile variable set to false, the program outputs no error messages to the console and draws a quad and a triangle as per the above screenshot, both on an Intel HD OpenGL 3.3 and on a GeForce with OpenGL 4.2.
However, with useStrictCoreProfile set to true, it clears the background color but does not draw the tri & quad, console output is this:
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
... if a 4.2 strict core profile is requested instead of 3.2, same issue. Applies to 3 different nvidia GPUs so I assume I'm not conforming to the strict core profile properly. What was I doing wrong, and how can I fix this?
Note, you won't find a glEnableVertexAttribArray call in the above Gist, as it's inside the glutil package I'm importing -- but this does get called as the last step in the gist's compileShaders() func.
答案1
得分: 15
你没有使用[glGenVertexArrays()]和[glBindVertexArray()]创建/绑定Vertex Array Object。VAO封装了一组顶点属性状态,包括启用哪些属性,详细的每个属性信息等。当该功能最初引入时,它们是可选的,但根据OpenGL核心规范的第10.4节,它们现在在严格/核心上下文中是必需的:
> 当没有绑定顶点数组时,任何修改、绘制或查询顶点数组状态的命令都会生成INVALID_OPERATION错误。这在初始GL状态下发生,并且可能是由于BindVertexArray或DeleteVertexArrays的副作用而发生。
以下是如何使用VAO的一个简单示例:
// 在初始化时:
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// 设置顶点属性状态:
// - glBindBuffer(GL_ARRAY_BUFFER,...);
// - glEnableVertexAttribArray(...);
// - glVertexAttribPointer(...);
// - 等等 - 参考OpenGL文档以了解VAO包含什么/不包含什么!
glBindVertexArray(0); // 解绑vao
// 在绘制时:
glBindVertexArray(vao); // 自动设置之前绑定的顶点属性状态
glDrawArrays(...);
glBindVertexArray(0); // 解绑vao
英文:
You're not creating/binding a Vertex Array Object with glGenVertexArrays() and glBindVertexArray(). VAOs encapsulate a bunch of vertex attribute state, including which attributes are enabled, detailed per-attribute information, etc. They were optional when the feature was originally introduced, but they're now required in strict/core contexts according to section 10.4 of the OpenGL core specification:
> An INVALID_OPERATION error is generated by any commands which
modify, draw from, or query vertex array state when no vertex array is bound.
This occurs in the initial GL state, and may occur as a result of BindVertexArray or a side effect of DeleteVertexArrays.
Here's a very rough example of how VAOs are used:
// 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论