インタラクティブシステム構築法 第 5 回 OpenGL と GLUT の使い方 (3) 埼玉大学情報システム工学科小林貴訓
シェーディング 光源の設定を有効にする glenable(gl_lighting); // 光源の設定を有効にする glenable(gl_light0); //0 番目の光源を有効にする (8 個まで設定可能 ) 光源の位置 GLfloat light0pos[] = { 0.0, 5.0, 0.0, 1.0 ; gllightfv(gl_light0, GL_POSITION, light0pos); // 光源 0 を位置 (0.0, 5.0, 0.0) に設定 実際の 3 次元位置座標は同次座行系 (x, y, z, w) を用いて (x/w, y/w, z/w) で指定される. 普通は w=1.0 にしておき, 無限遠方にしたければ w=0.0 にする. また,glMatrixMode(GL_MODELVIEW); の後に書く.
シェーディング 光源の色 GLfloat light0ambi [] = { 0.2, 0.2, 0.2, 1.0 ; gllightfv(gl_light0, GL_AMBIENT, light0ambi); // 光源 0 の環境光の色を設定 GLfloat light0diff [] = { 0.8, 0.8, 0.8, 1.0 ; gllightfv(gl_light0, GL_DIFFUSE, light0diff); // 光源 0 の拡散光の色を設定 GLfloat light0spec [] = { 0.5, 0.5, 0.5, 1.0 ; gllightfv(gl_light0, GL_SPECULAR, light0spec); // 光源 0 の鏡面光の色を設定 鏡面光 拡散光 環境光 鏡面光拡散光環境光 材質 = 反射率
シェーディング 物体の材質の設定 GLfloat mat0ambi[] = { 0.2, 0.2, 0.2, 1.0 ; glmaterialfv(gl_front_and_back, GL_AMBIENT, mat0ambi); // 環境光の反射率を設定 GLfloat mat0diff[] = { 0.6, 0.2, 0.2, 1.0 ; glmaterialfv(gl_front_and_back, GL_DIFFUSE, mat0diff); // 拡散光の反射率を設定 GLfloat mat0spec[] = { 0.2, 0.2, 0.2, 1.0 ; glmaterialfv(gl_front_and_back, GL_SPECULAR, mat0spec); // 鏡面光の反射率を設定 環境光, 拡散光, 鏡面光のそれぞれに対して, それぞれの反射率を掛けたものを足しこんだものが実際に見える色になる GLfloat mat0shine[] = { 50.0 ; glmaterialfv(gl_front_and_back, GL_SHININESS, mat0shine); の指数を設定 (0-128で大きい方がピカッとした感じになる) // 鏡面光
シェーディング 法線ベクトルの設定 glenable(gl_normalize); // 法線ベクトルの自動正規化を有効 glnormal3f(0.0, 1.0, 0.0); // 法線方向の設定 glbegin(gl_quads); // 面の描画 glvertex3f( 1.0f, 0.0f, 1.0f); glvertex3f(-1.0f, 0.0f, 1.0f); glvertex3f(-1.0f, 0.0f,-1.0f); glvertex3f( 1.0f, 0.0f,-1.0f); glend(); 点や面には表と裏がある. 法線ベクトルで表裏が設定され, 光の反射も規定される. 材質設定の GL_FRONT_AND_BACK は表裏両面を描画する設定だった. glutsolidteapot などは既に設定済み 法線ベクトル
シェーディング シェーディングモードの設定 glshademodel(gl_smooth); // スムーズシェーディングに設定 様々な材質 真珠 GLfloat mat0ambi[] = {0.25, 0.20725, 0.20725, 1.0; GLfloat mat0diff[] = {1, 0.829, 0.829, 1.0; GLfloat mat0spec[] = {0.296648, 0.296648, 0.296648, 1.0; GLfloat mat0shine[] ={ 10.24; 真鍮 GLfloat mat0ambi[] = {0.329412, 0.223529, 0.027451, 1.0; GLfloat mat0diff[] = {0.780392, 0.568627, 0.113725, 1.0; GLfloat mat0spec[] = {0.992157, 0.941176, 0.807843, 1.0; GLfloat mat0shine[] ={ 27.89743616;
マウス入力 クリックイベントのコールバック関数の登録 glutmousefunc(mouse); // マウスクリックコールバック関数の指定 クリックイベントのコールバック関数 static int MouseLB_ON=0; // 左マウスボタン押下フラグ static int MouseRB_ON=0; // 右マウスボタン押下フラグ void mouse(int button, int state, int x, int y){ if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){ MouseLB_ON = 1; printf("(%3d,%3d) で左ボタンが押されました n", x, y); else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP){ MouseLB_ON = 0; printf("(%3d,%3d) で左ボタンを離しました n", x, y); else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){ MouseRB_ON = 1; printf("(%3d,%3d) で右ボタンが押されました n", x, y); else if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP){ MouseRB_ON = 0; printf("(%3d,%3d) で右ボタンを離しました n", x, y);
マウス入力 ドラッグイベントのコールバック関数の登録 glutmotionfunc(dragmotion); // マウスドラッグコールバック関数の指定 ドラッグイベントのコールバック関数 void dragmotion(int x, int y){ if (MouseLB_ON==1) printf( (%3d,%3d) で左ドラッグ中... n", x, y); else if (MouseRB_ON==1) printf( (%3d,%3d) で右ドラッグ中... n", x, y); マウス移動のコールバック関数の登録 glutpassivemotionfunc(passivemotion);// マウス移動コールバック関数の指定 マウス移動のコールバック関数 void passivemotion(int x, int y){ printf("(%3d,%3d) でマウス移動中... n", x, y);
キー入力 通常キーのコールバック関数 ( 押したとき ) の登録 glutkeyboardfunc(keyboard); // 通常キーコールバック関数の指定 ( 押したとき ) 通常キーのコールバック関数 ( 押したとき ) void keyboard(unsigned char key, int x, int y){ switch (key) { case '1': printf("(%3d,%3d) で 1 が押されました n", x, y); case '2': printf("(%3d,%3d) で 2 が押されました n", x, y); case '3': printf("(%3d,%3d) で 3 が押されました n", x, y);
キー入力 通常キーのコールバック関数 ( 離したとき ) の登録 glutkeyboardupfunc(keyboardup); // 通常キーコールバック関数の指定 ( 離したとき ) 通常キーのコールバック関数 ( 離したとき ) void keyboardup(unsigned char key, int x, int y){ switch (key) { case '1': printf("(%3d,%3d) で 1 が離されました n", x, y); case '2': printf("(%3d,%3d) で 2 が離されました n", x, y); case '3': printf("(%3d,%3d) で 3 が離されました n", x, y);
キー入力 特殊キーのコールバック関数 ( 押したとき ) の登録 glutspecialfunc(specialkey); // 特殊キーコールバック関数の指定 ( 押したとき ) 特殊キーのコールバック関数 ( 押したとき ) void specialkey(int key, int x, int y){ switch (key) { case GLUT_KEY_UP: printf("(%3d,%3d) で [ ] が押されました n", x, y); case GLUT_KEY_DOWN: printf("(%3d,%3d) で [ ] が押されました n", x, y); case GLUT_KEY_LEFT: printf("(%3d,%3d) で [ ] が押されました n", x, y); case GLUT_KEY_RIGHT: printf("(%3d,%3d) で [ ] が押されました n", x, y);
キー入力 特殊キーのコールバック関数 ( 離したとき ) の登録 glutspecialupfunc(specialkeyup); // 特殊キーコールバック関数の指定 ( 離したとき ) 特殊キーのコールバック関数 ( 離したとき ) void specialkeyup(int key, int x, int y){ switch (key) { case GLUT_KEY_UP: printf("(%3d,%3d) で [ ] が離されました n", x, y); case GLUT_KEY_DOWN: printf("(%3d,%3d) で [ ] が離されました n", x, y); case GLUT_KEY_LEFT: printf("(%3d,%3d) で [ ] が離されました n", x, y); case GLUT_KEY_RIGHT: printf("(%3d,%3d) で [ ] が離されました n", x, y);
キーリピート キーリピートを無効にするには以下を書く glutignorekeyrepeat(gl_true); // キーリピートを無効にする
演習 光源や材質の値を様々に変えて, 画像がどのように変化するかを確認しよう 素材の色を変える 照明の色を変える 法線ベクトルを変える 光源や物体を移動させてアニメーション マウスやキー入力でティーポットを様々に動かすプログラムを作ってみよう マウスの動きに合わせて物体を移動するプログラム 物体を移動させる代わりに視点を移動させるプログラム キーボードを用いて物体を並進 回転させるプログラム
来週 来週は自習です課題として以下のプログラムを作成してください オブジェクトを2つ作って, 片方をキーボードで操作して, もう片方に近づいたら色を変える 時間が余ったら, これまでの内容を使った CGアニメーションを作成してください例 : 太陽系シミュレータを高度化する 基本形状を組み合わせて, ロボットの上半身をつくる 手を振る, 頷くなどのアニメーションを作る基本形状を組み合わせて, 手を作る グーからパー, パーからチョキなどのアニメーションを作る