简析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];


你可能感兴趣的:(OpenGL,游戏开发)