Dre*_*all 36 opengl graphics performance vbo vertex-buffer
经过多年关于顶点缓冲对象(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():
顶点阵列(CPU端):
顶点缓冲对象(GPU端):
我使用GL_TRIANGLE_STRIP渲染了相同的数据并且得到了类似的无法区分(尽管由于额外的光栅化而预期速度较慢).如果有人想要,我也可以发布这些数字..
小智 27
优化3D渲染有很多因素.通常有4个瓶颈:
您的测试结果是错误的,因为您在最大化顶点或像素吞吐量时拥有大量CPU(和总线).VBO用于降低CPU(更少的api调用,与CPU DMA传输并行).由于您不受CPU限制,因此它们不会给您带来任何好处.这是优化101.在游戏中,例如CPU变得很珍贵,因为它需要用于AI和物理等其他东西,而不仅仅是发出大量的api调用.很容易看出,将顶点数据(例如3个浮点数)直接写入内存指针比调用将3个浮点数写入内存的函数要快得多 - 至少可以保存调用的周期.
Sla*_*a V 10
可能缺少一些东西:
这是一个疯狂的猜测,但你的笔记本电脑的卡可能完全没有这种操作(即模仿它).
你(通过将数据复制到GPU的存储器glBufferData(GL_ARRAY_BUFFER与任一GL_STATIC_DRAW或GL_DYNAMIC_DRAWPARAM)或你在存储器使用指针主(非GPU)阵列?(需要每帧将它复制,因此很慢)
您是否将索引作为另一个缓冲区通过glBufferData和GL_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
Run Code Online (Sandbox Code Playgroud)
因此,即使有10米的顶点,它也是正常的帧率,而对于glB/e,它是缓慢的.