OpenGL更新缓冲区如何影响速度

OpenGL How does updating buffers affect speed

我有一个映射到要发送的顶点属性的缓冲区。这是代码的基本功能:

glBindBuffer(GL_ARRAY_BUFFER, _bufferID);
_buffer = (VertexData*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

for(Renderable* renderable : renderables){
    const glm::vec3& size = renderable->getSize();
    const glm::vec3& position = renderable->getPosition();
    const glm::vec4& color = renderable->getColor();
    const glm::mat4& modelMatrix = renderable->getModelMatrix();
    glm::vec3 vertexNormal = glm::vec3(0, 1, 0);


    _buffer->position = glm::vec3(modelMatrix * glm::vec4(position.x, position.y, position.z, 1));
    _buffer->color = color;
    _buffer->texCoords = glm::vec2(0, 0);
    _buffer->normal = vertexNormal;
    _buffer++;
}

然后我在一次绘制调用中绘制所有可渲染对象。我很好奇为什么触摸 _buffer 变量会导致程序大幅减速。例如,如果我每帧都调用 std::cout << _buffer->position.x;,我的 fps 会下降到通常的 1/4 左右。

我想知道的是为什么会这样。我想知道的原因是因为我希望能够在移动时批量提供翻译对象。本质上,我希望缓冲区始终位于同一位置并且不会更改,但我可以更改它而不会对性能造成巨大牺牲。我认为这是不可能的,但我想知道为什么。如果这不会导致大量问题,下面是我想做的事情的示例:

if(renderables.at(index)->hasChangedPosition())
    _buffer+=index;
    _buffer->position = renderables.at(index)->getPosition();

我知道我可以通过着色器统一发送变换,但您不能在一次绘制调用中对批处理对象执行此操作。

why touching the _buffer variable at all causes massive slow down in the program

...好吧,你确实请求了一个GL_WRITE_ONLY缓冲区; GL 驱动程序完全有可能使用自定义 fault 处理程序设置支持 glMapBuffer() 返回的指针的内存页面,该处理程序实际上会传到 GPU 以获取请求的字节,这可以是...不快。

而如果您只 写入提供的地址,则 driver/OS 在 glUnmapBuffer() 调用之前无需执行任何操作,此时它可以设置一个很好的、快速的 DMA 传输来一次性将新的缓冲区内容发送到 GPU 内存。