4 维游戏渲染优化

发布于 2024-12-01 00:11:24 字数 3969 浏览 4 评论 0原文

最近我开始编写一个C++版本的贪食蛇4d游戏(游戏解释< /a>,游戏的 C++/openGL 版本)。我真的是一个编程初学者......所以每一条评论,甚至是对编程风格的评论都值得赞赏。

“蛇”吃掉 (6) 个立方体后,我的帧丢失了。
游戏逻辑背后的事实是,蛇存储在一个名为snake.p_list的向量中,每次蛇与食物碰撞(在程序cibo中称为),它都会向p_list添加一个新对象。 可能是游戏引擎的原因?或者您对导致丢帧的原因有其他想法?您知道如何使这些功能看起来更好吗?

好的,我运行了探查器...并且: 应用程序配置文件:

  • 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()

可能是绘图函数:(

绘图函数:

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 = tesseract_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();
    }

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 = tesseract_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();
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏尔 2024-12-08 00:11:24

如果循环中每个元素的材质属性没有改变,您可以这样做:

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();

使用 glColorMaterial 也可能比 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)

此外,这可以让您更改每个四边形(甚至每个顶点)的颜色,但仅使用一个 glBegin (GL_QUADS) / glEnd() 对而不是 24 个(这可能会产生很大的速度差异)。此外,如果所有四边形的颜色相同,您可以将对 glColor4f() 的调用放在循环之外。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文