从效率的角度(或其他重要的观点来看)是什么更喜欢?OpenGL是更好的批量绘制或具有静态VBOs
现状
一个OpenGL应用程序,它在不同的位置绘制多行每帧(每秒60帧)。可以说有10条线。或100000行。答案会不同吗?
- #1具有静态VBO永远不会改变,含有线
每帧将有一个调用glDrawArrays每行绘制调用的2个顶点,和在它们之间会有矩阵变换定位我们一行
- #2更新的VBO与所有行的数据每帧
每一帧都会有一个平局呼叫
从效率的角度(或其他重要的观点来看)是什么更喜欢?OpenGL是更好的批量绘制或具有静态VBOs
现状
一个OpenGL应用程序,它在不同的位置绘制多行每帧(每秒60帧)。可以说有10条线。或100000行。答案会不同吗?
每帧将有一个调用glDrawArrays每行绘制调用的2个顶点,和在它们之间会有矩阵变换定位我们一行
每一帧都会有一个平局呼叫
第二个是令人难以置信的更高效。
更改状态,特别是转换和矩阵,往往会导致重新计算其他状态,并且通常会导致更多的数学运算。
但是,更新几何图形只涉及覆盖缓冲区。
随着现代视频硬件在相当大规模的带宽总线上,发送几个浮点数是微不足道的。它们旨在快速移动大量数据,这是该作业的副作用。更新顶点缓冲区正是他们经常和快速完成的。如果我们分别确定32个字节的点(float4位置和颜色),我相信100000个线段小于6 MB,PCIe 2.0 x16大约为8 GB/s。
在某些情况下,根据驱动程序或卡片如何处理转换,更改一个可能会导致一些矩阵乘法和重新计算其他值(包括转换,剔除和剪切平面等)。如果更改,则这不是问题这个状态,画出几千个多边形,然后重复,但是当状态经常变化时,它们将会有很大的成本。
以前解决此问题的一个很好的例子是配料的概念,最小化状态变化,因此可以在它们之间绘制更多的几何图形。这用于更有效地绘制大量的几何图形。
作为一个非常明确的例子,考虑#1的最佳情况:变换集触发器不需要额外的计算,并且驱动程序非常热情和完美地缓冲。要绘制10万株,您需要:
函数调用的开销单是要杀性能。
在另一方面,配料包括:
你做复制更多的数据,但有一个很好的机会VBO内容仍然不如复制为贵矩阵数据。另外,您可以在函数调用中节省大量的CPU时间(从200000降低到2)。这可以简化您的生活,驱动程序(它必须缓冲所有内容并检查是否有多余的呼叫,并优化和处理下载),也可能是视频卡(可能需要重新计算)。为了使它真正明确的,可视化的简单代码:
for (i = 0; i < 100000; ++i)
{
matrix = calcMatrix(i);
setMatrix(matrix);
drawLines(1, vbo);
}
(现在打开那)
好了,这是否意味着它是总是更好地烘烤到一个VBO然后绘制,而不是使用矩阵进行转换?如果我说了一些,也许是10,移动纹理四边形。计算对象的坐标,重新创建VBO,上传和绘制真的会更好吗?与在每个对象上使用矩阵平移(我优化为简单的2次加法而不是64次乘法和48次加法)然后绘制每个对象相反。 – mk12
“如果我们分别确定32个字节的点(float4的位置和颜色)”并且几乎不需要将这一点减半:vec3的位置和vec4的无符号字节颜色。此外,你应该调查[缓冲区对象流](http://www.opengl.org/wiki/Buffer_Object_Streaming),以提高性能。 –
@ Mk12你问了一个更复杂的问题。你的问题答案很简单,因为每个对象都非常小,即使你有很多对象,顶点数据也很小。一旦你有更多的对象,计算他们的头寸成本变得更加重要,上传成本也是如此。 –