使用glMapBuffer使用一个缓冲区渲染多个对象?

时间:2016-04-07 07:28:39

标签: c++ opengl opengl-4

我对缓冲区的概念感到困惑。我理解 glBufferData glBufferSubData 的基础知识。在主循环中的渲染函数之前使用 glBufferSubData ,可以使用偏移 size 参数在顶点缓冲区中存储多个模型对象索引缓冲区。然后在渲染时绑定单个顶点缓冲区并使用正确的偏移和大小调用 glDrawElements 以渲染多个对象。

这是 glMapBuffer 的情况吗?或者我想调用 glMapBuffer 来链接顶点和索引数据,然后绘制?

GLuint vertexArrayId;
GLuint verticesBufferId;
GLuint indicesBufferId;

void setupBuffers() {
    glGenVertexArrays(1, &vertexArrayId);
    glBindVertexArray(vertexArrayId);
    glGenBuffers(1, &verticesBufferId);
    glGenBuffers(1, &indicesBufferId);

    glBindBuffer(GL_ARRAY_BUFFER, verticesBufferId);
    glBufferData(GL_ARRAY_BUFFER, VERTICES_SIZE, NULL, GL_STATIC_DRAW);
    // glMapBuffer stuff here 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBufferId);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES_SIZE, NULL, GL_STATIC_DRAW);
    // glMapBuffer stuff here
}

void render() {
    glBindBuffer(GL_ARRAY_BUFFER, verticesBufferId);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)((sizeof(GLfloat) * 0)));

    glEnableVertexAttribArray(0);
    // glDrawElements stuff here
    glDisableVertexAttribArray(0);

    // Model, View, Projection transformations here
    // glUniformMatrix4fv 
}

1 个答案:

答案 0 :(得分:2)

您可以使用glMapBuffer将数据从ram上传到GPU:

    glBindBuffer(GL_ARRAY_BUFFER, verticesBufferId);
    void *data = glMapBuffer( GL_ARRAY_BUFFER, ... );
    // copy vertex data from instance 
    ::memcpy( data, vertices, vertexSize );
    ...
    glUnmapBuffer( ... );

例如,当您想要从模型上传顶点数据和索引数据时。你可以使用从glMapBuffer返回的指针,就像raw-c-pointer一样(只是为了方便)

请记住:glMapBuffer并不快,所以尽量避免在渲染循环中使用它。在调用glUnMap之后,数据将被转移到GPU。

当您必须定期将数据从CPU上传到GPU时,有更好的方法,例如使用Uniform-Blocks。 我找到了这篇博文,其中的映射解释得非常好(有其所有缺点):Mapping in OpenGL