OpenGL: INVALID_OPERATION following glEnableVertexAttribArra
OpenGL: INVALID_OPERATION following glEnableVertexAttribArray
我正在将一个功能正常的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中记录了这个错误条件。