最終更新: mikk_ni3_92 2009年03月27日(金) 17:11:08履歴
現在地 >> メニュー >> サンプルコード::Cg >> Cg::基本編07 >> Cg::基本編07まとめ1
//----- 入力データ構造 ----// 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; }
void Cg_Fragment_Main(in float4 in_color : COLOR, out float4 out_color : COLOR) { out_color = in_color; }
#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(); }