opengl全景圖轉換為天空盒圖(成功)
阿新 • • 發佈:2019-02-07
前面哪個opengl程式實際上已經快成功了,只差一點點了。
發現只要前、後圖對換,左、右圖對換就可以了
所以這裡除了對換外,把哪個要按2次鍵才能截到正確的圖也改一下(延時)
具體看程式碼吧:
然後把這6張圖片放到前面的天空盒程式中://53 全景球貼圖 切分6圖 //左鍵(+ 移動)旋轉,右鍵(+ 移動)縮放 1,2,3,4 切換地圖,回車鍵(enter)全屏切換,按w、a、s、d、f、x、切換視角並截圖 #pragma comment( lib, "opengl32.lib" ) #pragma comment( lib, "glut32.lib") #include <GL/glut.h> #include <GL/glu.h> #include <math.h> #include <cstdlib> #include <string> #include "ArcBall.h" #include "Sky.h" CSky m_sky; void setWidthHeight(GLint width ,GLint height); void screenshot(char* FileName); //全視窗 int BuildTexture(char *szPathName, GLuint &texid); //初始化,必須用全域性變數的方式,不能用new ArcBallT arcBall(600.0f,400.0f); ArcBallT* ArcBall =&arcBall;// new ArcBallT(600.0f,400.0f);//&arcBall; #define PI 3.141592654 GLuint SkyTexture[10];//紋理 int width,height;//螢幕寬高 int R=100;//地圖球半徑 std::string direction;//方向 bool Shot=false; void reshape(int w, int h){ glViewport(0,0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //GLdouble zNear=R*cos(PI/2); gluPerspective(90.0f, (GLfloat)w / (GLfloat)h, 6.5f, R*2);//zNear glMatrixMode(GL_MODELVIEW); ////ball ArcBall->setBounds((GLfloat)w, (GLfloat)h);//1. 設定視窗邊界 } void init(){ glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClearDepth(1.0f); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); /* 啟用紋理 */ glEnable(GL_TEXTURE_2D); /* 初始化天空 */ //載入天空紋理圖 //請放到一起(和其它圖) BuildTexture("m1.jpg",SkyTexture[0]);//塔下全景圖 BuildTexture("mm2.jpg",SkyTexture[3]);//航空圖 BuildTexture("mesh.jpg",SkyTexture[1]);//英文世界地圖 BuildTexture("mm.jpg",SkyTexture[4]);//起居室圖 BuildTexture("world3.jpg",SkyTexture[2]);//航空航海圖 //int R=105;//地圖球半徑 m_sky.InitSky(0,0,0,R,SkyTexture[0]);//初始化天空球 direction="前"; } void display (void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0,//m_sky.GetSkyR()*ArcBall->zoomRate+5.0,//視點跟蹤球大小 0.0, 0.0,R, 0.0, 1.0, 0.0); //glTranslatef(0,0,-3); glScalef(ArcBall->zoomRate, ArcBall->zoomRate, ArcBall->zoomRate);//2. 縮放 glScalef(-1.0, -1.0, -1.0);//2. 縮放 glMultMatrixf(ArcBall->Transform.M); //3. 旋轉 //位置轉到... if(direction=="後") glRotatef(180, 0.0, 1.0, 0.0); else if(direction=="左") glRotatef(90, 0.0, 1.0, 0.0); else if(direction=="右") glRotatef(-90, 0.0, 1.0, 0.0); else if(direction=="上") glRotatef(90, 1.0, 0.0, 0.0); else if(direction=="下") glRotatef(-90, 1.0, 0.0, 0.0); /* 繪製天空 */ m_sky.ShowSky() ; glFlush (); } //移動 void move(int x, int y) { ArcBall->MousePt.s.X = x; ArcBall->MousePt.s.Y = y; ArcBall->upstate(); glutPostRedisplay(); } //點選 void mouse(int button, int state, int x, int y) { if(button == GLUT_LEFT_BUTTON && state==GLUT_DOWN){ ArcBall->isClicked = true; move(x,y); } else if(button == GLUT_LEFT_BUTTON && state==GLUT_UP) ArcBall->isClicked = false; else if(button == GLUT_RIGHT_BUTTON && state==GLUT_DOWN){ ArcBall->isRClicked = true; move(x,y); } else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) ArcBall->isRClicked = false; ArcBall->upstate(); glutPostRedisplay(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; case '1': m_sky.T=SkyTexture[1]; break; case '2': m_sky.T=SkyTexture[2]; break; case '3': m_sky.T=SkyTexture[3]; break; case '4': m_sky.T=SkyTexture[4]; break; case '5': m_sky.T=SkyTexture[0]; break; case 13://按回車切換全屏 { static bool full=false; if (full) { glutReshapeWindow(width,height);//視窗 full=false; } else { glutFullScreen();//全屏 full=true; } } break; case 'w': { direction="上"; glutPostRedisplay(); Shot=true; } break; case 'f': { direction="後"; glutPostRedisplay(); Shot=true; } break; case 'x': { direction="下"; glutPostRedisplay(); Shot=true; } break; case 'a': { direction="左"; glutPostRedisplay(); Shot=true; } break; case 'd': { direction="右"; glutPostRedisplay(); Shot=true; } break; case 's'://前 { direction="前"; glutPostRedisplay(); Shot=true; } break; } glutPostRedisplay(); } void saveShot() { static int count=0; if(Shot){ if(count<2){//延時 count++; return; } if(direction=="前"){ setWidthHeight(width,height); screenshot("前.bmp"); //全視窗 system("bmp2jpg 前.bmp");//轉化為jpg }else if(direction=="後") { setWidthHeight(width,height); screenshot("後.bmp"); //全視窗 system("bmp2jpg 後.bmp");//轉化為jpg }else if(direction=="左") { setWidthHeight(width,height); screenshot("左.bmp"); //全視窗 system("bmp2jpg 左.bmp");//轉化為jpg }else if(direction=="右") { setWidthHeight(width,height); screenshot("右.bmp"); //全視窗 system("bmp2jpg 右.bmp");//轉化為jpg }else if(direction=="上") { setWidthHeight(width,height); screenshot("上.bmp"); //全視窗 system("bmp2jpg 上.bmp");//轉化為jpg }else if(direction=="下") { setWidthHeight(width,height); screenshot("下.bmp"); //全視窗 system("bmp2jpg 下.bmp");//轉化為jpg } Shot=false; count=0; } } int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); width=640;height=640; R=width/(2*sin(45*PI/180)); glutInitWindowSize(width,height); glutCreateWindow("HI"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse); //註冊滑鼠事件。 glutMotionFunc(move); //註冊移動事件 glutKeyboardFunc(keyboard); glutIdleFunc(saveShot); //在程式空閒的時候就會被呼叫的函式的函式名。 glutMainLoop(); return 0; }
//char *bmpName[] = { "back","front","bottom","top","left","right"};
char *bmpName[] = { "後","前","下","上","左","右"};
效果圖:
每個連線都是正確的了。完成!