C ++,OpenGL - 渲染大量的...茶壶

时间:2014-09-27 13:38:56

标签: c++ opengl

我是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()应该更频繁地发生?或者不经常?

2 个答案:

答案 0 :(得分:11)

你正在使用旧的,不推荐使用的OpenGL部分(称为“立即模式”),其中所有图形数据都是从每一帧从CPU发送到GPU:内部glutSolidTeapot()是代码,它可以执行类似的操作glBegin(GL_TRIANGLES)后跟了很多glVertex3f(...),最后是glEnd()。被弃用的原因是因为它是一个瓶颈。 GPU是高度并行的,并且能够同时处理多个三角形,但如果您的程序使用glVertex3f一次一个地发送顶点,则它们无法执行此操作。

您应该了解现代OpenGL API,首先创建一个“缓冲对象”并将顶点数据加载到其中 - 基本上将您的形状上传到GPU的内存一次,向上 - 前面 - 然后你可以发出大量调用,告诉GPU使用缓冲区对象中的顶点绘制三角形,而不是每次都要再次发送所有顶点。

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

对于现代风格的OpenGL,我知道

Open.gl是一个不错的教程,但我确信还有其他的。

答案 1 :(得分:1)

Wyzard是正确的,部分原因。除了您使用旧的弃用API之外,在每次绘制调用中,您一次又一次地从CPU到GPU提交所有数据,您还希望保持下降帧速率,同时多次渲染相同的几何体事实上,在使用可编程管道的同时保持这种几何渲染方法也不会给你带来太大的影响。你会在+ -40-60对象(取决于你的GPU)之后开始注意到FPS下降。你真正需要的是什么叫做批量绘图可能有不同的技术所有巫婆都暗示你使用现代OpenGL,因为我们在这里谈论数据缓冲区(在你的情况下你上传到GPU的顶点阵列)。你可以将所有几何体推到一个单独的顶点缓冲区或使用instanced rendering命令。在你的情况下,如果你所经历的是多次绘制相同的网格,第二种技术是完美的解决方案。有更复杂的技术,如indirect multiple draw命令,允许你绘制确实非常大量通过单个绘制调用可以获得不同几何形状的关系。但是对于初学者来说这些是非常先进的。无论如何,最重要的是你必须转向现代OpenGL并开始使用几何体批处理如果你想保持你的应用程序FPS高,同时绘制大量的啮合。