如果我的 VBO class 引用顶点数组,数据是否仍存储在 GPU 上?

If my VBO class references vertex arrays, is data still stored on the GPU?

很简单,我的问题是这样的。下面是我的代码,用于跟踪和处理 OpenGL 中的顶点缓冲区对象的 C++ 头文件。为了符合核心标准,它必须使用顶点数组(VAO)。由于调用了glGenVertexArrays()等相关方法,请问这个渲染方法是否还有信息存储在GPU或RAM中?

class VertexBuffer
{
private:
    int vertCount;

    GLuint vertArray;
    GLuint vertBuffer;

public:
    VertexBuffer();
    void renderInterleaved();
    void createInterleaved(GLfloat*, int);
    void destroy();

    GLuint* getVboId();
};

VertexBuffer::VertexBuffer()
{
    glGenVertexArrays(1, &vertArray);
    glGenBuffers(1, &vertBuffer);
}

void VertexBuffer::renderInterleaved()
{
    glBindVertexArray(vertArray);
    glBindBuffer(GL_ARRAY_BUFFER, vertBuffer);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    int stride = 7 * sizeof(GLfloat);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*) 0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, stride, (void*)(3 * sizeof(GLfloat)));
    glDrawArrays(GL_TRIANGLES, 0, vertCount);

    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void VertexBuffer::createInterleaved(GLfloat* data, int vertices)
{
    vertCount = vertices;
    glBindBuffer(GL_ARRAY_BUFFER, vertBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices * 21 * sizeof(GLfloat), data, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void VertexBuffer::destroy()
{
    glDeleteBuffers(1, &vertBuffer);
    glDeleteVertexArrays(1, &vertArray);
}

GLuint* VertexBuffer::getVboId()
{
    return &vertBuffer;
}

术语 "vertex buffer object" 一直以来都是用词不当,由引入缓冲区对象的扩展的不幸命名造成。

没有"vertex buffer object."只有buffer object,表示OpenGL管理内存的线性数组。缓冲区对象可用于存储用于渲染操作的顶点数据,但任何特定的缓冲区对象都没有 intrinsic 可以做到这一点。只是如何使用的问题。

如果您的对象封装了您将用于 glVertexAttribPointer 的参数,那么它不仅仅封装了一个缓冲区对象。缓冲区对象不知道如何呈现自身或它包含什么数据;它只是一个缓冲区。它代表的最接近的OpenGL概念是顶点数组对象。

但是您的代码也没有真正使用 VAO。每次调用 renderInterleaved 时,您都在设置已作为 VAO 的一部分存储的状态。所有这些 glVertexAttribPointerglEnableVertexAttribArray 调用都记录在 VAO 中。这是你应该设置一次的东西,然后只需绑定 VAO 并用它渲染。所以是的,这是一个效率较低的 VAO。

但是您的 class 比 VAO 封装了 更多。它知道如何呈现自己。因此,class 的最佳名称是 "mesh" 或类似的名称。