現在地メニュー >> Cg >> Cg編05 >> Cg編05::ライティング1 >> Cg編05::まとめ1

問題


ライティングを行え。
その他条件:
  • オブジェクト座標系でライティングする
  • オブジェクトとワールド座標系が一致した状態でよい

答え

main.cpp

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

#pragma comment (lib,"cg.lib")
#pragma comment (lib,"cgGL.lib")

//-------- 各種外部変数 -------------//
//Cg用変数
CGcontext CgContext; //コンテキスト
CGprofile CgVertexProfile;//頂点プロファイル
CGprogram CgVertexProgram;
CGprofile CgFragmentProfile;//フラグメントプロファイル
CGprogram CgFragmentProgram;
CGparameter CgModelViewProj; //CGparameter型(ModelProj行列を取得)
CGparameter CgObjEye;//オブジェクト空間用
CGparameter CgObjLight;

//視点位置
float worldEyePos[]={3,4,5};
//光源位置
float worldLightPos[]={-1,1,1,1};

//-------- プロトタイプ宣言 -----//
void display();
void reshape(int w, int h);
void drawXYZ();
void runShader();

//-------- Cgの初期設定 -----------//
//頂点シェーダ設定
void setUpCgVertex()
{
	//プロファイルの取得
	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, //プロファイル
		"CgVertexMain", //「.cgファイル」で最初にいく関数
		NULL); //NULLでよい

	cgGLLoadProgram(CgVertexProgram);//プログラムのロード
	if(CgVertexProgram==NULL){
		std::cerr <<"Vertex Program Err. \n";
		exit(0);
	}
	//パラメータの関連付け
	CgModelViewProj = cgGetNamedParameter(CgVertexProgram, "modelViewProj");
	CgObjEye = cgGetNamedParameter(CgVertexProgram,"objEye");
	CgObjLight = cgGetNamedParameter(CgVertexProgram,"objLight");

}

//フラグメントの初期設定
void setUpCgFragment()
{
	//プロファイルの取得
	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, //プロファイル
		"CgFragmentMain", //「.cgファイル」で最初にいく関数
		NULL); //NULLでよい

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

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

	setUpCgVertex();
	setUpCgFragment();
}


//------------ GLUTの初期設定 ---------------//
void GLUT_CALL_FUNC()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
}

void OtherMyInit()
{
	glClearColor(1,1,1,1);
	glEnable(GL_DEPTH_TEST);
}

void GLUT_INIT(int argc,char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(640,480);
	glutCreateWindow("Basic lighting");
	GLUT_CALL_FUNC();
	OtherMyInit();
}
//---------- メイン関数 ---------------//
int main(int argc,char **argv)
{
	GLUT_INIT(argc,argv);
	CgINIT();//Cgセットアップ
	glutMainLoop();

	return 0;
}

//----------- ここから各種コールバック -----------------//
void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	gluLookAt(worldEyePos[0],worldEyePos[1],worldEyePos[2],0,0,0,0,1,0);

	runShader();//シェーダ

	drawXYZ();//ここは普通の描画
	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 drawXYZ()
{
	glBegin(GL_LINES);

	glColor3f(1,0,0);
	glVertex3f(0,0,0);
	glVertex3f(200,0,0);

	glColor3f(0,1,0);
	glVertex3f(0,0,0);
	glVertex3f(0,200,0);

	glColor3f(0,0,1);
	glVertex3f(0,0,0);
	glVertex3f(0,0,200);

	glEnd();

	glColor3f(1,1,1);
}

void setUpCgParams()
{
	//ここで視点と光源をオブジェクト空間にして、シェーダに与える
	//今回は特に移動が無いのでそのままでOK
	cgSetParameter3fv(CgObjEye,worldEyePos);
	cgSetParameter4fv(CgObjLight,worldLightPos);
}

void runShader()
{
	 //Cgの有効化
	cgGLBindProgram(CgVertexProgram);
	cgGLEnableProfile(CgVertexProfile);

	cgGLBindProgram(CgFragmentProgram);
	cgGLEnableProfile(CgFragmentProfile);


	setUpCgParams();

	//現在のmodelview,projection行列を取得
	cgGLSetStateMatrixParameter(CgModelViewProj,
		CG_GL_MODELVIEW_PROJECTION_MATRIX,
		CG_GL_MATRIX_IDENTITY);


	cgUpdateProgramParameters(CgVertexProgram);//プログラムのパラメータの更新

	glColor3f(0,1,0);
	glutSolidSphere(0.5,60,60);

	//Cgの無効化
	cgGLDisableProfile(CgVertexProfile);
	cgGLDisableProfile(CgFragmentProfile);
}

vertex.cg

//入力頂点
struct VertexIn
{
	float4 position : POSITION;
	float3 color : COLOR;
	float4 normal : NORMAL;
};

//出力頂点
struct VertexOut
{
	float4 position : POSITION;
	float3 color : COLOR;
};


//------- 頂点計算のルーチン -------------//
float3 calcVertexLighting(VertexIn input, 
						uniform float3 objEye,
						uniform float4 objLight)
{
	float3 eyeVec = normalize(objEye - input.position.xyz);//視点へのベクトル
	float3 lightVec = normalize(objLight.xyz - input.position.xyz);//光源へのベクトル
	float3 halfVec = normalize(eyeVec + lightVec);
	float3 normalVec = normalize(input.normal.xyz);
	
	float NL = dot(normalVec,lightVec);
	float NH = dot(normalVec,halfVec);

	float3 lightColor = float3(1,1,1);//光の色は(1,1,1)
	float4 lightingCoff = lit(NL,NH,52); 

	float3 ambMaterial = float3( 0.24725, 0.1995, 0.0745);
	float3 diffMaterial = float3(0.75164, 0.60648 , 0.22648);
	float3 specMaterial = float3(0.628281, 0.555802,0.366065);

	float3 color = lightColor * lightingCoff.x * ambMaterial
				+ lightColor * lightingCoff.y * diffMaterial
				+ lightColor * lightingCoff.z * specMaterial;

	return color;
}


//-------- 頂点シェーダメイン関数 ---------//
VertexOut CgVertexMain(in VertexIn input,
					   uniform float4x4 modelViewProj,
					   uniform float3 objEye,
					   uniform float4 objLight
					   )
{
	VertexOut output;//出力用
	//位置は普通に変換
	output.position = mul(modelViewProj, input.position);

	//ここから頂点の色の計算
	output.color = calcVertexLighting(input, objEye, objLight);

	return output;
}

fragment.cg

//フラグメントの入力
struct FragmentIn
{
	float4 position : POSITION; //ラスタライズ用(使用しない)
	float3 color : COLOR;
};

//フラグメントの出力
struct FragmentOut
{
	float3 color : COLOR;
};

//--------- フラグメントシェーダメイン関数 ------------//
FragmentOut CgFragmentMain(in FragmentIn input)
{
	FragmentOut output;//フラグメント出力
	output.color = input.color;

	return output;
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






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


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

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