OpenGL: INVALID_OPERATION following glEnableVertexAttribArra

OpenGL: INVALID_OPERATION following glEnableVertexAttribArray

本文关键字:following glEnableVertexAttribArra OPERATION INVALID OpenGL      更新时间:2023-10-16

我正在将一个功能正常的OpenGL应用程序从Windows移植到OSX,并在调用glEnableVertexAttribArray()后不断获得"无效操作"(代码1282)错误。下面是渲染方法:

gl::Disable(gl::DEPTH_TEST);    
gl::Disable(gl::CULL_FACE);
gl::PolygonMode(gl::FRONT_AND_BACK,gl::FILL);
/// render full-screen quad
gl::UseProgram(m_program);
check_gl_error();
gl::BindBuffer(gl::ARRAY_BUFFER, m_vertexBuffer);
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, m_indexBuffer);
check_gl_error();
GLint positionLocation = -1;
positionLocation = gl::GetAttribLocation(m_program,"Position");
check_gl_error();
/// positionLocation now == 0
gl::EnableVertexAttribArray(positionLocation);
//// ************ ERROR RETURNED HERE **********************
//// ************ ERROR RETURNED HERE **********************
check_gl_error();
gl::VertexAttribPointer(positionLocation,3,gl::FLOAT,false,3 * sizeof(GLfloat),(const GLvoid*)0);
check_gl_error();
gl::DrawElements(gl::TRIANGLES,m_indexCount,gl::UNSIGNED_SHORT,0);
check_gl_error();
gl::BindBuffer(gl::ARRAY_BUFFER,0);
check_gl_error();
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER,0);
check_gl_error();

check_gl_error()只获取最后一个GL错误并返回一个稍微可读的描述。

此代码在Windows下运行良好。但是,正如我很快了解到的,这并不一定意味着它是正确的。我已经验证了所有先前绑定的对象(程序,顶点缓冲区,索引缓冲区)都是有效的句柄。glGetAttribLocation()返回Position属性的有效位置(在本例中为0)。

glEnableVertexAttribArray()的失败案例有哪些?有没有我之前没有设置过的状态?

如果我注释掉绘制代码,窗口在每一帧上都被清除为我的测试颜色(红色)(从代码片段中未显示的方法调用),其他一切都工作正常,这意味着其他一切都是正确的。

建议吗?

哦,对于GL状态机模拟器,它会告诉我为什么是一个"无效操作"。(或者引用一些神秘的、神奇的文档,描述每个gl*调用所需的输入状态。)

你在OS X上看到这个错误是因为如果你使用的是OpenGL 3,它只支持OpenGL核心配置文件。X或更高。您的代码不符合核心配置文件。您很可能在Windows上使用了兼容性配置文件。

具体来说,核心配置文件要求为所有顶点相关的调用绑定一个顶点数组对象(VAO)。因此,在调用glEnableVertexAttribArray()或其他类似函数之前,您需要创建并绑定一个VAO:

GLuint vaoId = 0;
glGenVertexArrays(1, &vaoId);
glBindVertexArray(vaoId);

关于如何发现错误条件:在这种情况下,它并不像应该的那么容易。假设您使用GL3级别的功能集。在理想的情况下,你会去www.opengl.org,拉下"文档"菜单靠近左上角,选择"OpenGL 3.3参考页面",点击左侧窗格中的glEnableVertexAttribArray,并查看页面上的"错误"部分。然后你看到…GL_INVALID_OPERATION没有被列为可能的错误。

接下来,您可能想要检查最新版本中是否有更好的东西。你做同样的事情,但选择"OpenGL 4参考页面"代替。

仍未列出错误条件。

现在您已经意识到,就像您之前的许多人一样,这些手册页经常是错误的。所以你找到了最终的来源:规格。这次你在文档菜单中选择"OpenGL注册表"。这为您提供了PDF格式的所有规范文档的链接。同样,让我们先试试3.3。搜索"EnableVertexAttribArray"在文档中,有…仍然没有GL_INVALID_OPERATION文档作为可能的错误。

最后,检查最新的规范文档,即4.4。再次寻找"enablevertexattriarray",是时候来个提示了:

如果没有绑定顶点数组对象,将生成INVALID_OPERATION错误。

我很确定这个错误也适用于GL3。尽管手册页不完整很常见,但规范文档缺少内容的情况要少见得多。非常密切相关的glVertexAttribPointer()调用已经在GL3中记录了这个错误条件。