最近做遊戲的時候遇到了一個小問題,我們的遊戲是2D、3D結合的(準確的說是主菜單、議會界面是2D的,但是真實打鬥場景爲3D),由2D切換到3D沒有問題,但是由3D切換回2D問題就來了:每次切換都只有glClear()管用,其餘的加載圖片之類的都顯示不了。經過分析感覺應該是視圖矩陣的問題,因爲在3D場景中我們多次調用了glLookAt()、gluPerspective()等函數,而每調用一次,OpenGL的機理是把當前矩陣乘上轉換算子,所以每次都乘,到了2D場景的時候如果不轉換回來就會出問題。
可以關注我的個人主頁:http://alanzjl.sinaapp.com
解決這個問題有兩種辦法,第一種是在display()函數裏通過glPushMatrix()、glPopMatrix()解決。但是我們遇到的問題是可能在display中Push、Pop的次數太多,導致最終這種辦法不行。還有一種就是在初始狀態下記錄初始矩陣,在將切換回2D的時候恢復初始矩陣。
可通過
glGetIntegerv(GL_VIEWPORT,&view); //viewport
glGetDoublev(GL_MODELVIEW_MATRIX,&model);//model
glGetDoublev(GL_PROJECTION_MATRIX,&proj);//projection
得到。
但是我們只要得到一次而且是第一次的矩陣就可以,所以要藉助一個static int變量。具體實現代碼:
void my_display(void){
static flagggg;
if(flagggg==0){
//只取第一次的初始矩陣
glGetIntegerv(GL_VIEWPORT,&view); //viewport
glGetDoublev(GL_MODELVIEW_MATRIX,&model);//model
glGetDoublev(GL_PROJECTION_MATRIX,&proj);//projection
flagggg=1;
}
/**************************************************************
模式入口
**************************************************************/
if(Enter_Mode==-1)
introduction();
else if(Enter_Mode==0)
main_menu();
else if(Enter_Mode==1){
adventure(); //此處是3D
}
else if(Enter_Mode==2){ //此處是2D,會由上面一種模式切換到此模式,需要矩陣還原
glLoadMatrixd(view);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(model);
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(proj);
congress();
}
else if(Enter_Mode==3)
achievement();
else if(Enter_Mode==4)
quit();
else if(Enter_Mode==5)
complete();
/**************************************************************/
}
其中,view、model、proj被我定義爲了全局變量,它們是:
GLint view[4];
GLdouble model[16];
GLdouble proj[16];