mk1*_*k12 18 opengl performance vbo draw
从效率的角度来看(或者如果它很重要的另一种观点),什么是可取的?
情况
一种OpenGL应用程序,每帧(60 fps)在不同位置绘制许多行.可以说有10行.或100 000行.答案会有所不同吗?
每一帧每行都会有一个glDrawArrays调用,而在两者之间会有矩阵变换来定位我们的一行
每个帧都有一个绘制调用
ssu*_*ube 28
第二个是非常有效率.
改变状态,尤其是转换和矩阵,往往会导致其他状态的重新计算,并且通常会导致更多的数学运算.
但是,更新几何图形只需要覆盖缓冲区.
使用相当大的带宽总线上的现代视频硬件,发送一些浮动是微不足道的.它们旨在快速移动大量数据,这是工作的副作用.更新顶点缓冲区正是它们经常和快速执行的操作.如果我们假设每个32字节(float4位置和颜色),100000个线段小于6 MB,PCIe 2.0 x16大约8 GB/s,我相信.
在某些情况下,根据驱动程序或卡处理变换的方式,更改一个可能会导致某些矩阵乘法并重新计算其他值,包括变换,剔除和剪裁平面等.如果您更改状态,这不是问题,绘制几千个多边形,并重复,但当状态经常发生变化时,它们将会产生巨大的成本.
之前解决的一个很好的例子是批处理的概念,最小化状态变化,因此可以在它们之间绘制更多的几何.这用于更有效地绘制大量几何体.
作为一个非常明显的例子,考虑#1的最佳情况:变换集触发没有额外的计算和驱动程序热情和完美缓冲.要绘制100000行,您需要:
单独的函数调用开销会破坏性能.
另一方面,批处理涉及:
您可以复制更多数据,但VBO内容很可能不如复制矩阵数据那么昂贵.另外,在函数调用中可以节省大量的CPU时间(200000到2).这简化了您的生活,驱动程序(必须缓冲所有内容并检查冗余调用并优化和处理下载)以及可能的视频卡(可能必须重新计算).为了使其清晰,可视化简单的代码:
for (i = 0; i < 100000; ++i)
{
matrix = calcMatrix(i);
setMatrix(matrix);
drawLines(1, vbo);
}
Run Code Online (Sandbox Code Playgroud)
(现在打开那个)
matrix = calcMatrix();
setMatrix(matrix);
for (i = 0; i < 100000; ++i)
{
localVBO[i] = point[i];
}
setVBO(localVBO);
drawLines(100000, vbo);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11258 次 |
| 最近记录: |