現在地 >> メニュー >> サンプルコード::Cg >> Cg::基本編07 >> Cg::基本編07まとめ1

問題


頂点シェーダ部分で光源、視点、材質から色計算をせよ。

答え

vertex.cg

//----- 入力データ構造 ----//
struct VERTEX_DATA_IN
{
	float4 position : POSITION;
	float3 normal : NORMAL;
};



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

//------- uniform型の各種データ ---------//
struct UNIFORMS
{
	float4x4 modelViewMatrix;
	float3 globalAmbient;
	float3 lightColor;
	float3 lightPos;
	float3 eyePos;
	float3 Ke;
	float3 Ka;
	float3 Kd;
	float3 Ks;
	float shininess;
};


//---------- メイン関数 -------------//
VERTEX_DATA_OUT Cg_Main(in VERTEX_DATA_IN IN ,uniform UNIFORMS uniforms)
{
	VERTEX_DATA_OUT OUT;

	//透視投影
	OUT.position = mul(uniforms.modelViewMatrix, IN.position);

	//位置、法線を取得
	float3 P = IN.position.xyz;
	float3 N = IN.normal;


	float3 emissive = uniforms.Ke;//放射輝度
	float3 ambient = uniforms.Ka * uniforms.globalAmbient; //環境光計算


	//ランバート反射
	float3 L = normalize(uniforms.lightPos - P);
	float diffuseLight = max(dot(N, L), 0);
	float3 diffuse = uniforms.Kd * uniforms.lightColor * diffuseLight;


	//Blinのモデルでの計算
	float3 V = normalize(uniforms.eyePos - P);//Blinのモデルで計算
	float3 H = normalize(L + V);
	float specularLight = pow(max(dot(N, H), 0), uniforms.shininess);
	if (diffuseLight <= 0){
		specularLight = 0;
	}
	
	float3 specular = uniforms.Ks * uniforms.lightColor * specularLight;

	//phongのモデル
	//float3 V = normalize(uniforms.eyePos - P);//phongのモデルでの計算
	//float3 R = normalize(2*dot(L,N)*N - L);
	//float specularLight = pow(max(dot(R,V), 0), uniforms.shininess);
	//if (diffuseLight <= 0){ 
		//specularLight = 0;
	//}
	//float3 specular = uniforms.Ks * uniforms.lightColor * specularLight;


	//色の決定
	OUT.color.xyz = emissive + ambient + diffuse + specular;
	OUT.color.w = 1;
	return OUT;

}

fragment.cg

void Cg_Fragment_Main(in float4 in_color : COLOR, out float4 out_color : COLOR)
{
	out_color = in_color;
}

main.cpp

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

//---------データ構造の定義------------//
float EyePosition[4] = {3,4,5,1};


//光源データ構造
struct LIGHTDATA
{
	float GlobalAmb[3];//環境光
	float Color[3];//光源の色
	float position[4];//位置(x,y,z,w)
};
LIGHTDATA Light= {{ 0.2, 0.2, 0.2 },{ 1,1,1 },{-3,4,5,1}};

//材質データ構造
struct MATERIALDATA
{
	float Emissive[3];//放射輝度
	float Ambient[3];//環境光
	float Diffuse[3];//拡散反射光 
	float Specular[3];//鏡面光
	float Shininess;//輝度
};
//初期設定(金色)
MATERIALDATA MaterialData =
{
	{0.0, 0.0, 0.0},{0.24725, 0.1995, 0.0745},
	{0.75164, 0.60648 , 0.22648},{0.628281, 0.555802,0.366065},
	51.2
};



//---------- プロトタイプ宣言 ----------------//
void SetUpVertexShader();
void SetUpCgParametersV();
void GetNameforCgV();
void SetValtoCgParamV();
void SetUpFragmentShader();

void display(void);
void reshape(int w, int h);

void DRAW_XYZ();



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


void GLUT_CALL_FUNC()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
}

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


//----------- Cgの設定 ---------------//

//Cg用グローバル変数
CGcontext Cg_Cont; //コンテキスト

struct PROFANDPROG
{
	CGprogram Program;
	CGprofile Profile;
};
PROFANDPROG CgVertex;
PROFANDPROG CgFragment;



struct CGPARAMETERS
{
	CGparameter modelview;//モデルビュー行列
	CGparameter globalAmb;
	CGparameter lightColor,lightPosition;//光源の色と位置
	CGparameter eyePosition; //視点位置
	CGparameter Ke,Ka,Kd,Ks,shininess;//各種係数など
};
CGPARAMETERS CgParameters;


void CG_INIT()
{

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

	SetUpVertexShader(); //頂点セットアップ
	SetUpFragmentShader();//フラグメントセットアップ

}


//----------  頂点セットアップ  -----------------------//
void SetUpVertexShader()
{
	//---------- プロファイルの設定 -----------//
	CgVertex.Profile = cgGLGetLatestProfile(CG_GL_VERTEX);
	if(CgVertex.Profile == CG_PROFILE_UNKNOWN)
	{
		std::cout << "Invalid profile type\n";
		exit(0);
	}
	cgGLSetOptimalOptions(CgVertex.Profile);

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

	cgGLLoadProgram(CgVertex.Program);
	if(CgVertex.Program==NULL)
	{
		std::cout << cgGetErrorString(cgGetError()) << std::endl;
		exit(0);
	}


	SetUpCgParametersV();//パラメータセットアップ

}



//CgParameter型をセットアップ
void SetUpCgParametersV()
{
	GetNameforCgV();  //名前
	SetValtoCgParamV(); //値
}


//--- Cgファイル内でのunform変数の名前付け---//
void GetNameforCgV()
{
	CgParameters.modelview = cgGetNamedParameter(CgVertex.Program, "uniforms.modelViewMatrix");
	CgParameters.globalAmb = cgGetNamedParameter(CgVertex.Program, "uniforms.globalAmbient");

	//光源
	CgParameters.lightColor = cgGetNamedParameter(CgVertex.Program, "uniforms.lightColor");
	CgParameters.lightPosition = cgGetNamedParameter(CgVertex.Program, "uniforms.lightPos");
	
	//材質
	CgParameters.Ke = cgGetNamedParameter(CgVertex.Program, "uniforms.Ke");
	CgParameters.Ka = cgGetNamedParameter(CgVertex.Program, "uniforms.Ka");
	CgParameters.Kd = cgGetNamedParameter(CgVertex.Program, "uniforms.Kd");
	CgParameters.Ks = cgGetNamedParameter(CgVertex.Program, "uniforms.Ks");
	CgParameters.shininess = cgGetNamedParameter(CgVertex.Program, "uniforms.shininess");
	
	//視点の位置
	CgParameters.eyePosition = cgGetNamedParameter(CgVertex.Program, "uniforms.eyePos");
}

//------------- 値の設定  -------------------//
void SetValtoCgParamV()
{
	/* 値の設定*/
	cgSetParameter3fv(CgParameters.globalAmb, Light.GlobalAmb);

	/* 視点と光源の設定 */
	cgSetParameter4fv(CgParameters.lightPosition, Light.position);
	cgSetParameter3fv(CgParameters.lightColor, Light.Color);
	cgSetParameter4fv(CgParameters.eyePosition, EyePosition);
	
	/* 材質パラメータ */
	cgSetParameter3fv(CgParameters.Ke, MaterialData.Emissive);
	cgSetParameter3fv(CgParameters.Ka, MaterialData.Ambient);
	cgSetParameter3fv(CgParameters.Kd, MaterialData.Diffuse);
	cgSetParameter3fv(CgParameters.Ks, MaterialData.Specular);
	cgSetParameter1f(CgParameters.shininess,MaterialData.Shininess);
}

//--------- フラグメントセットアップ -----------------//

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

	cgGLSetOptimalOptions(CgFragment.Profile);


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

	cgGLLoadProgram(CgFragment.Program);
	if(CgFragment.Program==NULL)
	{
		std::cout << cgGetErrorString(cgGetError()) << std::endl;
		exit(0);
	}
}


//----------- メイン関数 ----------------//
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);

	glLoadIdentity();
	gluLookAt(EyePosition[0], EyePosition[1], EyePosition[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	

	DRAW_XYZ();

	//行列取得
	cgGLSetStateMatrixParameter(CgParameters.modelview,CG_GL_MODELVIEW_PROJECTION_MATRIX,CG_GL_MATRIX_IDENTITY);

	


	//---- Cgの有効化  ----//
	cgGLBindProgram(CgVertex.Program);
	cgGLEnableProfile(CgVertex.Profile);

	cgGLBindProgram(CgFragment.Program);
	cgGLEnableProfile(CgFragment.Profile);



	glutSolidSphere(0.5,60,60);

	cgGLDisableProfile(CgVertex.Profile);
	cgGLDisableProfile(CgFragment.Profile);


	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 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






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


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

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