开发者

4 Dimensional Game Render Optimizazion

recently I started to program a C++ version of the game Snake 4d (Game explanation, C++/openGL version of the game). I'm really a programming beginner... so every comment, even to the programming style is appreciated.

I have a frame drop after the "snake" eated (6) cubes.

The game logic stays behind the fact that the snake is stored in a vector called snake.p_list, every time the snake collide with food (called in the program cibo), it will be added a new object to the p_list. Could be due to the game engine? or maybe you have an other idea of what can cause the frame drop? do you have any idea how to make those functions look better?

ok I runned the profiler... and : application profile:

  • 23.0% 23.0% GeForceGLDriver glrCompExecuteKernel
  • 19.3% 19.3% GeForceGLDriver gldCopyTexSubImage
  • 5.4% 5.4% GeForceGLDriver gldFinish
  • 5.3% 5.3% GLEngine gleUpdateLightRGBASumsUnconditional
  • 3.9% 3.9% GLEngine gleUpdateDeferredState
  • 2.1% 2.1% GLEngine gleGetVertexSubmitFuncObjectAndKey
  • 2.1% 2.1% GeForceGLDriver gldUpdateDispatch
  • 1.8% 1.8% 4dimensions MyGLBox::paintGL()

is probably the drawing function :(

drawing function :

for(p = p_list.begin();p != p_list.end(); p++){
    Polygon4 p1 = *p;

    if(prj == PRJ_2D){
        //parameters to project in 2d
        double angle = PI/4;
        double Cx = 0.;
        double Lx = 50./2;
        double p_cam = 10.;
        //actually simply fits...
        for(int i = 0; i < 32; ++i){
            V4 v1_2d = p1.v_list[p1.e_list[i].e[0]];
            V4 v2_2d = p1.v_list[p1.e_list[i].e[1]];

            double x1 = Cx + (Lx*v1_2d[c_i])/(p_cam*2*tan(angle));
            double y1 = Cx + (Lx*v1_2d[c_j])/(p_cam*2*tan(angle));
            double x2 = Cx + (Lx*v2_2d[c_i])/(p_cam*2*tan(angle));
            double y2 = Cx + (Lx*v2_2d[c_j])/(p_cam*2*tan(angle));

            float mat_specular[] ={0.1,0.1,0.1,0.1};
            glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

            GLfloat mat_shininess[] = { 0 };
            glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

            GLfloat mat_color[] = {p1.color.r,p1.color.g,p1.color.b,0.5};
            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);

            glBegin(GL_LINES);
            glVertex3f(x1,y1,0.);
            glVertex3f(x2,y2,0.);
            glEnd();


        }
    }

    else{

        for(vertex = p1.v_list.begin(); vertex != p1.v_list.end(); vertex++){
            v3d = cam.prj_p(*vertex);
            tesseract_prj.v_list.push_back(v3d);
        }
        tesseract_prj.e_list = p1.e_list;
        tesseract_prj.f_list = p1.f_list;

        //edges render
        for(int i = 0; i <32; ++i){
            V3 v1 = tesseract_prj.v_list[tesseract_prj.e_list[i].e[0]];
            V3 v2 = tesseract_prj.v_list[tesseract_prj.e_list[i].e[1]];
            float mat_specular[] ={0.1,0.1,0.1,0.1};

          glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

            GLfloat mat_shininess[] = { 0 };
            glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

            GLfloat mat_color[] = {0.0,0.0,0.0,1.};
            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);

            glBegin(GL_LINES);
            glVertex3f(v1[0],v1[1],v1[2]);
            glVertex3f(v2[0],v2[1],v2[2]);
            glEnd();
        }
        //faces render

        for(int i = 0; i<24; ++i){
            V3 v1 = tesse开发者_开发百科ract_prj.v_list[tesseract_prj.f_list[i].f[0]];
            V3 v2 = tesseract_prj.v_list[tesseract_prj.f_list[i].f[1]];
            V3 v3 = tesseract_prj.v_list[tesseract_prj.f_list[i].f[2]];
            V3 v4 = tesseract_prj.v_list[tesseract_prj.f_list[i].f[3]];

            GLfloat mat_color[] = {p1.color.r,p1.color.g,p1.color.b,0.5};
            glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);

            glBegin(GL_QUADS);
            glVertex3f(v1[0],v1[1],v1[2]);
            glVertex3f(v2[0],v2[1],v2[2]);
            glVertex3f(v3[0],v3[1],v3[2]);
            glVertex3f(v4[0],v4[1],v4[2]);
            glEnd();
        }
        tesseract_prj.e_list.clear();
        tesseract_prj.v_list.clear();
    }


If material properties don't change for each element in a loop you can do this instead:

float mat_specular[] ={0.1,0.1,0.1,0.1};
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);

GLfloat mat_shininess[] = { 0 };
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

GLfloat mat_color[] = {0.0,0.0,0.0,1.};
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mat_color);

glBegin(GL_LINES);
    for(int i = 0; i <32; ++i)
    {
        glVertex3f(v1[0],v1[1],v1[2]); //note: drawing multiple lines with one
        glVertex3f(v2[0],v2[1],v2[2]); //glBegin/glEnd pair will be much faster
    }
glEnd();

Using glColorMaterial may also be faster than glMaterialfv:

glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL); //now  ambient and diffuse is set by glColor4f()

glBegin(GL_QUADS);
for(int i = 0; i<24; ++i)
{
    glColor4f(r,g,b,0.5);
    glVertex3f(v1[0],v1[1],v1[2]);
    glVertex3f(v2[0],v2[1],v2[2]);
    glVertex3f(v3[0],v3[1],v3[2]);
    glVertex3f(v4[0],v4[1],v4[2]);
}
glEnd();

glDisable(GL_COLOR_MATERIAL);//now use glMaterialfv() for ambient and diffuse (optional)

Also, this lets you change the color for each quad (or even each vertex) but use only one glBegin(GL_QUADS) / glEnd() pair instead of 24 (which could make a big speed difference). Furthermore, you can put the call to glColor4f() outside of the loop if the color was the same for all the quads.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜