#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()在这两个例子中做了什么?
答案 0 :(得分:4)
在GL中,除非您专门加载新矩阵(glLoadIdentity()
或类似),否则矩阵运算会累积当前活动的矩阵。 glPushMatrix()
和glPopMatrix()
允许您将当前矩阵存储在堆栈中,并在以后检索它,允许您进行可以丢弃的修改。
在您的第一个示例中,删除glPushMatrix()
和glPopMatrix()
将导致轮换与之前的旋转连接,从而导致旋转快速加速(我会当角度超过180度时,它会最终反转并向后倾斜。
在第二个示例中,您使用glLoadIdentity()
重新初始化模型视图矩阵,因此不会有这样的转换累积。