今天忽然感悟到為什么在進行變換之前要用glPushMatrix();這個函數(shù),而在變換完畢后有用glPopMatrix()這兩個函數(shù)了,趕緊記下來:
我們在變換坐標的時候,使用的是glTranslatef(),glRotaef()等函數(shù)來操作,操作的是什么呢?操作的是當(dāng)前矩陣,我們也知道,這些坐標變換(翻轉(zhuǎn),旋轉(zhuǎn)也好)都是通過操作矩陣來實現(xiàn)的,而矩陣相乘是會疊加的,當(dāng)你用完一個變換函數(shù)后,當(dāng)前操作的矩陣就被改變了,當(dāng)你還停留在變換以前的思維,我在這個地方繪制恰好是我想要的時候,你會發(fā)現(xiàn)再繪制出來的不是在你想要的位置,因為你在操作變換的時候,當(dāng)前矩陣被改變了。
比如你在默認情況下在原點畫了一個球,然后又進行了一個變換,比如用glTranslatef( 0.0, 0.0, 1.0 );沿z軸移動一定距離又畫了一個球,然后你想再在原點畫一個大一點的球覆蓋原來的那個,當(dāng)你繪制的時候就會發(fā)現(xiàn),你現(xiàn)在繪制的球已不在你想像的地方了。
我們來做個實驗:
代碼如下:
void display()
{
glClear( GL_COLOR_BUFFER_BIT );
glShadeModel( GL_SMOOTH );
//現(xiàn)在原點繪制一個紅色正方形
glColor3f( 1.0, 0.0, 0.0 );
glRectf( -0.05, -0.05, 0.05, 0.05 );
//glPushMatrix();
//變換--沿x軸移動
glTranslatef( 0.2, 0.0, 0.0 );
//glPopMatrix();
//再繪制一個正方形
glColor3f( 0.0, 1.0, 0.0 );
glRectf( -0.05, -0.05, 0.05, 0.05 );//這時,當(dāng)我們還想在同樣位置繪制時,卻發(fā)現(xiàn)已經(jīng)偏移
glFlush();
}
當(dāng)我們把glPushMatrxi()和glPopMatrix()注釋掉以后我們發(fā)現(xiàn),當(dāng)我們再想在同樣的位置繪制一個正方形的時候,就會發(fā)現(xiàn)已經(jīng)按我們的glTransfef()所指定的沿x軸偏移了0.2個單位。
而當(dāng)我們不把兩句函數(shù)調(diào)用注釋掉時,運行發(fā)現(xiàn),綠色的正方形覆蓋了原來的紅色的正方形。
所以,這兩個函數(shù)的壓棧彈棧是有用地~~~~~~~~~~
這兩個函數(shù)的具體的執(zhí)行方式就不扯了,網(wǎng)上n多。
知之為知之,不知百度之
~~~~~~~~~~~~吼吼~~~~~~~~~~
續(xù)文:
頓悟這點以后,晚上又突然想明白了另一個大問題:移動光源的位置。
在頓悟以前,總覺得光源該怎么移動呢?那不是十分十分麻煩么,而且不知道怎么辦,現(xiàn)在明白了這個道理以后,光照的移動就簡單了。
移動方式:
先pushMatrix()一下,然后在進行移動操作,然后旋轉(zhuǎn)操作,然后指定光源的位置,然后PopMatrix()一下,就完成了。
測試代碼:
#include <gl/glut.h>
static int spin = 0;
void init()
{
glShadeModel( GL_SMOOTH );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable( GL_DEPTH_TEST );
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 };
glPushMatrix();
glTranslatef( 0.0, 0.0, -5.0 );
glPushMatrix();
glRotated( (GLdouble)spin, 1.0, 0.0, 0.0 );
glLightfv( GL_LIGHT0, GL_POSITION, position );
glTranslated( 0.0, 0.0, 1.5 );
glDisable( GL_LIGHTING );
glColor3f( 0.0, 1.0, 0.0 );
glutWireCube( 0.1 );//綠色的下框,代表光源位置
glEnable( GL_LIGHTING );
glPopMatrix();
glutSolidSphere( 0.5, 40, 40 );//被光照的物體
glPopMatrix();
glFlush();
}
void reshape( int w, int h )
{
glViewport( 0, 0, (GLsizei)w, (GLsizei)h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 40.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void mouse( int button, int state, int x, int y )
{
switch ( button )
{
case GLUT_LEFT_BUTTON:
if ( state == GLUT_DOWN )
{
spin = ( spin + 30 ) % 360;
glutPostRedisplay();
}
break;
default:
break;
}
}
int main( int argc, char ** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
glutInitWindowPosition( 100, 100 );
glutInitWindowSize( 500, 500 );
glutCreateWindow( argv[0] );
init();
glutDisplayFunc( display );
glutReshapeFunc( reshape );
glutMouseFunc( mouse );
glutMainLoop();
return 0;
}