OpenGL的glPushMatrix()和glPopMatrix()矩阵栈顶操作函数详解
来源:互联网 发布:mysql 查看表空间大小 编辑:程序博客网 时间:2024/05/18 06:20
OpenGL中图形绘制后,往往需要一系列的变换来达到用户的目的,而这种变换实现的原理是又通过矩阵进行操作的。opengl中的变换一般包括视图变换、模型变换、投影变换等,在每次变换后,opengl将会呈现一种新的状态(这也就是我们为什么会成其为状态机)。
有时候在经过一些变换后我们想回到原来的状态,就像我们谈恋爱一样,换来换去还是感觉初恋好,怎么办?强大的opengl就帮我们提供了两个函数:giPushMatrix()和glPopMatrix();
首先我们要知道,对于矩阵的操作都是对于矩阵栈的栈顶来操作的。当前矩阵即为矩阵栈的栈顶元素,而对当前矩阵进行平移、旋转等的变换操作也同样是对栈顶矩阵的修改。所以我们在变换之前调用giPushMatrix()的话,就会把当前状态压入第二层,不过此时栈顶的矩阵也与第二层的相同。
当经过一系列的变换后,栈顶矩阵被修改,此时调用glPopMatrix()时,栈顶矩阵被弹出,且又会恢复为原来的状态。
函数的作用过程可以用下图描述,更为直观。
在opengl场景中一般存在多种矩阵变换操作,而控制这些操作的命令主要用到
glMatrixMode(GLenum mode);
作用:用于指定用哪个矩阵作为当前矩阵,mode用于指定哪一种矩阵栈是其后矩阵操作的目标。mode可取:
GL_MODELVIEW: 把其后的矩阵操作施加于造型视图矩阵栈。(默认)
GL_PROJECTION: 把其后的矩阵操作施加于投影矩阵栈。
GL_TEXTURE: 把其后的矩阵操作施加于纹理矩阵栈。
注意上述三种模式分别对应了三种矩阵栈。
所以在场景中存在多种矩阵变换时,glPushMatrix()和glPopMatrix()一般情况下也要结合glMatrixMode(GLenum mode)运用,系统才知道具体操作的是哪个矩阵栈。
注意:
摄像机矩阵和模型矩阵用的是同一个矩阵,就是GL_MODELVIEW (model是模型搜索矩阵,view是摄像机矩阵,GL_MODELVIEW里保存的是这两个矩阵的积)。所以选择GL_MODELVIEW之后直接用glTranslate,glRotate之类的就行。
其实摄像机和模型矩阵本质上是一回事(这也是为什么OpenGL把这两个矩阵放在一起保存的原因),因为比如把整个世界向y+方向移动10跟把摄像机向y-方向移动10是等价的。旋转也是一样。
虽然矩阵里可以保存任何变换,但按照OpenGL的概念,model和view矩阵里只能保存平移,旋转和缩放;project矩阵里只能保存投影矩阵,viewport矩阵里只能保存二维平移和缩放。这样来看把model和view放在一起是合理的。他们之间的区别纯粹是人为的。
附上代码例子:
1 #include <stdlib.h> 2 #include "include\glut.h" 3 4 static int year = 0, day = 0; 5 6 void init(void) 7 { 8 glClearColor (0.0, 0.0, 0.0, 0.0); 9 glShadeModel (GL_FLAT);10 }11 12 void display(void)13 {14 glClear (GL_COLOR_BUFFER_BIT);15 glColor3f (1.0, 1.0, 1.0);16 17 glPushMatrix();18 {19 glutWireSphere(1.0, 20, 16); /* draw sun */20 glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);21 22 glTranslatef (2.0, 0.0, 0.0); //把坐标原点变换位置23 24 glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);25 glutWireSphere(0.2, 10, 8); /* draw smaller planet */26 }27 glPopMatrix();28 29 glutSwapBuffers();30 }31 32 void reshape(int w, int h)33 {34 glViewport (0, 0, (GLsizei) w, (GLsizei) h);35 glMatrixMode (GL_PROJECTION);36 glLoadIdentity ();37 gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);38 39 glMatrixMode(GL_MODELVIEW);40 glLoadIdentity();41 gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);42 }43 44 void keyboard(unsigned char key, int x, int y)45 {46 switch (key) {47 case 'd':48 day = (day + 10) % 360;49 glutPostRedisplay();50 break;51 case 'D':52 day = (day - 10) % 360;53 glutPostRedisplay();54 break;55 case 'y':56 year = (year + 5) % 360;57 glutPostRedisplay();58 break;59 case 'Y':60 year = (year - 5) % 360;61 glutPostRedisplay();62 break;63 case 27:64 exit(0);65 break;66 default:67 break;68 }69 }70 71 int main(int argc, char** argv)72 {73 glutInit(&argc, argv);74 glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);75 glutInitWindowSize (500, 500);76 glutInitWindowPosition (100, 100);77 glutCreateWindow (argv[0]);78 79 init();80 glutDisplayFunc(display);81 glutReshapeFunc(reshape);82 glutKeyboardFunc(keyboard);83 glutMainLoop();84 return 0;85 }
运行结果:
- OpenGL的glPushMatrix()和glPopMatrix()矩阵栈顶操作函数详解
- opengl 中glpushmatrix和glpopmatrix函数的个人理解
- OpenGL中glPushMatrix和glPopMatrix的原理
- OpenGL中glPushMatrix和glPopMatrix的原理
- 《高效学习OpenGL》之 操作矩阵堆栈 glPushMatrix(),glPopMatrix()
- opengl中的glpushmatrix和glpopmatrix
- opengl中glPushMatrix() 和 glPopMatrix()用法的真正意义
- OpenGL ES之glPushMatrix, glPopMatrix函数
- glPushMatrix和glPopMatrix的作用
- glPushMatrix和glPopMatrix的作用
- glPushMatrix和glPopMatrix的作用
- glPushMatrix()和glPopMatrix()的作用
- glPushMatrix()和glPopMatrix()的作用
- Opengl中的glTranslatef、glPushMatrix和glPopMatrix
- opengl入门记录--glPushMatrix和glPopMatrix原理
- glPushMatrix()和glPopMatrix()以及glLoadIdentity()的理解
- glPushMatrix和glPopMatrix的作用 …
- glLoadIdentity(),glPushMatrix(),glPopMatrix()和glMatrixMode()的作用
- 欢迎使用CSDN-markdown编辑器
- JavaScript与JScript的区别
- HDU 1260
- 自绘控件(有疑问)
- 空字符对浮动的影响
- OpenGL的glPushMatrix()和glPopMatrix()矩阵栈顶操作函数详解
- 9月5日云栖精选夜读:智能语音交互:阿里的研究和实践
- spring MVC 拦截
- Codeforces 160E Buses and People【二分+线段树+离散化】
- 父类引用指向子类对象
- Tapestry(一):结合jetty开发Tapestry3项目
- Binary Tree Longest Consecutive Sequence
- uboot 编译报错
- HDU 2955