您的位置:首页 > 运维架构

简析OpenGL的2D、3D切换

2015-03-18 08:52 190 查看
最近做游戏的时候遇到了一个小问题,我们的游戏是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];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: