简体   繁体   English

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

[英]OpenGL How does updating buffers affect speed

I have a buffer I map to vertex attributes to send.我有一个缓冲区,我映射到要发送的顶点属性。 Here is the basic functionality of the code:下面是代码的基本功能:

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++;
}

and then I draw all renderables in one draw call.然后我在一次绘制调用中绘制所有可渲染对象。 I am curious as to why touching the _buffer variable at all causes massive slow down in the program.我很好奇为什么完全触摸_buffer变量会导致程序大幅减慢。 For example, if I call std::cout << _buffer->position.x;例如,如果我调用std::cout << _buffer->position.x; every frame, my fps tanks to about 1/4th of what it usually is.每一帧,我的 fps 都会降低到通常的 1/4 左右。

What I want to know is why it does this.我想知道的是它为什么这样做。 The reason I want to know is because I want to be able to give translate objects in the batch when they are moved.我想知道的原因是因为我希望能够在移动时在批处理中给出翻译对象。 Essentially, I want the buffer to always be in the same spot and not change but I can change it without huge sacrifices to performance.从本质上讲,我希望缓冲区始终位于同一位置并且不会更改,但我可以在不牺牲性能的情况下更改它。 I assume this isn't possible but I would like to know why.我认为这是不可能的,但我想知道为什么。 Here is an example of what I would want to do if this didn't cause massive issues:这是一个示例,说明如果这不会导致大问题,我会怎么做:

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

I am aware I can send the transforms through the shader uniform but you can't do that for batched objects in one draw call.我知道我可以通过着色器统一发送变换,但您不能在一次绘制调用中对批处理对象执行此操作。

why touching the _buffer variable at all causes massive slow down in the program为什么完全接触 _buffer 变量会导致程序大幅减慢

...well, you did request a GL_WRITE_ONLY buffer; ...好吧,您确实请求了GL_WRITE_ONLY缓冲区; it's entirely possible that the GL driver set up the memory pages backing the pointer returned by glMapBuffer() with a custom fault handler that actually goes out to the GPU to fetch the requested bytes, which can be...not fast. GL 驱动程序完全有可能使用自定义错误处理程序设置支持glMapBuffer()返回的指针的内存页,该处理程序实际上会转到 GPU 以获取请求的字节,这可能......不快。

Whereas if you only write to the provided addresses the driver/OS doesn't have to do anything until the glUnmapBuffer() call, at which point it can set up a nice, fast DMA transfer to blast the new buffer contents out to GPU memory in one go.而如果你只写入提供的地址,驱动程序/操作系统在glUnmapBuffer()调用之前不必做任何事情,此时它可以设置一个很好的、快速的 DMA 传输来将新的缓冲区内容发送到 GPU 内存一气呵成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM