現在地 >> メニュー >> サンプルコード::Cg >> Cg::テクスチャ投影

問題


画像を読み込んでテクスチャ投影を行え。

頂点シェーダ

//----  入力データ構造  ---//
struct VERTEX_DATA
{
	float4 position : POSITION;
};

//---- 出力データ構造 ------//
struct VERTEX_OUTPUT
{
	float4 position : POSITION;
	float4 texCoord : TEXCOORD0;
};

//----- メイン関数 ------//
VERTEX_OUTPUT Cg_Main(VERTEX_DATA input, //入力 
					uniform float4x4 modelViewMatrix, //透視投影
					uniform float4x4 TextureMatrix) //テクスチャ投影
{
	VERTEX_OUTPUT VOUT; //出力

	//透視投影
	VOUT.position = mul(modelViewMatrix, input.position);
	//テクスチャ投影
	VOUT.texCoord = mul(TextureMatrix, input.position);
	return VOUT;
}

フラグメントシェーダ


//--- 入力データ構造 ---//
struct COLOR_OUTPUT {
	float4 color : COLOR;
};

//---- Cgメイン関数 -----//
COLOR_OUTPUT Cg_Fragment_Main(float4 texCoord : TEXCOORD0,
							  uniform sampler2D decal : TEX0)
{
	COLOR_OUTPUT OUT;
	OUT.color = tex2Dproj(decal,texCoord);//テクスチャ投影で色付け
	
	return OUT;
}

メイン関数


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


//--------------- 各種外部変数 ------------------------//
//Cgコンテキスト
CGcontext Cg_Cont;
//テクスチャ用変数
GLuint texture[1];
//投影位置
double ProjPos[3]={0,0,3};
//絞り具合
double ProjFovy = 30;


//------------- 各種データ構造 ------------------------//
//マウスの状態
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};



//----------- プロトタイプ宣言 --------------//
//Cg関係
void SET_UP_CG_VERTEX();
void SET_UP_CG_FRAGMENT();
void CgBindAndEnable();
void CgDisable();
//コールバック
void display(void);
void reshape(int w, int h);
void myMouseFunc(int button,int state,int x,int y);
void myMouseMotion(int x,int y);
void specialkeydown(int key, int x, int y);
void keyboard(unsigned char key, int x, int y);


//各種関数
void DRAW_XYZ();
void SetUpProjectPos();



//------------- 画像読み込み -----------------//
void LoadGLTextures()
{

	IplImage *imgA=cvLoadImage("test2.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
	if(imgA==NULL){
		std::cerr << "Can't Load Image\n";
		std::exit(0);
	}

	cvFlip(imgA); //上下反転

	//テクスチャ作成
	glBindTexture(GL_TEXTURE_2D, texture[0]);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgA->width,imgA->height, GL_BGR,GL_UNSIGNED_BYTE,imgA->imageData);

	cvReleaseImage( &imgA );
};




//------------ OpenGLの初期設定 ---------------//
void GLUT_INIT()
{
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(640,480);
	glutCreateWindow("Texture Projection part.1");
}


void GLUT_CALL_FUNC()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMouseFunc(myMouseFunc);
	glutMotionFunc(myMouseMotion);
	glutSpecialFunc(specialkeydown);
	glutKeyboardFunc(keyboard);

}


void MY_INIT()
{
	glClearColor(1.0, 1.0, 1.0, 1.0);
	glEnable(GL_DEPTH_TEST);
	LoadGLTextures();
}


//----------- Ggの設定 ----------------//
void CG_INIT()
{

	//コンテキスト作成
	Cg_Cont = cgCreateContext();
	if(Cg_Cont == NULL){
		std::cout << "Can't Create Context\n";
		exit(0);
	}

	SET_UP_CG_VERTEX(); //頂点セットアップ
	SET_UP_CG_FRAGMENT();//フラグメントセットアップ
}


//---------- 頂点シェーダのセットアップ -----------------//
CGprofile Vert_Prof;//頂点プロファイル
CGprogram Vert_Prog;//プログラム
CGparameter modelview;//モデルビュー行列
CGparameter TexMatrix;//テクスチャ行列

void SET_UP_CG_VERTEX()
{

	//---  プロファイルの設定   ---//
	Vert_Prof = cgGLGetLatestProfile(CG_GL_VERTEX);
	if(Vert_Prof == CG_PROFILE_UNKNOWN){
		std::cout << "Invalid profile type\n";
		exit(0);
	}
	cgGLSetOptimalOptions(Vert_Prof);


	//----  ファイルを読んでコンパイル -----//
	Vert_Prog =cgCreateProgramFromFile(
						Cg_Cont,		//コンテキスト
						CG_SOURCE,		//Cgソースコード
						"vertex.cg",	//「.cgファイル名」
						Vert_Prof,		//プロファイル
						"Cg_Main",		//「.cgファイル」で最初にいく関数
						NULL);			//NULLでよい

	cgGLLoadProgram(Vert_Prog); //プログラムをロードする
	if(Vert_Prog==NULL)
	{
		std::cout << cgGetErrorString(cgGetError()) << "\n";
		exit(0);
	}

	modelview = cgGetNamedParameter(Vert_Prog, "modelViewMatrix"); //「.cgファイル」での名前の設定
	TexMatrix = cgGetNamedParameter(Vert_Prog, "TextureMatrix");
}


//------- フラグメントの設定 ------------//
CGprofile Frag_Prof;	//フラグメントプロファイル
CGprogram Frag_Prog;	//フラグメントプログラム
CGparameter FragParam_decal; //Cgパラメータ

void SET_UP_CG_FRAGMENT()
{
	Frag_Prof = cgGLGetLatestProfile(CG_GL_FRAGMENT);
	if(Frag_Prof == CG_PROFILE_UNKNOWN)
	{
		std::cout << "Fragment : profile is unknown\n";
		exit(0);
	}

	cgGLSetOptimalOptions(Frag_Prof);

	Frag_Prog =	cgCreateProgramFromFile(
							Cg_Cont,		//コンテキスト
							CG_SOURCE,		//Cgソースコード
							"fragment.cg",	//「.cgファイル名」
							Frag_Prof,		//プロファイル
							"Cg_Fragment_Main",	//「.cgファイル」で最初にいく関数
							NULL);			//NULLでよい

	cgGLLoadProgram(Frag_Prog);
	if(Frag_Prog==NULL)
	{
		std::cout << cgGetErrorString(cgGetError()) <<"\n";
		exit(0);
	}

	FragParam_decal = cgGetNamedParameter(Frag_Prog, "decal");//「.cgファイル」内での名前
	cgGLSetTextureParameter(FragParam_decal, texture[0]); //作ったテクスチャとGPUとの関連付け

}

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

	GLUT_INIT();
	
	GLUT_CALL_FUNC();
	MY_INIT();
	CG_INIT();//Cgセットアップ

	glutMainLoop();

	return 0;
}


//----------- ここから各種コールバック --------------//
void display(void)
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	SetUpProjectPos(); //投影位置の設定
	gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	
	glRotated(ObjRot.xAngle,1,0,0);
	glRotated(ObjRot.yAngle,0,1,0);
	
	DRAW_XYZ();

	//投影点の描画
	glPointSize(10);
	glBegin(GL_POINTS);
	glColor3f(1,0,0);
	glVertex3dv(ProjPos);
	glColor3f(1,1,1);
	glEnd();
	glPointSize(1);



	//Cgの有効化
	CgBindAndEnable();
	

	glPushMatrix();
	glTranslatef(0,0,-3);
	//透視投影行列取得
	cgGLSetStateMatrixParameter(modelview,CG_GL_MODELVIEW_PROJECTION_MATRIX,CG_GL_MATRIX_IDENTITY);
	glRectf(-2,2,2,-1);
	glPopMatrix();

	//透視投影行列取得
	cgGLSetStateMatrixParameter(modelview,CG_GL_MODELVIEW_PROJECTION_MATRIX,CG_GL_MATRIX_IDENTITY);
	glutSolidSphere(1,30,30);
	
	CgDisable();//Cgの無効化

	glutSwapBuffers();


}


void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, (double)w / (double)h, 1.0, 100.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)
{
	int xdis,ydis;

	if(MouseStatus.flag == false)return;

	xdis = x - MouseStatus.Xstart;
	ydis = y - MouseStatus.Ystart;

	ObjRot.xAngle += (double)ydis * MouseStatus.weight;
	ObjRot.yAngle += (double)xdis * MouseStatus.weight;

	MouseStatus.Xstart = x;
	MouseStatus.Ystart = y;
	

	display();
}


//特殊キー処理
void specialkeydown(int key, int x, int y)
{
	switch(key)
	{
	case GLUT_KEY_UP:
		ProjPos[1]+=0.1; //+y軸
		break;

	case GLUT_KEY_DOWN:
		ProjPos[1]-=0.1; //-y軸
		break;

	case GLUT_KEY_RIGHT:
		ProjPos[0]+=0.1; //x軸
		break;

	case GLUT_KEY_LEFT:
		ProjPos[0]-=0.1; //-x軸
		break;
	}
	display();
}

void keyboard(unsigned char key, int x, int y)
{
	switch(key)
	{
	case 'z':
		ProjPos[2]-=0.1; //-z軸
		break;
	case 'x':
		ProjPos[2]+=0.1; //+z軸
		break;

	case 'f':
		ProjFovy += 2;
		break;
	case 'd':
		ProjFovy -=2;
		break;
	}

	display();
}



//----------- ここから各種関数 --------------//
void DRAW_XYZ()
{
	glBegin(GL_LINES);

	glColor3d(0,1,0);//x
	glVertex2d(-100,0);
	glVertex2d(100, 0);
	
	glColor3d(1,0,0);//y
	glVertex2d(0,0);
	glVertex2d(0,100);

	glColor3d(0,0,1);//z
	glVertex3d(0,0,-100);
	glVertex3d(0,0, 100);
	glEnd();
}


//投影位置の設定
void SetUpProjectPos()
{
	static int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);


	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glTranslated(0.5, 0.5, 0.0); //テクスチャ座標の位置補正

	gluPerspective(ProjFovy, static_cast<double>(viewport[2])/viewport[3], 1.0, 100.0);
	gluLookAt(ProjPos[0], ProjPos[1], ProjPos[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //投影位置

	//テクスチャ行列取得
	cgGLSetStateMatrixParameter(TexMatrix,CG_GL_TEXTURE_MATRIX,CG_GL_MATRIX_IDENTITY); 
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}


//-------------- ここからCg関係 ------------------//
//cgの有効化
void CgBindAndEnable()
{
	cgGLBindProgram(Vert_Prog);
	cgGLEnableProfile(Vert_Prof);

	cgGLBindProgram(Frag_Prog);
	cgGLEnableProfile(Frag_Prof);
	cgGLEnableTextureParameter(FragParam_decal);
}

//cgの無効化
void CgDisable()
{
	cgGLDisableProfile(Vert_Prof);
	cgGLDisableProfile(Frag_Prof);
	cgGLDisableTextureParameter(FragParam_decal);
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






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


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

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