【问题标题】:VAO renders fine on macOS, but INVALID_OPERATION on LinuxVAO 在 macOS 上呈现良好,但在 Linux 上呈现 INVALID_OPERATION
【发布时间】:2017-12-17 02:05:24
【问题描述】:

我有一个在 Qt Widgets 应用程序中使用 OpenGL 的应用程序。在切换到 Linux 之前,我曾经在一切正常的 macOS 上开发它。现在当我调用glBindVertexArray(mesh->getVao()); 时,OpenGL 会吐出 INVALID_OPERATION。

使用 AMD 的 CodeXL,我确定 mesh->getVao() 重新调整了 2。我还用它来获取所有 OpenGL 调用的列表。经检查,似乎生成了一个ID为2的VAO,调用列表中没有glDeleteVertexArrays。我什至将删除顶点数组的代码注释掉了。

OpenGL 文档指出,glBindVertexArray 可能失败的唯一原因是它未指定为零或生成的 VAO。

尽管存在 VAO,glBindVertexArray 会吐出 INVALID_OPERATION 是否还有其他可能的原因,以及为什么它可以在 macOS 上运行但不能在 Linux 上运行?


一些代码示例,如果有帮助的话

网格渲染

void renderMesh(const Resource::ResourceMesh *mesh) {
    //Set up textures
    for (unsigned int i = 0; i < mesh->getTextures().size(); i++) {
        glActiveTexture(GL_TEXTURE0 + i);
        mesh->getTextures().at(i)->getTexture()->bind();
    }
    static const int texIDs[32] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
    glUniform1iv(shaderTexID, MAX_SHADER_TEXTURES, texIDs);

    //Draw the mesh
    glBindVertexArray(mesh->getVao());
    qDebug() << "mesh == nullptr:" << (mesh == nullptr);
    glDrawElements(GL_TRIANGLES, mesh->getIndices().size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

VAO 生成

//In ResourceMesh.hpp

protected:
    QVector<Model::Vertex> vertices;
    QVector<unsigned int> indices;
    QVector<Resource::ResourceTexture*> textures;

    GLuint vao;
    GLuint vbo;
    GLuint ebo;

//In ResourceMesh.cpp

void ResourceMesh::generateGlBuffers() {
    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);
    glGenBuffers(1, &ebo);

    glBindVertexArray(vao);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Model::Vertex), &vertices[0], GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

    //Vertex positions
    glEnableVertexAttribArray(GLManager::VertexAttribs::VERTEX_POSITION);
    glVertexAttribPointer(GLManager::VertexAttribs::VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(Model::Vertex), (void*) offsetof(Model::Vertex, position));

    //Vertex normals
    glEnableVertexAttribArray(GLManager::VertexAttribs::VERTEX_NORMAL);
    glVertexAttribPointer(GLManager::VertexAttribs::VERTEX_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(Model::Vertex), (void*) offsetof(Model::Vertex, normal));

    //Vertex texture coordinates
    glEnableVertexAttribArray(GLManager::VertexAttribs::VERTEX_TEX_COORD);
    glVertexAttribPointer(GLManager::VertexAttribs::VERTEX_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(Model::Vertex), (void*) offsetof(Model::Vertex, texCoord));

    glBindVertexArray(0);
}

如果有帮助,这里是 CodeXL 的截图,在 glBindVertexArray 处打破

【问题讨论】:

  • 请检查您的Linux机器是否有GL_ARB_vertex_array_object扩展名。很可能它没有,因此出现了问题。
  • @hidefromkgb 该扩展名列在 Nvidia X 服务器设置下。
  • GL_INVALID_OPERATION 错误可能由之前的 gl 命令触发。当某些东西在操作系统中运行但在其他操作系统中不起作用时,我怀疑驱动程序的功能。在这种情况下,glActiveTexture max 和 glUniform1iv max 统一大小。
  • @Ripi2 CodeXL 强制调试上下文并让我确定哪个调用触发了 GL_INVALID_OPERATION。我也刚刚评论了这一点,但仍然遇到同样的问题。
  • 你有两个上下文。您是否将应用 VAO 的上下文设置为当前?

标签: c++ linux macos qt opengl


【解决方案1】:

已在 cmets 中解决 - 结果发现 VAO 是在错误的上下文中创建的。我猜 Qt 的 macOS 实现共享所有内容的上下文,而在 Linux 上,它们是分开的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 2021-09-11
    • 1970-01-01
    相关资源
    最近更新 更多