OpenGL视图和模型变换中各变换发生顺序的思考

http://blog.csdn.net/xiajun07061225/article/details/7037020

 

在视图模型变换中,顶点v的变换是按照相反的顺序发生的,而不是按照它的代码中先后顺序出现的。下面举例说明。

考虑下面的代码:

[cpp] view plain copy print ?
  1. glMatrixMode(GL_MODELVIEW);  
  2.     glLoadIdentity();  
  3.     glMultMatrixf(N);  
  4.     glMultMatrixf(M);  
  5.     glMultMatrixf(L);  
  6.     glBegin(GL_POINTS);  
  7.     glVertex3dv(v);  
  8.     glEnd();  

在这段代码中,模型视图矩阵按顺序分别包含I、N、NM,最后是NML,其中I表示单位矩阵。经过变化的顶点是NMLv。因此顶点变换就是N(M(Lv))。

下面看绘制机器人手臂的display()函数的代码:

[cpp] view plain copy print ?
  1. void display()  
  2. {  
  3.     glClear(GL_COLOR_BUFFER_BIT);  
  4.     glPushMatrix();  
  5.   
  6.     glTranslatef(-1.0,0.0,0.0);  
  7.     glRotatef((GLfloat)shoulder,0.0,0.0,1.0);  
  8.     glTranslatef(1.0,0.0,0.0);  
  9.   
  10.     //绘制第一段手臂   
  11.     glPushMatrix();   
  12.     glScalef(2.0,0.4,1.0);  
  13.     glutWireCube(1.0);  
  14.     glPopMatrix();  
  15.   
  16.     glTranslatef(1.0,0.0,0.0);  
  17.     glRotatef((GLfloat)elbow,0.0,0.0,1.0);  
  18.     glTranslatef(1.0,0.0,0.0);  
  19.   
  20.     //绘制第二段手臂   
  21.     glPushMatrix();   
  22.     glScalef(2.0,0.4,1.0);  
  23.     glutWireCube(1.0);  
  24.     glPopMatrix();  
  25.   
  26.     glPopMatrix();  
  27.     glutSwapBuffers();    
  28. }  

我们通过逐步调试运行来查看效果。

现在注释掉代码:

[cpp] view plain copy print ?
  1. glTranslatef(-1.0,0.0,0.0);  
  2.     glRotatef((GLfloat)shoulder,0.0,0.0,1.0);  
  3.     glTranslatef(1.0,0.0,0.0);  

以及绘制第二段手臂的代码:

[cpp] view plain copy print ?
  1. //绘制第二段手臂   
  2.     glPushMatrix();   
  3.     glScalef(2.0,0.4,1.0);  
  4.     glutWireCube(1.0);  
  5.     glPopMatrix();  

只保留绘制第一段的代码,便于查看效果。

运行结果:

OpenGL视图和模型变换中各变换发生顺序的思考_第1张图片

显示的是经过缩放了的立方体。

然后解除下面这行代码的注释:glTranslatef(1.0,0.0,0.0);(位于旋转之下的代码)

运行结果:

OpenGL视图和模型变换中各变换发生顺序的思考_第2张图片

显示的是经过缩放、平移的结果。

在解除这行代码的注释:glRotatef((GLfloat)shoulder,0.0,0.0,1.0);

运行结果:

OpenGL视图和模型变换中各变换发生顺序的思考_第3张图片

显示的是经过缩放、平移、再旋转地结果。

再解除这行代码的注释:glTranslatef(-1.0,0.0,0.0);(位于旋转之上的代码)

运行结果:

OpenGL视图和模型变换中各变换发生顺序的思考_第4张图片

可以看出是上一步的结果又平移之后的效果。

从上面的单步效果可以看出,乘法的出现顺序和他们的代码中得出现顺序相反。


最后给出绘制两端机器人手臂整个代码:

[cpp] view plain copy print ?
  1. //绘制机器人手臂   
  2. #include <GL/glut.h>   
  3.   
  4. static int shoulder = 0,elbow = 0;//两段手臂旋转的角度   
  5.   
  6. void init ()  
  7. {  
  8.     glClearColor(0.0,0.0,0.0,0.0);  
  9.     glShadeModel(GL_FLAT);  
  10. }  
  11.   
  12. void display()  
  13. {  
  14.     glClear(GL_COLOR_BUFFER_BIT);  
  15.     glPushMatrix();  
  16.   
  17.     glTranslatef(-1.0,0.0,0.0);  
  18.     glRotatef((GLfloat)shoulder,0.0,0.0,1.0);  
  19.     glTranslatef(1.0,0.0,0.0);  
  20.   
  21.     //绘制第一段手臂   
  22.     glPushMatrix();   
  23.     glScalef(2.0,0.4,1.0);  
  24.     glutWireCube(1.0);  
  25.     glPopMatrix();  
  26.   
  27.     glTranslatef(1.0,0.0,0.0);  
  28.     glRotatef((GLfloat)elbow,0.0,0.0,1.0);  
  29.     glTranslatef(1.0,0.0,0.0);  
  30.   
  31.     //绘制第二段手臂   
  32.     glPushMatrix();   
  33.     glScalef(2.0,0.4,1.0);  
  34.     glutWireCube(1.0);  
  35.     glPopMatrix();  
  36.   
  37.     glPopMatrix();  
  38.     glutSwapBuffers();    
  39. }  
  40.   
  41. void reshape(int w,int h)  
  42. {  
  43.     glViewport(0,0,(GLsizei)w,(GLsizei)h);  
  44.     glMatrixMode(GL_PROJECTION);  
  45.     glLoadIdentity();  
  46.     gluPerspective(65.0,(GLfloat) w/ (GLfloat)h,1.0,20.0);  
  47.     glMatrixMode(GL_MODELVIEW);  
  48.     glLoadIdentity();  
  49.     glTranslatef(0.0,0.0,-5.0);  
  50. }  
  51.   
  52. void keyboard(unsigned char key,int x,int y)  
  53. {  
  54.     switch(key)//s和e键控制两端手臂的旋转角度   
  55.     {  
  56.     case 's':  
  57.         shoulder = (shoulder + 5)% 360;  
  58.         glutPostRedisplay();  
  59.         break;  
  60.     case 'S':  
  61.         shoulder = (shoulder - 5)% 360;  
  62.         glutPostRedisplay();  
  63.         break;  
  64.     case 'e':  
  65.         elbow = (elbow + 5) % 360;  
  66.         glutPostRedisplay();  
  67.         break;  
  68.     case 'E':  
  69.         elbow = (elbow - 5) % 360;  
  70.         glutPostRedisplay();  
  71.         break;  
  72.     default:  
  73.         break;  
  74.     }  
  75. }  
  76.   
  77. int main(int argc,char** argv)  
  78. {  
  79.     glutInit(&argc,argv);  
  80.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  
  81.     glutInitWindowSize(400,400);  
  82.     glutInitWindowPosition(100,100);  
  83.     glutCreateWindow(argv[0]);  
  84.     init();  
  85.     glutDisplayFunc(display);  
  86.     glutReshapeFunc(reshape);  
  87.     glutKeyboardFunc(keyboard);  
  88.     glutMainLoop();  
  89.     return 0;  
  90. }  
运行效果(通过s和e键可以控制两端手臂的旋转角度):

OpenGL视图和模型变换中各变换发生顺序的思考_第5张图片


你可能感兴趣的:(buffer,360,keyboard)