簡析OpenGL的2D、3D切換

最近做遊戲的時候遇到了一個小問題,我們的遊戲是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];


發佈了31 篇原創文章 · 獲贊 14 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章