最終更新: mikk_ni3_92 2009年12月20日(日) 17:48:28履歴
現在地:メニュー >> Cg >> Cg編05 >> Cg編05::ライティング1 >> Cg編05::まとめ1
#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); }
//入力頂点 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; }
//フラグメントの入力 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; }