現在地 >> メニュー >> 発展編01 >> 発展編01::投影テクスチャ>>発展編01::まとめコード13

問題

画像を読み込んで、(0,0,2)の位置からテクスチャを投影せよ。

答え

#include <iostream>
#include <string>
#include <highgui.h>
#include <cv.h>
#include <gl/glut.h>

//------- 各種外部変数 -------//
const std::string file("file.png");
double aspect;



//--------- テクスチャ関連 ----------------//
//テクスチャID
GLuint textureId;

//テクスチャ座標生成用
enum{COORD_S,COORD_T,COORD_R,COORD_Q};
float coordForTexGen[][4] = 
{
	{ 1.0, 0.0, 0.0, 0.0 }, // s
	{ 0.0, 1.0, 0.0, 0.0 }, // t
	{ 0.0, 0.0, 1.0, 0.0 }, // r
	{ 0.0, 0.0, 0.0, 1.0 }, // q
};


//--------- 各種プロトタイプ ----------------//
void display();
void reshape(int w,int h);
void timer(int msec);
void Draw();



//--------- テクスチャ作成 ---------------//
bool LoadAndBuildTexture()
{
	cv::Ptr<IplImage> imgA;
	imgA = cvLoadImage(file.c_str());
	if(imgA.empty())
	{
		std::cerr << "Can't Load Image\n";
		return false;
	}
	cvConvertImage(imgA,imgA,CV_CVTIMG_FLIP | CV_CVTIMG_SWAP_RB);

	glGenTextures(1, &textureId);
	glBindTexture(GL_TEXTURE_2D, textureId);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgA->width,imgA->height, GL_RGB,GL_UNSIGNED_BYTE,imgA->imageData);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	return true;
}//ここでIplImageはメモリを自動解放


//----------- 各種GLUTの初期化 -------------------//
void GLUT_CallFuncs()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutTimerFunc(0,timer,34);
}


void GLUT_Inits(int *argcp,char **argv)
{
	glutInit(argcp,argv);

	glutInitWindowSize(640,480);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
	glutCreateWindow("Projection Texture");

	GLUT_CallFuncs();
}


void myOtherInit()
{
	glClearColor(1,1,1,1);
	glEnable(GL_DEPTH_TEST);

	//テクスチャの座標生成に関する背定
	//Object Linearで生成
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	//係数の関連付け
	glTexGenfv(GL_S, GL_OBJECT_PLANE, coordForTexGen[0]);
	glTexGenfv(GL_T, GL_OBJECT_PLANE, coordForTexGen[1]);
	glTexGenfv(GL_R, GL_OBJECT_PLANE, coordForTexGen[2]);
	glTexGenfv(GL_Q, GL_OBJECT_PLANE, coordForTexGen[3]);

}


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

	myOtherInit();

	if ( LoadAndBuildTexture() == false)
	{
		return -1;
	}

	glutMainLoop();

	return 0;
}


//--------- テクスチャ投影位置の設定 ------------//
void setupTexProj()
{
	glMatrixMode(GL_TEXTURE);//テクスチャ行列モード
	glLoadIdentity();
	glTranslated(0.5, 0.5, 0.0);//座標空間調整

	gluPerspective(30.0, aspect, 1.0, 100.0);
	gluLookAt(0, 0, 2, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //(0,0,2)から投影予定
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

}

//------------ 各種コールバック ------------//
void display()
{
	static int angle = 0;
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	
	setupTexProj();//投影位置を設定


	gluLookAt(2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	
	glRotatef(static_cast<float>(angle),0,1,0);
	Draw();

	//スポットライト位置描画
	glColor3f(1,0,0);
	glPointSize(5);
	glBegin(GL_POINTS);
	glVertex3f(0,0,2);
	glEnd();
	glColor3f(1,1,1);
	glPointSize(1);

	glutSwapBuffers();
	if(++angle >= 360) angle = 0;
}

void reshape(int w, int h)
{
	aspect = static_cast<double>(w) / h;
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, aspect , 0.1, 200.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void timer(int msec)
{
	glutTimerFunc(17,timer,17);
	glutPostRedisplay();
}


//----------- ここから各種関数 -------------//
void Draw()
{
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);
	glEnable(GL_TEXTURE_GEN_Q);
	glutSolidCube(1);
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_GEN_R);
	glDisable(GL_TEXTURE_GEN_Q);
	glDisable(GL_TEXTURE_2D);
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






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


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

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