首页 > 编程知识 正文

gltranslatef函数(opengl渲染原理)

时间:2023-05-06 16:14:40 阅读:75843 作者:102

用OpenGL绘制图形后,往往需要一系列的变换来实现用户的目的,该变换的实现原理由矩阵操作。 opengl中的变换通常包括视图变换、模型变换和投影变换,每次变换时opengl都是新状态。 所以,成为状态机。

有时经过一些变换,我们想恢复到原来的状态。 就像我们在恋爱一样,即使交换也觉得慷慨的池子很好。 我该怎么办? 强大的opengl为我们提供了两个函数: giPushMatrix (和glPopMatrix )。

首先,需要知道对矩阵的操作都是对矩阵堆栈的堆栈顶部进行的。 当前矩阵是矩阵堆栈的堆栈顶部元素,对当前矩阵进行平移、旋转等变换操作也同样是堆栈顶部矩阵的修正。 因此,如果我们在转换之前调用giPushMatrix (),当前状态将被推入第2层,但堆栈顶部的矩阵也与第2层相同。

经过一系列变换后,修改堆栈顶部矩阵,此时调用glPopMatrix ()时,堆栈顶部矩阵将弹出并恢复为原始状态。

函数的作用过程可以用下图说明,更直观。

opengl场景中通常存在一些矩阵变换操作,但主要使用控制这些操作的命令

glmatrixmode(glenummode; 角色:用于指定以哪个矩阵为真

前矩阵,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 "includeglut.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 }

    运行结果:

    

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。