不能创建多个 VAO

Posted

技术标签:

【中文标题】不能创建多个 VAO【英文标题】:Cannot create more than one VAO 【发布时间】:2014-11-20 04:44:22 【问题描述】:

我正在尝试使用现代 (3.3) OpenGL 创建一个用于游戏的简单图形系统。动态对象将具有动态几何图形,并且 VBO 将在发生更改时更新。这部分很容易实现。虽然只要只使用一个 VAO,一切都运行良好,但对 glGenVertexArrays 的进一步调用不会创建另一个对象(打印第一个和第二个的 ID 都返回 1)并且新对象的 VAO 初始化中的某些内容会呈现第一个无法执行任何编辑。每个“现代 OpenGL”教程要么只使用一个对象,要么有一些非常重要的冲突(最常见的是使用 glVertexAttribPointer)。以下代码涉及对象的图形系统。 (不知道这有多重要,但我正在使用 glfw3 来创建窗口和上下文)。

初始化游戏对象(图形 sn-p)

glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
glGenBuffers(1, &vertexCoordBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
glBufferData(GL_ARRAY_BUFFER, 2000 * 3 * sizeof(float), nullptr, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);
allocatedVerticies = 2000;

更新网格

    //generate mesh
std::vector<float> vertices;
vertices.reserve(voxels.size() * 3 * 12);

//Vertices are added to the vector. This part works. Removed this code for clarity.


vertexCount = vertices.size() / 3;
glBindVertexArray(vertexArrayID);
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
if (allocatedVerticies < vertexCount)

    //reallocate the buffers
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    allocatedVerticies = vertexCount;

else

    /////////////////////////////
    //reallocate the buffers- originally a reallocation was not going to be used, but glBufferSubData does not work
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    allocatedVerticies = vertexCount;


    ////////////////////////////////////////this does not work for some reason
    //reset data
    //glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(float), vertices.data());

edited = false;

渲染对象

glBindVertexArray(vertexArrayID);
glDrawArrays(GL_TRIANGLES, 0, vertexCount);

如果有人对 OpenGL 更有经验,可以指出我的错误(或其他问题),那就太好了。

【问题讨论】:

这段代码在 C++ 类中?如果是,您是否删除了析构函数中的 OpenGL 对象?您是否有可能不小心复制了这些对象?如果这听起来可能,我会定义私有复制构造函数和赋值运算符以防止意外复制。 我已经设置了复制构造函数和赋值运算符,如果调用它们就会抛出错误。他们从不这样做,所以我认为这与问题无关。 【参考方案1】:

在您提供的代码中,我看不到任何可能导致这种行为的东西。也许您应该提供与您的渲染相关的整个解决方案,以便更好地了解您的程序中发生了什么?

顺便说一句:如果您已经为您的缓冲区定义了glVertexAttribPointer(),那么您不必每次更新存储在您的vertexCoordBufferID 中的数据时都这样做如果您当然不更改数据布局及其类型。而不是:

vertexCount = vertices.size() / 3;
glBindVertexArray(vertexArrayID);
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
if (allocatedVerticies < vertexCount)

    //reallocate the buffers
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    allocatedVerticies = vertexCount;

你可以只使用:

vertexCount = vertices.size() / 3;
glBindBuffer(GL_ARRAY_BUFFER, vertexCoordBufferID);
if (allocatedVerticies < vertexCount)

    //reallocate the buffers
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
    allocatedVerticies = vertexCount;

【讨论】:

以上是关于不能创建多个 VAO的主要内容,如果未能解决你的问题,请参考以下文章

为啥纹理(GL_TEXTURE_2D)不能与(VertexArray)VAO一起使用

没有 VAO 的每个着色器属性的 VBO 或不同的方法?

多网格模型的 vao 管理

多个缓冲器和 VAO 性能

VAO 中的 C++ GLSL 多个 IBO

一个 VBO 可以绑定多个 VAO 吗?