現在地 >> メニュー >> サンプルコード::Cg >> Cg::基本編05 >> Cg::アニメーション2 >> Cg::基本編05まとめ2

問題


アニメーションせよ。
その他条件:
  • GPUで頂点を回転し透視投影する。

答え

頂点シェーダ

//-------- 各種データ構造 --------//
struct InputVertex	//入力データ構造
{
	float4 position : POSITION;
	float3 color : COLOR;
};

struct OutputVertex	//出力データ構造
{
	float4 position : POSITION;
	float3 color : COLOR;
};

//-------- 頂点シェーダメイン関数 ---------//
OutputVertex Cg_Main(in InputVertex input,uniform float4x4 modelViewMatrix,uniform float RotAngleY)
{

	float angle = radians(RotAngleY); //「度」を「ラジアン」に変換
	float SinData,CosData;
	sincos(angle,SinData,CosData); //sin(angle)とcos(angle)を計算する
	
	//頂点を回転させる
	OutputVertex OUT;
	OUT.position[0] = CosData*input.position[0] + SinData*input.position[2]; //x座標
	OUT.position[1] = input.position[1]; //y座標
	OUT.position[2] = -SinData*input.position[0] + CosData*input.position[2]; //z座標
	OUT.position[3] = input.position[3]; //w座標
	
	
	OUT.position = mul(modelViewMatrix, OUT.position); //透視投影
	OUT.color = input.color; //色はそのまま

	return OUT;
}

フラグメントシェーダ

//-------- 各種データ構造 --------//
struct OutputColor      //出力データ構造
{
        float3 color : COLOR;
};


//--------- フラグメントシェーダメイン関数 ------------//
OutputColor Cg_Fragment_Main(in float3 color : COLOR)
{
        OutputColor OUT;

        OUT.color = color; //色は線形補間
        
        return OUT;
}

メイン関数

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

//-------- 各種外部変数 -------------//
//Cg用変数
CGcontext CgContext; //コンテキスト
CGprofile CgVertexProfile;//頂点
CGprogram CgVertexProgram;
CGparameter modelview;//CGparameter型(透視投影行列を取得)
CGparameter RotAngle;

CGprofile CgFragmentProfile;//フラグメント
CGprogram CgFragmentProgram;


//-------- プロトタイプ宣言 -----//
void SET_UP_CG_VERTEX();
void SET_UP_CG_FRAGMENT();
void EnableCG();
void DisableCG();
void display();
void reshape(int w, int h);
void timer(int value);
void DRAW_XYZ();


//-------- OpenGLの初期設定 ---------//
void GLUT_INIT()
{
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(640,480);
	glutCreateWindow("Cg with Animation2");
}


void GLUT_CALL_FUNC()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutTimerFunc(0,timer,17);
}

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


//-------- Cgの初期設定 -----------//
void CG_INIT()
{
	//コンテキスト作成
	CgContext = cgCreateContext();
	if(CgContext == NULL){
		std::cerr << "Can't Create Context\n";
		exit(0);
	}

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

//頂点シェーダ設定
void SET_UP_CG_VERTEX()
{

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


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

	cgGLLoadProgram(CgVertexProgram);//プログラムのロード
	if(CgVertexProgram==NULL){
		std::cerr <<"Vertex Program Err. \n";
		exit(0);
	}


	//CGparameter型の名前を設定、シェーダファイルで「modelViewMatrix」という変数名
	modelview = cgGetNamedParameter(CgVertexProgram, "modelViewMatrix");
	RotAngle = cgGetNamedParameter(CgVertexProgram, "RotAngleY");
}


//フラグメントシェーダ設定
void SET_UP_CG_FRAGMENT()
{
	//プロファイル
	CgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
	if(CgFragmentProfile == CG_PROFILE_UNKNOWN){
		std::cerr << "Fragment : profile is unknown\n";
		exit(0);
	}
	cgGLSetOptimalOptions(CgFragmentProfile);

	//プログラムのコンパイル
	CgFragmentProgram 
		= cgCreateProgramFromFile(
							CgContext,//コンテキスト
							CG_SOURCE,//Cgソースコード
							"fragment.cg", //「.cgファイル名」
							CgFragmentProfile, //プロファイル
							"Cg_Fragment_Main", //「.cgファイル」で最初にいく関数
							NULL); //NULLでよい

	cgGLLoadProgram(CgFragmentProgram); //プログラムのロード
	if(CgFragmentProgram==NULL){
		std::cerr <<"Fragment Program Err. \n";
		exit(0);
	}
}

//Cgの有効化、無効化
void EnableCG()
{
	cgGLBindProgram(CgVertexProgram);
	cgGLEnableProfile(CgVertexProfile);

	cgGLBindProgram(CgFragmentProgram);
	cgGLEnableProfile(CgFragmentProfile);
}

void DisableCG()
{
	cgGLDisableProfile(CgVertexProfile);
	cgGLDisableProfile(CgFragmentProfile);
}

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

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

	return 0;
}



//----------- ここから各種コールバック -----------------//
void display()
{
	static float r = 0;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glLoadIdentity();
	gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

	cgGLSetStateMatrixParameter(modelview,CG_GL_MODELVIEW_PROJECTION_MATRIX,CG_GL_MATRIX_IDENTITY);
	cgSetParameter1f(RotAngle, r); //回転角度値の設定


	DRAW_XYZ();

	EnableCG();	//Cgの有効化
	
	glColor3f(1,0,1);
	glRectf(-1,1,1,-1);//描画

	DisableCG();//Cgの無効化
	
	glutSwapBuffers();

	
	if(++r > 360) r = 0;
}


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 timer(int t)
{
	display();
	glutTimerFunc(t,timer,17); //タイマー関数
}

//------------- ここから各種関数 -------------//
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();
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






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


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

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