2014-09-27 107 views
1

我在OpenGL编程方面很新颖。我的目标是设置面向对象的图形编程,我可以自豪地说我已经取得了一些进展。现在我有不同的问题。C++,OpenGL - 渲染大量的茶壶

可以说我们有工作程序什么可以使一个,两个或许多旋转茶壶。我通过在我的课堂内使用列表来做到这一点。绘图功能的原始代码是在这里:

void Draw(void) 
{ 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glMatrixMode(GL_MODELVIEW); 
glPushMatrix(); 

for(list<teapot>::iterator it=teapots.begin();it!=teapots.end();it++){ 
glTranslatef(it->pos.x,it->pos.y,it->pos.z); 
glRotatef(angle,it->ang.x,it->ang.y,it->ang.z); 
glutSolidTeapot(it->size); 
glRotatef(angle,-it->ang.x,-it->ang.y,-it->ang.z); 
glTranslatef(-it->pos.x,-it->pos.y,-it->pos.z); 
} 
glPopMatrix(); 
glutSwapBuffers(); 
} 

一切都很好,但是当我画大量的茶壶 - 两行说,128 - 我的FPS数下降。我不知道,如果这只是硬件限制,或者我做错了什么?也许glPushMatrix()和glPopMatrix()应该更频繁地发生?或更少?

+0

GLUT使用即时模式渲染,这对于性能来说很糟糕。改用VBOs,或者至少首先将茶壶呈现在显示列表中。 – 2014-09-27 13:59:43

回答

11

你使用OpenGL的一个古老的,过时的部分(称为“直接模式”),其中所有的图形数据从CPU发送到GPU每一帧:内glutSolidTeapot()是代码,不会后跟类似glBegin(GL_TRIANGLES)大量glVertex3f(...),最后glEnd()。弃用的原因是因为它是一个瓶颈。 GPU是高度并行的,并且能够同时处理许多三角形,但是如果您的程序一次只发送一个顶点,则它们不能这样做,其中的glVertex3f

你应该了解现代的OpenGL API,在其中您可以通过创建一个“缓冲区对象”和你的顶点数据加载到它开始 - 基本上传你的形状到GPU的内存一次,先期 - 然后您可以发出大量调用,告诉GPU使用该缓冲区对象中的顶点绘制三角形,而不必每次都发送所有顶点。

(不幸的是,这意味着你将无法使用glutSolidTeapot(),因为它引用了即时模式,并不知道如何为缓冲区对象生成顶点数据,但我相信你可以找到一个茶壶模型在网上某处。)

Open.gl是一个体面的教程,我知道现代风格的OpenGL,但我敢肯定也有其他人。

+1

+1,因为我喜欢茶壶。部分原因是你写的是正确的。 – 2014-09-27 14:12:26

+0

谢谢你!现在我明白生成一个茶壶不是很好开始...;) – 2014-09-27 16:33:15

+1

好吧,把茶壶作为测试没有错。只需将其放入VBO中,而不是使用'glutSolidTeapot'在即时模式下绘制它。 – Wyzard 2014-09-27 16:37:33

1

由于您正在使用旧的弃用API,因此在每次绘制调用时,您一次又一次地将所有数据从CPU提交到GPU,您还希望在渲染相同几何体时保持下降帧率因此实际上,在使用可编程管道时保持这种几何体渲染方法也不会让您获益。您将在+ - 40-60个物体(取决于您的GPU)之后开始注意到FPS已经下降。您真正需要的是称为批处理drawing.the批处理绘图可能有不同的技术,所有的女巫暗示你使用现代的OpenGL,因为我们在这里谈论的数据缓冲区(您上传到GPU的情况下的顶点阵列)。您可以将所有的几何体推入单个顶点缓冲区或使用instanced rendering命令。在您的情况下,如果您所有人都在多次绘制相同的网格,则s第二种技术是完美的解决方案。还有更复杂的技术,如indirect multiple draw命令,它们允许您通过一次绘制调用确实绘制非常大量的不同几何图形。但对于初学者来说,这些技术相当先进。总而言之,底线是您必须移动到现代的OpenGL,并开始使用几何配料,如果你想保持你的应用程序FPS高,同时绘制大量的网格。