我该如何使这个简单的OpenGL代码(工作在“宽松的”3.3和4.2配置文件中)在严格的3.2和4.2核心配置文件中工作? [英] 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?

查看:223
本文介绍了我该如何使这个简单的OpenGL代码(工作在“宽松的”3.3和4.2配置文件中)在严格的3.2和4.2核心配置文件中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些3D代码,我注意到它们不会在严格的核心配置文件中呈现,但可以在正常(未明确请求的仅作为核心)配置文件上下文中呈现。为了隔离这个问题,我写了最小的最简单的OpenGL程序,绘制一个三角形和一个矩形:


我发布了OpenGL程序 as a Gist here


$ b 使用 useStrictCoreProfile 变量设置为false ,程序不会向控制台输出错误消息,并按照上述屏幕截图绘制四边形和三角形,无论是在英特尔HD OpenGL 3.3还是带有OpenGL 4.2的GeForce上。



然而,其中 strictCoreProfile 设置为true,它清除背景颜色,但不绘制tri&四,控制台输出是这样的:

  GLCONN:OpenGL 3.2.0 @ NVIDIA公司GeForce GT 640M LE / PCIe / SSE2(GLSL :1.50 NVIDIA via Cg compiler)
LASTERR:在步骤'render.VertexAttribPointer()'处的OpenGL错误:GL_INVALID_OPERATION
LASTERR:步骤'render.DrawArrays()'处的OpenGL错误:GL_INVALID_OPERATION
LASTERR :步骤'render.VertexAttribPointer()'处的OpenGL错误:GL_INVALID_OPERATION
LASTERR:步骤'render.DrawArrays()'处的OpenGL错误:GL_INVALID_OPERATION
LASTERR:步骤'(后循环)'处的OpenGL错误: GL_INVALID_OPERATION
EXIT

...如果请求4.2严格核心配置文件而不是3.2,同样的问题。适用于3个不同的NVIDIA GPU,所以我假设我不符合严格的核心配置文件。注意,在上面的Gist中你找不到 glEnableVertexAttribArray 调用,因为它是 glutil软件包中的内容 I' m导入 - 但是这确实被称为要点的最后一步 compileShaders() func。

解决方案

您不是使用顶点数组对象 www.opengl.org/wiki/GLAPI/glGenVertexArrays> glGenVertexArrays()和 glBindVertexArray() 。 VAO封装了一堆顶点属性状态,包括启用了哪些属性,每个属性的详细信息等。当功能最初被引入时,它们是可选的,但是它们现在在严格/核心上下文中根据< OpenGL核心规范


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


下面是一个非常粗略的例子,说明如何使用VAO:

  //在初始化时间:
GLuint vao = 0;
glGenVertexArrays(1,& vao);
glBindVertexArray(vao);
//设置你的顶点属性状态:
// - glBindBuffer(GL_ARRAY_BUFFER,...);
// - glEnableVertexAttribArray(...);
// - glVertexAttribPointer(...);
// - 等 - 请参阅OpenGL文档以查看VAO中包含的内容!
glBindVertexArray(0); // unbinds vao

//在绘制时间:
glBindVertexArray(vao); //自动设置以前绑定的顶点属性状态
glDrawArrays(...);
glBindVertexArray(0); // unbinds vao


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.

解决方案

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

这篇关于我该如何使这个简单的OpenGL代码(工作在“宽松的”3.3和4.2配置文件中)在严格的3.2和4.2核心配置文件中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆