OpenGL(三)图形变换之矩阵堆栈

来源:互联网 发布:手机店刷机软件 编辑:程序博客网 时间:2024/05/16 16:23

通过原子核动画 示例学习知识点:

<span style="font-size:18px;">#include<windows.h>#include<gl/gl.h>#include<gl/glut.h>//还是以俯视理解void SetupRC(void){glEnable(GL_DEPTH_TEST);//启动深度测试glFrontFace(GL_CCW);   //指定逆时针绕法表示多边形正面//设置窗口背景颜色为白色glClearColor(1.0f, 1.0f, 1.0f, 1.0f);}void ChangeSize(int w, int h){if (h == 0)h = 1;//设置视区尺寸glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();//设置修剪空间GLfloat fAspect = (float)w / (float)h;gluPerspective(45.0,fAspect,1.0,500.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void RenderScene(void){//绕原子核旋转的角度static float fElect1 = 0.0f;glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//设置当前操作矩阵为模型视图矩阵,并复位为单位矩阵//重置模型视图矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();//将图形沿z轴负方向移动//越往z轴负方向,视图越小glTranslatef(0.0f, 0.0f, -250.0f);//绘制红色的原子核glColor3f(1.0f,0.0f,0.0f);//该函数用于渲染一个球体。球体球心位于原点。//在OpenGL中默认的原点就是窗口客户区的中心glutSolidSphere(10.0f,15,15);    //当前绘制颜色为黑色glColor3f(0.0f,0.0f,0.0f);//保存当前的模型glPushMatrix();//绘制第一个电子//绕y轴旋转一定的角度glRotatef(fElect1,0.0f,1.0f,0.0f);//平移一段距离glTranslated(90.0f,0.0,0.0f);//向x轴正方向平移glColor3f(1.0f, 1.0f, 0.0f);//黄glutSolidSphere(6.0f,15,15);//画出电子//恢复矩阵glPopMatrix();//绘制第二个电子glPushMatrix();glRotatef(45.0f,0.0f,0.0f,1.0);glRotatef(fElect1, 0.0f, 1.0f, 0.0);glTranslatef(-70.0f,0.0f,0.0f);//向y轴负方向平移glColor3f(0.0f, 1.0f, 0.0f); //绿glutSolidSphere(6.0f,15,15);glPopMatrix();//绘制第三个电子glPushMatrix();glRotatef(-45.0f,0.0f,0.0f,1.0f);glRotatef(fElect1,0.0f,1.0f,0.0f);glTranslatef(0.0f,0.0f,60.0f); //向z轴正方向平移glColor3f(0.0f, 0.0f, 1.0f);//蓝色glutSolidSphere(6.0f,15,15);glPopMatrix();//增加旋转步长fElect1 += 10.0f;if (fElect1 > 360.0f)fElect1 = 10.0f;//交换两个缓冲区的指针//功能:防止复杂绘制时屏幕闪烁glutSwapBuffers();}void TimerFunc(int value){glutPostRedisplay();glutTimerFunc(100,TimerFunc,1);}int main(int argc, char *argv[]){//glutInit is used to initialize the GLUT libraryglutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH);glutCreateWindow("原子示例");glutDisplayFunc(RenderScene);glutReshapeFunc(ChangeSize);glutTimerFunc(500,TimerFunc,1);SetupRC();glutMainLoop();return 0;}</span>


本程序使用了透视投影,可以清楚地看到电子在旋转到远处时,体积逐渐变小,而旋转到近处时,体积有渐渐变大。
运行结果:



学习知识点:

1.矩阵堆栈(其实前面已经接触过了)

OpenGL 为模型视图矩阵和投影矩阵各维护这一个“”矩阵堆栈“”,工作方式跟我们普通堆栈一样。

我们可以吧当前矩阵压到堆栈中保存它,然后对当前矩阵进行修改,把矩阵弹出堆栈即可恢复。

使用函数如下:

void glPushMatrix(void );

void glPopMatrix(void );

函数glPushMatrix(void )用户将当前矩阵压人矩阵堆栈,常用于保存当前矩阵。

glPopMatrix常用于将最后一个矩阵弹出当前矩阵堆栈,常用于恢复当前变换矩阵原先的状态。

2:、OpenGL 维护两个栈:投影变换栈,几何变换栈。

投影: glOrtho,gluPerspective--------------------glMatrixMode(GL_PROJECTION); 

几何变 换:glTranslatef,glRotatef,glScalef--------glMatrixMode(GL_MODELVIEW); 

在调用glMatrixMode(GL_MODELVIEW)时,系统会自动将几何变换桟清空并压入单位矩阵,因此不必再调用glLoadIdentity()函数。

glMatrixMode(GL_MODELVIEWING或GL_PROJECTION);本命令执行后参数所指矩阵栈就成为当前矩阵栈,以后的矩阵栈操纵命令将作用于它。



1 0