为什么调用glPushMatrix()和glPopMatrix()

今天忽然感悟到为什么在进行变换之前要用glPushMatrix();这个函数,而在变换完毕后有用glPopMatrix()这两个函数了,赶紧记下来:

    我们在变换坐标的时候,使用的是glTranslatef(),glRotaef()等函数来操作,操作的是什么呢?操作的是当前矩阵,我们也知道,这些坐标变换(翻转,旋转也好)都是通过操作矩阵来实现的,而矩阵相乘是会叠加的,当你用完一个变换函数后,当前操作的矩阵就被改变了,当你还停留在变换以前的思维,我在这个地方绘制恰好是我想要的时候,你会发现再绘制出来的不是在你想要的位置,因为你在操作变换的时候,当前矩阵被改变了。

 

      当你做了一些移动或旋转等变换后,使用glPushMatrix();OpenGL 会把这个变换后的位置和角度保存起来。然后你再随便做第二次移动或旋转变换,再用glPopMatrix();OpenGL 就把刚刚保存的那个位置和角度恢复。

比如:

view plain print ?
  1. glLoadIdentity();  
  2. glTranslatef(1,0,0);//向右移动(1,0,0)  
  3. glPushMatrix();//保存当前位置  
  4. glTranslatef(0,1,0);//现在是(1,1,0)了  
  5. glPopMatrix();//这样,现在又回到(1,0,0)了  

 

   比如你在默认情况下在原点画了一个球,然后又进行了一个变换,比如用glTranslatef( 0.0, 0.0, 1.0 );沿z轴移动一定距离又画了一个球,然后你想再在原点画一个大一点的球覆盖原来的那个,当你绘制的时候就会发现,你现在绘制的球已不在你想像的地方了。

我们来做个实验:

代码如下:

 

view plain print ?
  1. void display()  
  2. {  
  3. glClear( GL_COLOR_BUFFER_BIT );  
  4. glShadeModel( GL_SMOOTH );  
  5. //现在原点绘制一个红色正方形  
  6. glColor3f( 1.0, 0.0, 0.0 );  
  7. glRectf( -0.05, -0.05, 0.05, 0.05 );  
  8. //glPushMatrix();  
  9. //变换--沿x轴移动  
  10.     glTranslatef( 0.2, 0.0, 0.0 );  
  11.     //glPopMatrix();  
  12. //再绘制一个正方形  
  13. glColor3f( 0.0, 1.0, 0.0 );  
  14. glRectf( -0.05, -0.05, 0.05, 0.05 );//这时,当我们还想在同样位置绘制时,却发现已经偏移  
  15. glFlush();  
  16. }  
 

 

 

    当我们把glPushMatrxi()和glPopMatrix()注释掉以后我们发现,当我们再想在同样的位置绘制一个正方形的时候,就会发现已经按我们的glTransfef()所指定的沿x轴偏移了0.2个单位。

而当我们不把两句函数调用注释掉时,运行发现,绿色的正方形覆盖了原来的红色的正方形。

 

所以,这两个函数的压栈弹栈是有用地~~~~~~~~~~

这两个函数的具体的执行方式就不扯了,网上n多。

知之为知之,不知百度之

~~~~~~~~~~~~吼吼~~~~~~~~~~

续文:

顿悟这点以后,晚上又突然想明白了另一个大问题:移动光源的位置。

在顿悟以前,总觉得光源该怎么移动呢?那不是十分十分麻烦么,而且不知道怎么办,现在明白了这个道理以后,光照的移动就简单了。

移动方式:

      先pushMatrix()一下,然后在进行移动操作,然后旋转操作,然后指定光源的位置,然后PopMatrix()一下,就完成了。

测试代码:

 

view plain print ?
  1. #include <gl/glut.h>  
  2. static int spin = 0;  
  3. void init()  
  4. {  
  5. glShadeModel( GL_SMOOTH );  
  6.     glEnable( GL_LIGHTING );  
  7. glEnable( GL_LIGHT0 );  
  8. glEnable( GL_DEPTH_TEST );  
  9. }  
  10. void display()  
  11. {  
  12. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );  
  13. GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };  
  14. glPushMatrix();  
  15. glTranslatef( 0.0, 0.0, -5.0 );  
  16. glPushMatrix();  
  17. glRotated( (GLdouble)spin, 1.0, 0.0, 0.0 );  
  18. glLightfv( GL_LIGHT0, GL_POSITION, position );  
  19. glTranslated( 0.0, 0.0, 1.5 );  
  20. glDisable( GL_LIGHTING );  
  21. glColor3f( 0.0, 1.0, 0.0 );  
  22. glutWireCube( 0.1 );//绿色的下框,代表光源位置  
  23. glEnable( GL_LIGHTING );  
  24. glPopMatrix();  
  25. glutSolidSphere( 0.5, 40, 40 );//被光照的物体  
  26. glPopMatrix();  
  27. glFlush();  
  28. }  
  29. void reshape( int w, int h )  
  30. {  
  31.     glViewport( 0, 0, (GLsizei)w, (GLsizei)h );  
  32. glMatrixMode( GL_PROJECTION );  
  33. glLoadIdentity();  
  34. gluPerspective( 40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0 );  
  35. glMatrixMode( GL_MODELVIEW );  
  36. glLoadIdentity();  
  37. }  
  38. void mouse( int button, int state, int x, int y )  
  39. {  
  40. switch ( button )  
  41. {  
  42. case GLUT_LEFT_BUTTON:  
  43.    if ( state == GLUT_DOWN )  
  44.    {  
  45.     spin = ( spin + 30 ) % 360;  
  46.     glutPostRedisplay();  
  47.    }  
  48.    break;  
  49. default:  
  50.    break;  
  51. }  
  52. }  
  53. int main( int argc, char ** argv )  
  54. {  
  55. glutInit( &argc, argv );  
  56. glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );  
  57. glutInitWindowPosition( 100, 100 );  
  58. glutInitWindowSize( 500, 500 );  
  59. glutCreateWindow( argv[0] );  
  60. init();  
  61. glutDisplayFunc( display );  
  62. glutReshapeFunc( reshape );  
  63. glutMouseFunc( mouse );  
  64. glutMainLoop();  
  65. return 0;  
  66. }  
 



你可能感兴趣的:(测试,百度,buffer,360,button)