現在來試試 球紋理(=720度全景圖)轉換為天空盒圖(6張,前,後,左,右,頂,底)
先找一張全景圖:
流程:
1。載入全景圖到opengl 中并貼到天空球上
2。把視線分别轉到前,後,左,右,頂,底
3。截屏儲存為檔案
具體看代碼吧:
//53 全景球貼圖 切分6圖
//左鍵(+ 移動)旋轉,右鍵(+ 移動)縮放 1,2,3,4 切換地圖,Enter鍵(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;//方向
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("map5.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);
if(direction=="左")
glRotatef(90, 0.0, 1.0, 0.0);
if(direction=="右")
glRotatef(-90, 0.0, 1.0, 0.0);
if(direction=="上")
glRotatef(90, 1.0, 0.0, 0.0);
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();
setWidthHeight(width,height);
screenshot("上.bmp"); //全視窗
system("bmp2jpg 上.bmp");//轉化為jpg
}
break;
case 'f':
{
direction="後";
glutPostRedisplay();
setWidthHeight(width,height);
screenshot("後.bmp"); //全視窗
system("bmp2jpg 後.bmp");//轉化為jpg
}
break;
case 'x':
{
direction="下";
glutPostRedisplay();
setWidthHeight(width,height);
screenshot("下.bmp"); //全視窗
system("bmp2jpg 下.bmp");//轉化為jpg
}
break;
case 'a':
{
direction="左";
glutPostRedisplay();
setWidthHeight(width,height);
screenshot("左.bmp"); //全視窗
system("bmp2jpg 左.bmp");//轉化為jpg
}
break;
case 'd':
{
direction="右";
glutPostRedisplay();
setWidthHeight(width,height);
screenshot("右.bmp"); //全視窗
system("bmp2jpg 右.bmp");//轉化為jpg
}
break;
case 's'://前
{
direction="前";
glutPostRedisplay();
setWidthHeight(width,height);
screenshot("前.bmp"); //全視窗
system("bmp2jpg 前.bmp");//轉化為jpg
}
break;
}
glutPostRedisplay();
}
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);
glutMainLoop();
return 0;
}
按w,a,s,d,f,x 分别截圖
由于opengl機制,每個按鍵要按兩次才能儲存目前圖(估計要加延時)
效果圖(分别為,頂,左,前,右,後,底):
好象有一點效果,但是不能連接配接起來。
怎麼控制邊界,還得研究學習,也期待高手指教!!