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

标签 c++ opengl opengl-4

我对缓冲区的概念感到困惑。我了解 glBufferDataglBufferSubData 的基础知识。在主循环中的渲染函数之前使用glBufferSubData,您可以使用偏移大小参数将多个模型对象存储在顶点缓冲区和索引缓冲区。然后在渲染时绑定(bind)单个顶点缓冲区并使用正确的偏移量和大小调用 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 
}

最佳答案

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

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

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

请记住:glMapBuffer 速度并不快,因此请尽量避免在渲染循环期间使用它。调用glUnMap后,数据将被传输到GPU。

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

关于c++ - 使用 glMapBuffer 用一个缓冲区渲染多个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36469450/

相关文章:

objective-c - 从 NSImage 获取 GLuint 纹理

opengl - glRotate(angle,x,y,z),在这种情况下x,y,z是多少?

qt - openGL - 无法显示图像

c++ - 为什么派生类中的重写函数会隐藏基类的其他重载?

c++: main() 有问题? - 此处不允许在 '{' token 之前进行函数声明

c++ - 设置 std::threads 的线程亲和性

c++ - opengl重新编译显示列表

opengl - OpenGL 4.0++ 核心配置文件中固定功能管道的属性位置是什么?

opengl - 如何避免现代 GPU 上三角形之间出现黑线?

c++ - 使用 vector 还是数组?