1. 程式人生 > >opengl全景圖轉換為天空盒圖(成功)

opengl全景圖轉換為天空盒圖(成功)

前面哪個opengl程式實際上已經快成功了,只差一點點了。

發現只要前、後圖對換,左、右圖對換就可以了

所以這裡除了對換外,把哪個要按2次鍵才能截到正確的圖也改一下(延時)

具體看程式碼吧:

//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;
}
然後把這6張圖片放到前面的天空盒程式中:
    //char *bmpName[] = { "back","front","bottom","top","left","right"};
    char *bmpName[] = { "後","前","下","上","左","右"};

效果圖:



每個連線都是正確的了。完成!