最終更新: mikk_ni3_92 2008年11月23日(日) 17:51:18履歴
現在地 >> メニュー >> サンプルコード::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); }