哪一个是编写这个gl代码的正确方法

时间:2015-01-14 11:38:18

标签: c++ opengl frame-rate

我一直在用opengl和处理纹理做一些实验。 在我的实验中,我有一个随机生成的(int)数组

 int mapskeleton[300][300];

然后我有了自己的obj文件加载器来加载带纹理的obj

m2d wall,floor;//i initialize and load those files at start

用于记录我使用的渲染时间的统计信息

bool Once = 1; 
int secs = 0;

现在在渲染代码中我做了我的实验

    //  Code A: Benchmarked on radeon 8670D   
    //  Takes 232(average) millisecs for drawing 300*300 tiles

if(Once)
secs = glutGet(GLUT_ELAPSED_TIME);

for(int i=0;i<mapHeight;i++){
    for(int j=0;j<mapWidth;j++){
        if(mapskeleton[j][i] == skel_Wall){
            glBindTexture(GL_TEXTURE_2D,wall.texture);
            glPushMatrix();
            glTranslatef(j*10,i*10,0);      
            wall.Draw();//Draws 10 textured triangles
            glPopMatrix();
        }
        if(mapskeleton[j][i] == skel_floor){
            glBindTexture(GL_TEXTURE_2D,floor.texture);
            glPushMatrix();
            glTranslatef(j*10,i*10,0);      
            floor.Draw();//Draws 2 textured triangles
            glPopMatrix();
        }           

    }
}
if(Once){
secs = glutGet(GLUT_ELAPSED_TIME)-secs;
printf("time taken for rendering %i msecs",secs)
Once = 0;
}

和其他代码是

    //  Code B:    Benchmarked on radeon 8670D   
    //  Takes 206(average) millisecs for drawing 300*300 tiles


if(Once)
secs = glutGet(GLUT_ELAPSED_TIME);  

glBindTexture(GL_TEXTURE_2D,floor.texture);

for(int i=0;i<mapHeight;i++){
    for(int j=0;j<mapWidth;j++){
        if(mapskeleton[j][i] == skel_floor){
            glPushMatrix();
            glTranslatef(j*10,i*10,0);      
            floor.Draw();
            glPopMatrix();
        }
    }
}
glBindTexture(GL_TEXTURE_2D,wall.texture);

for(int i=0;i<mapHeight;i++){
    for(int j=0;j<mapWidth;j++){
        if(mapskeleton[j][i] == skel_Wall){
            glPushMatrix();
            glTranslatef(j*10,i*10,0);      
            wall.Draw();
            glPopMatrix();
        }
    }
}   
if(Once){
secs = glutGet(GLUT_ELAPSED_TIME)-secs;
printf("time taken for rendering %i msecs",secs)
Once = 0;
}

对我来说,代码A看起来很好用一个人(初学者)查看代码。但基准测试说不同。 我的gpu似乎喜欢代码B.我不明白为什么代码B花费更少的时间来渲染?

2 个答案:

答案 0 :(得分:2)

对OpenGL状态的改变通常很昂贵 - 驱动程序和/或GPU数据结构和高速缓存可能变得无效。在您的情况下,问题的变化是绑定不同的纹理。在代码B中,您要执行两次。在代码A中,您可以轻松地执行数千次。

编程OpenGL渲染时,您通常需要为设置A设置管道,渲染需要设置A的所有内容,重新设置设置B的管道,渲染需要设置B的所有内容,依此类推

答案 1 :(得分:1)

@Angew介绍了为什么一个选项比另一个选项更有效。但有一点很重要,需要非常明确地说明。根据您的问题文本,特别是在这里:

  

用于记录渲染时间的统计信息

     

我的gpu似乎喜欢代码B

您似乎试图测量渲染/ GPU性能。

您并非全都在测量GPU性能!

您可以测量设置状态和进行绘制调用的时间。 OpenGL允许GPU从CPU上执行的代码异步操作。在进行(大多数)OpenGL调用时,您应该记住的是,您提交工作到GPU以便以后执行。当GPU完成这项工作时,并不知道。最明确的是(除了在速度关键代码中要避免的极少数调用之外)在调用返回时不会发生。

您在代码中测量的内容纯粹是用于进行这些调用的 CPU开销。这包括您自己的代码中发生的事情,以及处理调用和准备工作以便以后提交到GPU的驱动程序代码中发生的事情。

我并不是说测量没用。最小化CPU开销非常重要。你只需要非常了解你实际测量的是什么,并确保你得出正确的结论。