我试图在3D空间中的随机位置显示尽可能多的纹理四边形。根据我的经验到目前为止,我甚至无法显示其中的几千个,而不会将fps显着低于30(我的相机移动脚本变得迟钝)。
现在我正在学习古老的教程。初始化OpenGL后:
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0, 0, 0, 0);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
我设定了观点和观点:
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
然后我加载一些纹理:
glGenTextures(TEXTURE_COUNT, &texture[0]);
for (int i...){
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[0]->w,TextureImage[0]->h,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->pixels);
}
最后我使用:
绘制我的GL_QUADSglBindTexture(GL_TEXTURE_2D, q);
glTranslatef(fDistanceX,fDistanceZ,-fDistanceY);
glBegin(GL_QUADS);
glNormal3f(a,b,c);
glTexCoord2f(d, e); glVertex3f(x1, y1, z1);
glTexCoord2f(f, g); glVertex3f(x2, y2, z2);
glTexCoord2f(h, k); glVertex3f(x3, y3, z3);
glTexCoord2f(m, n); glVertex3f(x4, y4, z4);
glEnd();
glTranslatef(-fDistanceX,-fDistanceZ,fDistanceY);
我发现所有代码都非常自我解释。不幸的是,据我所知,这种做事方式已被弃用。我在互联网上读了一些关于PBO和vertexArrays的模糊的东西,但我没有找到关于如何使用它们的任何教程。我甚至不知道这些物体是否适合实现我在这里尝试做的事情(屏幕上有十亿个四边形而没有滞后)。也许这里的任何人都可以给我一个明确的建议,我应该用什么来达到结果呢?如果你碰巧还有一分钟的业余时间,你能不能给我一些关于如何使用这些功能的简短摘要(就像我对上面弃用的那些功能一样)?
答案 0 :(得分:8)
也许这里有人可以给我一个明确的建议,我应该用什么来达到结果?
什么是“结果”?你还没有很好地解释你想要完成的是什么。你所说的只是你想要绘制很多纹理四边形。你想用那些纹理四边形做什么做?
例如,在给定相同像素数据的情况下,您似乎创建了相同的纹理,具有相同的宽度和高度。但是您将它们存储在不同的纹理对象中。 OpenGL不知道它们包含相同的数据。因此,在渲染四边形时,您会花费大量时间不必要地交换纹理。
如果您只是随机抽取它们来测试性能,那么问题就毫无意义了。这样的测试毫无意义,因为它们完全是人为的。他们只测试这种人为场景,每次渲染四边形时都会改变纹理。
在不知道您最终要渲染的内容的情况下,我唯一能做的就是提供一般性能建议。按顺序(即:在你做后面的事情之前做第一次):
停止更改每个四边形的纹理。您可以在同一纹理中将多个图像打包在一起,然后只使用一次glBindTexture
调用一次渲染使用该纹理的所有四边形。四边形的纹理坐标指定它使用的纹理中的哪个图像。
停止使用glTranslate
定位每个四边形。您可以使用它来定位四边形组,但您应该自己进行数学计算四边形的顶点位置。一旦glTranslate
次呼叫消失,您就可以在一对glBegin/glEnd
对的空间内放置多个四边形。
假设您的四边形是静态的(模型空间中的固定位置),请考虑使用buffer object来存储和render with您的四边形数据。
我在互联网上阅读了一些关于PBO和vertexArrays的模糊内容,但我没有找到任何关于如何使用它们的教程。
您是否尝试过具有OpenGL Wiki的pretty good list of tutorials(以及有关OpenGL的一般信息)?为了充分披露,我确实写了其中一个。
答案 1 :(得分:7)
我听说,在现代游戏中,毫米的多边形是实时渲染的
实际上它数以百万计。我认为你是德国人:“Milliarde”用英语翻译成“十亿”。
现在我正在学习古老的教程。
这是你的主要问题。当代OpenGL应用程序不使用古老的渲染方法。您正在使用立即模式,这意味着您将通过几个函数调用来提交单个顶点。这是非常低效的。现代应用程序(如游戏)可以达到高三角计数,因为它们不会浪费CPU时间来调用尽可能多的函数,它们不会浪费CPU→GPU带宽和数据流。
要实现实时渲染的高三角形数量,必须将所有几何数据放在“快速存储器”中,即位于图形卡的RAM中。 OpenGL为此提供的技术称为“顶点缓冲对象”。使用VBO,您可以使用单个绘图调用(glDrawArrays,glDrawElements及其亲属)绘制大批几何体。
在完成几何体之后,你必须对GPU很好。如果经常切换纹理或着色器,GPU不喜欢它。切换纹理使高速缓存的内容无效,切换着色器意味着停止GPU管道,但更糟糕的是,这意味着使执行路径预测统计无效(GPU统计着色器的哪些执行路径最有可能被执行)以及它展示的内存访问模式,用于迭代优化着色器执行。