假设我有5个实体(对象)和一个方法Render().每个实体都需要在缓冲区中设置自己的顶点进行渲染.
以下哪两种选择更好?
>使用glGenBuffer创建的一个大的预分配缓冲区,每个实体将使用(缓冲区的id作为参数传递给Render方法),通过glBufferSubData将其顶点写入缓冲区.
>每个实体都创建并使用自己的缓冲区.
如果一个大缓冲区更好,我如何使用适当的着色器和所有内容正确渲染此缓冲区中的所有顶点(来自所有实体)?
解决方法
只要具有一定的尺寸,具有多个VBO就可以了.你想要避免的是有很多小的绘制调用,并且必须非常频繁地绑定不同的缓冲区.
缓冲区必须有多大以避免过多的开销,这取决于很多因素,甚至几乎不可能给出经验法则.发挥作用的因素包括:
>硬件性能特征.
>驾驶员效率.
>相对于片段数(三角形大小)的顶点数.
>着色器的复杂性.
通常,保留通常在单个顶点缓冲区中同时绘制的相似/相关对象是有意义的.
将所有内容放在一个缓冲区中似乎极端,实际上可能会产生不利影响.假设您有一个大的“世界”,您只在任何给定的帧中渲染一个小子集.如果你走到极端,一个巨大的缓冲区中包含所有顶点,那么每次绘制调用都需要GPU访问该缓冲区.根据体系结构以及缓冲区的分配方式,这可能意味着:
>尝试将缓冲区保留在专用的GPU内存(例如VRAM)中,如果它太大,可能会出现问题.
>将内存映射到GPU地址空间.
>固定/连接内存.
如果上述任何一个需要应用于一个非常大的缓冲区,但最终只使用它的一小部分来渲染一个帧,那么这些操作就会有很大的浪费.在具有VRAM的系统中,它还可以防止其他分配(如纹理)适合VRAM.
如果使用只能访问参数给出的缓冲区子集的调用来完成渲染,例如glDrawArrays()或glDrawRangeElements(),则驱动程序可能会避免使整个缓冲区GPU可访问.但我不一定指望这种情况发生.