c++ - OpenGL更新缓冲区如何影响速度
问题描述
我有一个缓冲区,我映射到要发送的顶点属性。以下是代码的基本功能:
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();
我知道我可以通过着色器制服发送变换,但你不能在一次绘制调用中对批处理对象执行此操作。
解决方案
为什么完全触摸 _buffer 变量会导致程序大幅减速
...好吧,您确实请求了GL_WRITE_ONLY
缓冲区;glMapBuffer()
GL 驱动程序完全有可能使用自定义错误处理程序设置支持返回的指针的内存页面,该错误处理程序实际上会发送到 GPU 以获取请求的字节,这可能......不是很快。
然而,如果您只写入提供的地址,驱动程序/操作系统在调用之前无需执行任何操作glUnmapBuffer()
,此时它可以设置一个很好、快速的 DMA 传输,以便将新的缓冲区内容一次性发送到 GPU 内存.
推荐阅读
- python - 将附加子图的 x 轴刻度位置与 FacetGrid 对象的 x 轴刻度位置对齐
- visual-studio-code - 如何更改vscode中折叠块的背景颜色?
- flutter - 如何让博客在 TabBarView 中工作?
- amazon-s3 - AWS Glue 检查文件内容的正确性
- python - 如何使用python中的自定义字段将对象序列化为json
- android - 如何将 Timber 日志重定向到 Junit logcat
- java - 如何随机选择运营商?
- docker - 'docker ps' 中的命令是什么意思?
- javascript - const 变量:已经被声明
- python - TypeError:添加的层必须是类Layer的实例。成立: