当前位置:  开发笔记 > 编程语言 > 正文

VBO何时比"简单"OpenGL原语(glBegin())更快?

如何解决《VBO何时比"简单"OpenGL原语(glBegin())更快?》经验,为你挑选了2个好方法。

经过多年关于顶点缓冲对象(VBO)的讨论,我终于决定尝试它们(我的东西通常不是性能关键,显然......)

我将在下面描述我的实验,但总而言之,我看到"简单"直接模式(glBegin()/ glEnd()),顶点数组(CPU端)和VBO(GPU端)之间无法区分性能渲染模式.我试图理解为什么会这样,并且在什么条件下我可以期待看到VBO明显优于他们原始(双关语)的祖先.

实验细节

对于实验,我生成了一个具有大量点的(静态)3D高斯云.每个点都有与之关联的顶点和颜色信息.然后我在连续的帧中围绕云旋转相机,这是一种"轨道"行为.同样,这些点是静态的,只有眼睛移动(通过gluLookAt()).数据在任何渲染之前生成一次并存储在两个数组中以用于渲染循环.

对于直接渲染,整个数据集在单个glBegin()/ glEnd()块中呈现,其中包含一个循环,每个循环包含glColor3fv()和glVertex3fv().

对于顶点数组和VBO渲染,整个数据集使用单个glDrawArrays()调用进行渲染.

然后,我只需在紧凑的循环中运行一分钟左右,并使用高性能计时器测量平均FPS.

表现结果##

如上所述,我的台式机(XP x64,8GB RAM,512 MB Quadro 1700)和笔记本电脑(XP32,4GB RAM,256 MB Quadro NVS 110)的性能难以区分.然而,它确实按照预期的点数进行了扩展.显然,我也禁用了vsync.

笔记本电脑运行的具体结果(使用GL_POINTS渲染):

在glBegin()/ glEnd():

1K分 - > 603 FPS

10K分 - > 401 FPS

100K分 - > 97 FPS

1M点 - > 14 FPS

顶点阵列(CPU端):

1K分 - > 603 FPS

10K分 - > 402 FPS

100K分 - > 97 FPS

1M点 - > 14 FPS

顶点缓冲对象(GPU端):

1K分 - > 604 FPS

10K分 - > 399 FPS

100K分 - > 95 FPS

1M点 - > 14 FPS

我使用GL_TRIANGLE_STRIP渲染了相同的数据并且得到了类似的无法区分(尽管由于额外的光栅化而预期速度较慢).如果有人想要,我也可以发布这些数字..

问题(S)

是什么赋予了?

我需要做些什么才能实现VBO承诺的性能提升?

我错过了什么?

小智.. 27

优化3D渲染有很多因素.通常有4个瓶颈:

CPU(创建顶点,APU调用,其他一切)

总线(CPU < - > GPU传输)

顶点(固定函数管道执行时的顶点着色器)

像素(填充,片段着色器执行和rops)

您的测试结果是错误的,因为您在最大化顶点或像素吞吐量时拥有大量CPU(和总线).VBO用于降低CPU(更少的api调用,与CPU DMA传输并行).由于您不受CPU限制,因此它们不会给您带来任何好处.这是优化101.在游戏中,例如CPU变得很珍贵,因为它需要用于AI和物理等其他东西,而不仅仅是发出大量的api调用.很容易看出,将顶点数据(例如3个浮点数)直接写入内存指针比调用将3个浮点数写入内存的函数要快得多 - 至少可以保存调用的周期.



1> 小智..:

优化3D渲染有很多因素.通常有4个瓶颈:

CPU(创建顶点,APU调用,其他一切)

总线(CPU < - > GPU传输)

顶点(固定函数管道执行时的顶点着色器)

像素(填充,片段着色器执行和rops)

您的测试结果是错误的,因为您在最大化顶点或像素吞吐量时拥有大量CPU(和总线).VBO用于降低CPU(更少的api调用,与CPU DMA传输并行).由于您不受CPU限制,因此它们不会给您带来任何好处.这是优化101.在游戏中,例如CPU变得很珍贵,因为它需要用于AI和物理等其他东西,而不仅仅是发出大量的api调用.很容易看出,将顶点数据(例如3个浮点数)直接写入内存指针比调用将3个浮点数写入内存的函数要快得多 - 至少可以保存调用的周期.



2> Slava V..:

可能缺少一些东西:

    这是一个疯狂的猜测,但你的笔记本电脑的卡可能完全没有这种操作(即模仿它).

    你(通过将数据复制到GPU的存储器glBufferData(GL_ARRAY_BUFFER与任一GL_STATIC_DRAWGL_DYNAMIC_DRAWPARAM)或你在存储器使用指针主(非GPU)阵列?(需要每帧将它复制,因此很慢)

    您是否将索引作为另一个缓冲区通过glBufferDataGL_ELEMENT_ARRAY_BUFFERparams 传递?

如果完成这三件事,性能提升很大.对于Python(v/pyOpenGl),它在大于100个元素的数组上快大约1000倍,C++快5倍,但在阵列50k-10m顶点上.

以下是我对c ++(Core2Duo/8600GTS)的测试结果:

 pts   vbo glb/e  ratio
 100  3900  3900   1.00
  1k  3800  3200   1.18
 10k  3600  2700   1.33
100k  1500   400   3.75
  1m   213    49   4.34
 10m    24     5   4.80

因此,即使有10米的顶点,它也是正常的帧率,而对于glB/e,它是缓慢的.

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有