現在地: メニュー >> 実践編12 >> 実践編12::まとめコード

問題

以下の画像を使ってSkyBoxを作成せよ。

答え

#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <GL/glut.h>


//------------- 各種データ構造 ------------------------//
//マウスの状態
struct MOUSE
{
	int Xstart,Ystart;
	bool flag;
	double weight;
};
MOUSE MouseStatus={0,0,false,0.5};


//回転関係
struct ObjectRotate
{
	double xAngle,yAngle;
};
ObjectRotate ObjRot={0,0};



//----------- 各種外部変数 --------------//
const char *filename[]={"posx.jpg","negx.jpg","posy.jpg","negy.jpg","posz.jpg","negz.jpg"};
enum{POSX,NEGX,POSY,NEGY,POSZ,NEGZ};

//テクスチャID
unsigned int texId[6];//6方向分

//--------- プロトタイプ宣言 -----------//
void display();
void reshape(int w, int h);
void myMouseFunc(int button,int state,int x,int y);
void myMouseMotion(int x,int y);
void DrawSkyBox(float size);


//------------- OpenGLの初期化 -------------//
void GLUT_CALL_FUNCs()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMouseFunc(myMouseFunc);
	glutMotionFunc(myMouseMotion);
}


void OtherMyInit()
{
	glClearColor(0.0, 0.0, 0.0, 1.0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);//光源の有効化
	glEnable(GL_LIGHT0);

	glEnable(GL_NORMALIZE);
	//glColorで材質設定
	glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_COLOR_MATERIAL);

}


void GLUT_INITs(int *argcp, char **argv)
{
	glutInit(argcp,argv);
	glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(640,480);
	glutCreateWindow("Simple SkyBox");
	GLUT_CALL_FUNCs();
	OtherMyInit();
}



//------------- テクスチャの読み込み --------------//
void LoadTexture()
{

	glGenTextures( 6, &texId[0] );//6枚のテクスチャ

	cv::Ptr<IplImage> imgA;//OpenCVの新しいC++インターフェイス
	for(int loop = 0;loop < 6;++loop)
	{
		imgA = cvLoadImage(filename[loop],CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
		if(imgA.empty())
		{
			std::cerr << filename[loop] << " : Can't Load Image\n";
			exit(EXIT_FAILURE);
		}

		cvFlip(imgA,imgA);//上下反転


		glBindTexture( GL_TEXTURE_2D, texId[loop] );//バインド

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);//色は置き換えてマッピング
		
		glTexImage2D(GL_TEXTURE_2D,0,GL_RGB8,imgA->width,imgA->height, 0,GL_BGR,GL_UNSIGNED_BYTE,imgA->imageData);
		std::cout <<  filename[loop] << " : Loaded .\n";

		imgA.release();
	}


}




//------------ メイン関数 --------------//
int main(int argc, char **argv)
{
	GLUT_INITs(&argc,argv);
	LoadTexture();
	glutMainLoop();

	return 0;
}

//------------- ここから各種コールバック -----------------//
void display()
{
	static float Light0Pos[]={0.0, 500.0, 200.0,0}; //それらしい光源の位置を設定

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	gluLookAt(0.0, 0.0, 100.0, 0,0,-1, 0.0, 1.0, 0.0);//ちょっと後ろに下がる
	glRotated(ObjRot.xAngle,1,0,0);
	glRotated(ObjRot.yAngle,0,1,0);

	glLightfv(GL_LIGHT0, GL_POSITION, Light0Pos);

	DrawSkyBox(500); //SkyBoxを描画(大きさは500)
	

	glColor3f(0,1,0);
	glutSolidTeapot(10);//物体の描画

	glutSwapBuffers();


}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, (double)w / (double)h, 0.1, 1000.0);
	glMatrixMode(GL_MODELVIEW);
}




void myMouseFunc(int button,int state,int x,int y)
{
	if(button == GLUT_LEFT_BUTTON &&state == GLUT_DOWN){
		MouseStatus.Xstart = x;
		MouseStatus.Ystart = y;
		MouseStatus.flag = true;
	}
	else{
		MouseStatus.flag =false;
	}

}

void myMouseMotion(int x,int y)
{
	if(MouseStatus.flag == false)return;

	static int xdir,ydir;

	xdir = x - MouseStatus.Xstart;
	ydir = y - MouseStatus.Ystart;

	ObjRot.xAngle += (double)ydir * MouseStatus.weight;
	ObjRot.yAngle += (double)xdir * MouseStatus.weight;

	MouseStatus.Xstart = x;
	MouseStatus.Ystart = y;
	
	glutPostRedisplay();
}


//-------- SkyBoxの描画 -----------//
void DrawSkyBox(float size)
{
	glPushAttrib(GL_ENABLE_BIT);//この時点の各種glEnable()系は退避
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_LIGHTING);
	glDisable(GL_BLEND);

	//+x方向
	glBindTexture(GL_TEXTURE_2D, texId[POSX]);
	glBegin(GL_QUADS);
		glTexCoord2f(0, 0); glVertex3f(  size, -size, -size );
		glTexCoord2f(1, 0); glVertex3f( -size, -size, -size );
		glTexCoord2f(1, 1); glVertex3f( -size,  size, -size );
		glTexCoord2f(0, 1); glVertex3f(  size,  size, -size );
	glEnd();

	//+z方向
	glBindTexture(GL_TEXTURE_2D, texId[POSZ]);
	glBegin(GL_QUADS);
		glTexCoord2f(0, 0); glVertex3f(  size, -size,  size );
		glTexCoord2f(1, 0); glVertex3f(  size, -size, -size );
		glTexCoord2f(1, 1); glVertex3f(  size,  size, -size );
		glTexCoord2f(0, 1); glVertex3f(  size,  size,  size );
	glEnd();

	//-x方向
	glBindTexture(GL_TEXTURE_2D, texId[NEGX]);
	glBegin(GL_QUADS);
		glTexCoord2f(0, 0); glVertex3f( -size, -size,  size );
		glTexCoord2f(1, 0); glVertex3f(  size, -size,  size );
		glTexCoord2f(1, 1); glVertex3f(  size,  size,  size );
		glTexCoord2f(0, 1); glVertex3f( -size,  size,  size );
	glEnd();

	//-z方向
	glBindTexture(GL_TEXTURE_2D, texId[NEGZ]);
	glBegin(GL_QUADS);
		glTexCoord2f(0, 0); glVertex3f( -size, -size, -size );
		glTexCoord2f(1, 0); glVertex3f( -size, -size,  size );
		glTexCoord2f(1, 1); glVertex3f( -size,  size,  size );
		glTexCoord2f(0, 1); glVertex3f( -size,  size, -size );
	glEnd();

	//+y方向
	glBindTexture(GL_TEXTURE_2D, texId[POSY]);
	glBegin(GL_QUADS);
		glTexCoord2f(1, 1); glVertex3f( -size,  size, -size );
		glTexCoord2f(0, 1); glVertex3f( -size,  size,  size );
		glTexCoord2f(0, 0); glVertex3f(  size,  size,  size );
		glTexCoord2f(1, 0); glVertex3f(  size,  size, -size );
	glEnd();

	//-y方向
	glBindTexture(GL_TEXTURE_2D, texId[NEGY]);
	glBegin(GL_QUADS);
		glTexCoord2f(1, 0); glVertex3f( -size, -size, -size );
		glTexCoord2f(0, 0); glVertex3f( -size, -size,  size );
		glTexCoord2f(0, 1); glVertex3f(  size, -size,  size );
		glTexCoord2f(1, 1); glVertex3f(  size, -size, -size );
	glEnd();

	glPopAttrib();//各種Enable系をもどす
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます