之前写的关于VBO与Displaylists的讨论不是很详细,现在重新整理一下,不过需要注意的我的测试结果是在没做view frustum culling的前提下给出的。
关于Display List 和 VBO
Display List
把OpenGL命令进行编译,保存在显卡上,并且允许保存Vertex Array
优点:
将图形绘制和数据管理交给OpenGL进行管理,给OpenGL带来更多优化的机会,而且Display lists可以放在显卡中,避免了数据在总线上的传输而带来的瓶颈。另外,数据可以通过DMA传递到显卡进行绘制,减少了CPU调用,并且可以一次性传输成批的数据和命令。
缺点:
存储过多的OpenGL命令会加重内存负担(这个还需要测试具体数字)
编译时间太长
仅限于静态Geometry(即每个display list绘制的三角形列表不会改变)
测试发现,预先分配Display Lists的长度变化不会对速度造成影响,前提是每帧绘制的三角形数目不会超过一个瓶颈。这样说来,预先创建的Display lists数目只要没有超过系统瓶颈(?),影响速度的是实际使用的Display lists个数,或者说每帧绘制的三角形个数。
对比发现,VBO的效率会随着VBO实际使用数目的增加而急剧下降。尤其是VBOs所占用的空间超过显存时,存在内存和现存之间的数据传输,从而会带来瓶颈。
使用display lists每秒种绘制的三角形数目最大可以接近
Vertex Array
批量传输和绘制数据,减少单个绘制命令的调用参数,CPU和GPU之间的瓶颈,在OpenGL程序中已经不推荐使用。
VBO
VBO是包含在OpenGL1.5里面的一个扩展,它的设计旨在结合immediate mode,displaylist和vertex array的优点,并且避开了他们各自的一些不足。最让人激动的是,数据既可以完全存入VBO交给OpenGL进行管理,同时也提供了一种更加另外的功能,在不影响数据传输效率的情况下,动态改变VBO的数据。
令我同时也令不少人不解的是,在测试中大家发现使用VBO并没有带来预期的性能上的大幅提升,我在自己的地形渲染算法中反复测试发现使用display lists比使用VBO更能带来效率上的大幅提高。
在我的测试中,当每帧绘制的三角形数据都较少时,使用VBOs和Display lists都能带来速度上的提高,但是当每帧绘制的三角形数目逐渐增加时,VBOs的速度会急剧下降,而Display lists则保持稳定,知道达到令一个数据量级上的三角形数目才会使速度降低。
需要研究的问题:
第一:Display lists使用效率都与那些因素有关?
每个list绘制的三角形数目,同时绘制的Lists的总数
第二:影响VBO速度下降的主要因素?
每个VBO存储的三角形数目,同时绘制的VBOS的总数,帧存的大小
第三:分析Display lists性能超过VBO的原因?
VBO在每帧绘制时候都有状态转变(state-change),导致CPU过多的干涉和数据的重新传输?
二者在地层实现上存在的差异?是否新的显卡对VBO的支持更好一些?
现有硬件对VBO的支持:hardware-support 和 software-support
第四:看来需要重新设计一下vbo array 和 display list array的调度算法,原来的FIFO效率不够高,考虑使用LRU算法。总之要保证在每次使用的CHUNCK个数不太多时,尽量减少不必要的VBO或DISPLAY LIST的创建和维护。尤其是在使用VBO时,每次创建的VBO个数太多,会造成显存不足,从而大大影响系统性能。
第四:关于内存消耗
使用VBO耗费内存最大,其次是displaylist,最后是immediate
使用nvidia gDEBugger测试发现,使用display list耗费的帧存是VBO耗费的一半.
关键问题:当地形数据量巨大时,绘制同样细节程度的地形,为了不重新生成新的VBO而维持的VBO数组个数会急剧增大,进而导致AGP 内存占用量增加。当AGP内存不够用的时候,使用VBO或Display list的性能优势就体现不出来了。
不过通过测试发现,使用动态VBO在速度上还是优于immediate mode.
注意:在显示设置中关闭垂直同步,不然最高FPS不会超过最大刷新率!!!
FOLLOW_MODE与FLY_MODE的测试结果不同,前者没有做裁减,所以所有的三角形都要画,这样使用VBO和不使用VBO效率差别不大。但在FLY_MODE下,VBO的性能明显要高于不使用非VBO。