【问题标题】:OpenGL: INVALID_OPERATION following glEnableVertexAttribArrayOpenGL:在 glEnableVertexAttribArray 之后的 INVALID_OPERATION
【发布时间】:2023-03-19 02:02:01
【问题描述】:

我正在将功能正常的 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() 的失败案例有哪些?有没有我之前没有设置的状态?

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

建议?

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

【问题讨论】:

    标签: c++ macos opengl xcode5


    【解决方案1】:

    您在 OS X 上看到此错误是因为它仅在您使用 OpenGL 3.x 或更高版本时才支持 OpenGL Core Profile。您的代码不符合核心配置文件。您很可能在 Windows 上使用了兼容性配置文件。

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

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

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

    接下来,您可能想检查最新版本中是否有更好的功能。您也这样做,但选择“OpenGL 4 Reference Pages”。错误情况仍未列出。

    现在您已经意识到,就像您之前的许多人一样,这些手册页经常是错误的。所以你去最终的来源:规格。这次您在“文档”菜单中选择“OpenGL Registry”。这为您提供了指向 PDF 格式的所有规范文档的链接。再次,让我们先尝试 3.3。在文档中搜索“EnableVertexAttribArray”,发现...仍然没有 GL_INVALID_OPERATION 记录为可能的错误。

    最后一招,检查最新的规范文档,即 4.4。再次寻找“EnableVertexAttribArray”,是时候使用 heureka:

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

    我很确定该错误也适用于 GL3。虽然手册页不完整是相当常见的,但规范文档遗漏内容的情况要少得多。密切相关的 glVertexAttribPointer() 调用已经在 GL3 中记录了这种错误情况。

    【讨论】:

    • 很棒的答案。谢谢!我正在使用 4.1 前向兼容上下文,但 vao 绑定是问题所在。干杯。
    • 另外,我非常感谢您浏览文档搜索过程。非常有帮助。并且写得很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 2022-12-02
    相关资源
    最近更新 更多