現在地 >> メニュー >> サンプルコード::Cg >> Cg::uniform型? >> Cg::uniform型+構造体

問題


Cg::頂点ライティング?のプログラムを変更して、以下のようなuniform型の構造体を作成し、
同じ結果となるようにせよ。

struct MATERIAL //各種係数
{
float3 Ke;
float3 Ka;
float3 Kd;
float3 Ks;
float shininess;
};


struct EYE_AND_LIGHT //光源と視点の設定
{
float3 lightColor;
float3 lightPos;
float3 eyePos;
};

答え

[vertex.cg]



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



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


/* uniform用データ構造*/
struct MATERIAL //各種係数
{
float3 Ke;
float3 Ka;
float3 Kd;
float3 Ks;
float shininess;
};


struct EYE_AND_LIGHT //光源と視点の設定
{
float3 lightColor;
float3 lightPos;
float3 eyePos;
};


/******** メインエントリ関数 **********/
VERTEX_DATA_OUT Cg_Main(in VERTEX_DATA_IN IN ,
uniform float4x4 modelViewMatrix,
uniform float3 globalAmbient,
uniform EYE_AND_LIGHT Eye_And_Light,
uniform MATERIAL material
)
{

VERTEX_DATA_OUT OUT;

OUT.position = mul(modelViewMatrix, IN.position);//スクリーンの描画位置計算


float3 P = IN.position.xyz;
float3 N = IN.normal;


float3 emissive = material.Ke;//放射輝度

float3 ambient = material.Ka * globalAmbient; //環境光計算



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


float3 V = normalize(Eye_And_Light.eyePos - P);//Blinのモデルで計算
float3 H = normalize(L + V);
float specularLight = pow(max(dot(N, H), 0), material.shininess);
if (diffuseLight <= 0) specularLight = 0;
float3 specular = material.Ks * Eye_And_Light.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>


using namespace std;



/*** プロトタイプ宣言 ***/
inline void SET_UP_CG_VERTEX();
inline void GET_AND_SET_PARAM();
void SET_UP_CG_FRAGMENT();

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

void DRAW_XYZ();



/**************[OpenGLの設定]**********************/
inline void GLUT_INIT()
{
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(200,200);
}


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

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


/**************[Cgの設定]**********************/
/** Cg用変数 **/
CGcontext Cg_Cont;//コンテキスト
inline void CG_INIT()
{

/* コンテキスト */
Cg_Cont = cgCreateContext();
if(Cg_Cont == NULL)
{
cout << "Can't Create Context" << endl;
exit(0);
}

SET_UP_CG_VERTEX(); //頂点セットアップ

SET_UP_CG_FRAGMENT();//フラグメントセットアップ


}


/************* 頂点セットアップ ***************/
namespace{
CGprofile Vert_Prof;//プロファイル
CGprogram Vert_Prog;//プログラム
}

inline void SET_UP_CG_VERTEX()
{
/* プロファイルの設定 */
Vert_Prof = cgGLGetLatestProfile(CG_GL_VERTEX);
if(Vert_Prof == CG_PROFILE_UNKNOWN)
{
cout << "Invalid profile type" << endl;
exit(0);
}
cgGLSetOptimalOptions(Vert_Prof);


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

cgGLLoadProgram(Vert_Prog);
if(Vert_Prog==NULL)
{
CGerror Error = cgGetError();
cout << cgGetErrorString(Error) << endl;
exit(0);
}



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


}

/* 無名名前空間 */
namespace
{
CGparameter modelview;//モデルビュー行列
CGparameter globalAmb;
CGparameter lightColor,lightPosition;//光源の色と位置
CGparameter eyePosition; //視点位置
CGparameter Ke,Ka,Kd,Ks,shininess;//各種係数など

float myGlobalAmb[3] = { 0.2, 0.2, 0.2 };
float myLightColor[3] = { 1,1,1 };

const float Emissive[3] = {0.0, 0.0, 0.0},
Ambient[3] = {0.24725, 0.1995, 0.0745},
Diffuse[3] = {0.75164, 0.60648 , 0.22648},
Specular[3] = {0.628281, 0.555802,0.366065},
Shininess = 51.2,

look_at[4] = {3,4,5,1},
light_position[4] ={-3,4,5,1};

}


inline void GET_AND_SET_PARAM()
{
/* 名前の関連付け */
modelview = cgGetNamedParameter(Vert_Prog, "modelViewMatrix");
globalAmb = cgGetNamedParameter(Vert_Prog, "globalAmbient");

lightColor = cgGetNamedParameter(Vert_Prog, "Eye_And_Light.lightColor");
lightPosition = cgGetNamedParameter(Vert_Prog, "Eye_And_Light.lightPos");
eyePosition = cgGetNamedParameter(Vert_Prog, "Eye_And_Light.eyePos");

Ke = cgGetNamedParameter(Vert_Prog, "material.Ke");
Ka = cgGetNamedParameter(Vert_Prog, "material.Ka");
Kd = cgGetNamedParameter(Vert_Prog, "material.Kd");
Ks = cgGetNamedParameter(Vert_Prog, "material.Ks");
shininess = cgGetNamedParameter(Vert_Prog, "material.shininess");


/* 値の設定*/
cgSetParameter3fv(globalAmb,myGlobalAmb);

/* 視点と光源の設定 */
cgSetParameter4fv(eyePosition, look_at);
cgSetParameter4fv(lightPosition, light_position);
cgSetParameter3fv(lightColor,myLightColor);

/* 材質パラメータ */
cgSetParameter3fv(Ke, Emissive);
cgSetParameter3fv(Ka, Ambient);
cgSetParameter3fv(Kd, Diffuse);
cgSetParameter3fv(Ks, Specular);
cgSetParameter1f(shininess, Shininess);


}


/********* フラグメントのセットアップ *************/

CGprofile Frag_Prof;//フラグメント
CGprogram Frag_Prog;
void SET_UP_CG_FRAGMENT()
{
Frag_Prof = cgGLGetLatestProfile(CG_GL_FRAGMENT);
if(Frag_Prof == CG_PROFILE_UNKNOWN)
{
cout << "Fragment : profile is unknown" << endl;
exit(0);
}

cgGLSetOptimalOptions(Frag_Prof);


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

cgGLLoadProgram(Frag_Prog);
if(Frag_Prog==NULL)
{
CGerror Error = cgGetError();
cout << cgGetErrorString(Error) << endl;
exit(0);
}
}


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

GLUT_INIT();
glutCreateWindow("Cg with OpenGL");
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(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);

DRAW_XYZ();


/*Cgの有効化*/
cgGLBindProgram(Vert_Prog);
cgGLEnableProfile(Vert_Prof);

cgGLBindProgram(Frag_Prog);
cgGLEnableProfile(Frag_Prof);




glutSolidSphere(0.5,30,30);

cgGLDisableProfile(Vert_Prof);
cgGLDisableProfile(Frag_Prof);


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();

}

メモ


uniform型を構造体にまとめて引数にする場合、


[1]:構造体として普通に定義。

struct MATERIAL //各種係数
{
float3 Ke;
float3 Ka;
float3 Kd;
float3 Ks;
float shininess;
};


[2]:引数の時、uniformを追加する。
VERTEX_DATA_OUT Cg_Main(... ,uniform MATERIAL material, ...)
{
... ...
float3 ambient = material.Ka * globalAmbient; //環境光計算
... ...
}

また、「cppファイル」での名前の関連付けも以下のように「.cgファイル」で記述するものに合わせる必要がある。

Ke = cgGetNamedParameter(Vert_Prog, "material.Ke");
Ka = cgGetNamedParameter(Vert_Prog, "material.Ka");
Kd = cgGetNamedParameter(Vert_Prog, "material.Kd");
Ks = cgGetNamedParameter(Vert_Prog, "material.Ks");
shininess = cgGetNamedParameter(Vert_Prog, "material.shininess");

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






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


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

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