当删除glPushMatrix()和glPopMatrix()时,OpenGL动画运行得更快

时间:2013-02-23 06:56:12

标签: opengl matrix

#include <iostream>
#include <GL/glut.h>
#include <math.h>

using namespace std;

#define WIDTH 400
#define HEIGHT 400

#include <math.h>
#define ColoredVertex(c, v) do{ glColor3fv(c); glVertex3fv(v); }while(0)

GLfloat angle = 0.0f;

void myDisplay(void)
{
     static int list = 0;
     if( list == 0 )
     {
         // 

         GLfloat
             PointA[] = { 0.5f, -sqrt(6.0f)/12, -sqrt(3.0f)/6},
             PointB[] = {-0.5f, -sqrt(6.0f)/12, -sqrt(3.0f)/6},
             PointC[] = { 0.0f, -sqrt(6.0f)/12,   sqrt(3.0f)/3},
             PointD[] = { 0.0f,    sqrt(6.0f)/4,              0};
         GLfloat
             ColorR[] = {1, 0, 0},
             ColorG[] = {0, 1, 0},
             ColorB[] = {0, 0, 1},
             ColorY[] = {1, 1, 0};

         list = glGenLists(1);
         glNewList(list, GL_COMPILE);
         glBegin(GL_TRIANGLES);
         // ABC
         ColoredVertex(ColorR, PointA);
         ColoredVertex(ColorG, PointB);
         ColoredVertex(ColorB, PointC);
         // ACD
         ColoredVertex(ColorR, PointA);
         ColoredVertex(ColorB, PointC);
         ColoredVertex(ColorY, PointD);
         // CBD
         ColoredVertex(ColorB, PointC);
         ColoredVertex(ColorG, PointB);
         ColoredVertex(ColorY, PointD);
         // BAD
         ColoredVertex(ColorG, PointB);
         ColoredVertex(ColorR, PointA);
         ColoredVertex(ColorY, PointD);
         glEnd();
         glEndList();

         glEnable(GL_DEPTH_TEST);
     }
     // 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glPushMatrix();
     glRotatef(angle, 1, 0.5, 0);
     glCallList(list);
     glPopMatrix();
     glutSwapBuffers();
}

void myIdle(void)
{
     ++angle;
     if( angle >= 360.0f )
         angle = 0.0f;
     myDisplay();
}

int main(int argc, char* argv[])
{
     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
     glutInitWindowPosition(200, 200);
     glutInitWindowSize(WIDTH, HEIGHT);
     glutCreateWindow("OpenGL window");
     glutDisplayFunc(&myDisplay);
     glutIdleFunc(&myIdle);
     glutMainLoop();
     return 0;
}

这是绘制旋转四面体的一个非常基本的例子。我不明白的是使用 glPushMatrix() glPopMatrix()。如果我删除这些代码,该程序仍然有效,但动画似乎执行速度更快。我不知道是什么导致了这种加速 我已经掏出另一个例子来弄清楚这个伎俩。我只需更改myDisplay()函数,如下所示。

void myDisplay(void){
     glEnable(GL_DEPTH_TEST);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluPerspective(75, 1, 1, 400000000);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     gluLookAt(0, 0, 200000000, 0, 0, 0, 0, 1, 0);

     static int list = 0;
     static int earthList =0;

     if(list==0){
        list = glGenLists(1);

        glNewList(list, GL_COMPILE);
        glColor3f(1.0f, 0.0f, 0.0f);
        glutSolidSphere(69600000, 20, 20);
        glEndList();
     }
     if(earthList==0){
        earthList = glGenLists(1);

        glNewList(earthList, GL_COMPILE);
        glColor3f(0.0f, 0.0f, 1.0f);
        glutSolidSphere(15945000, 20, 20);
        glEndList();
     }

     // draw a red sun
     glCallList(list);

     // draw the earth
     //glPushMatrix();
     glRotatef(day/360.0*360.0, 0.0f, 0.0f, -1.0f);
     glTranslatef(150000000, 0.0f, 0.0f);
     glCallList(earthList);

     //glPopMatrix();

     glFlush();

     glutSwapBuffers();
} 

但这一次,即使我删除了glPushMatrix()和glPopMatrix()函数,也没有任何改变。我没有看到任何区别。这真让我困惑 谁能解释一下glPushMatrix()和glPopMatrix()在这两个例子中做了什么?

1 个答案:

答案 0 :(得分:4)

在GL中,除非您专门加载新矩阵(glLoadIdentity()或类似),否则矩阵运算会累积当前活动的矩阵。 glPushMatrix()glPopMatrix()允许您将当前矩阵存储在堆栈中,并在以后检索它,允许您进行可以丢弃的修改。

在您的第一个示例中,删除glPushMatrix()glPopMatrix()将导致轮换与之前的旋转连接,从而导致旋转快速加速(我会当角度超过180度时,它会最终反转并向后倾斜。

在第二个示例中,您使用glLoadIdentity()重新初始化模型视图矩阵,因此不会有这样的转换累积。