コンピューターグラフィックスS 第13回 OpenGL演習(3) システム創成情報工学科 尾下真樹 今日の内容 • 試験とレポート • OpenGL演習 – 文字の描画 – テクスチャマッピング • より高度な演習 • 昔の演習問題の解答(確認) 試験とレポート スケジュール • 7/30(月) 5限目 試験 • 8/22(水) レポート提出締め切り – 8/14 → 8/22に延長 (8/13~8/17は情報科学セン タが休みのため) • 成績は、レポート締め切り終了後、なるべく 早く公開予定 • レポートの大まかな点数とコメントを個別に 公開する予定 – レポート提出と同じシステム上で個別に提示 レポートに関する連絡 • 提出締め切り – 8/22(水) 17:00 • 講義のページから提出 – ファイル形式を守ること – 提出後は、自分でダウ ンロードして表示できる ことを確認すること • 読めないファイルを提出 しても評価しない – 締め切りまで修正可能 レポートに関する注意 • ファイル形式 – c のソースファイル(拡張子 c または cpp) – 必ずコンパイルできるファイルを提出すること • 提出後のファイルをダウンロードして、コンパイルでき ることを確認すること • レポート – 必ず、レポートの説明とプログラムが一致してい ること (変換行列の計算) – 他人のレポートやプログラムを、たとえ一部でも 丸写ししているものは不可(0点) – 個別に試問等を行う場合がある 試験 • 教科書・ノートなどの持込は不可 • 出題範囲 – 講義で取り扱った内容全て – 重要な概念を理解しているかどうか、アルゴリズ ムや考え方を理解しているかどうかを問う問題 を出す – 演習問題・過去問や講義資料を眺めておくだけ では不十分だと思われるので注意 • 講義資料は、あくまで講義の補助資料なので、講義 の説明をきちんと聞いて理解していなければ、後から 資料だけ見ても理解できない 成績判定と再試験 • 成績判定(シラバス通り) – 演習レポート 50点+試験 50点 +毎回の演習問題・課題(20点) • 再試験は基本的に行わない(シラバス通り) – もし、再試験を行う場合は、 • 全員受験可能とする • 本試験と同じ難易度の問題を出す • 試験点は、再試験の点数に80%をかけたものとする – 再試験・レポート再提出等を場合は、夏休み~ 再試期間中に連絡する • いちいち個別に質問に来ないこと 文字の描画 文字の描画 • プログラムでは、何らかの情報を表示するた め、画面に文字を表示したいことがある • Windowsでは、Win32 API の GDI を使用 することで、本来は簡単に文字を描画できる • OpenGLのダブルバッファリングを使用して いると、この機能は使えない • 何らかの描画方法を使う必要がある 文字の描画方法 • 基本的なやり方 – あらかじめ必要な文字 を並べた画像を用意 – その画像から画面上に 1文字ずつコピーするこ とで画面上に文字を描画 – (昔のゲーム専用機などで よく用いられた手法) ABCDE… HIJKL… 1234… • 実現方法 – GLUTには内部でこのような機能を実現してくれる関数 があるので、それを利用する – ただし、基本的に数字やアルファベットのみしか使えな い(日本語は不可) 文字の描画の手順 • 描画の初期化 – 射影行列 • 座標を指定しやすいように並行投影行列を設定 – ウィンドウサイズの情報を使用して設定 – モデルビュー行列 • 同じく単位行列に設定 – その他、ライティングやZバッファなどの不要な 機能はオフにする • 描画の設定 – 描画の位置や色を指定 文字の描画の手順 • 1文字描画の関数を使用 – glutBitmapCharacter( フォント, 文字コード) – 描画の後は、自動的に描画位置が1文字分横 に移動するので、続けて次の文字を描画できる – フォントの種類は、いくつかのものが定義されて いる(関数説明の資料参照) • 描画に必要なピクセル幅の計算 – glutBitmapWidth( フォント, 文字コード) – 指定した文字を描画するのに何ピクセル必要か が求まるので、レイアウトに使用できる プログラムの修正 • ウィンドウサイズの記録 – グローバル変数を定義 – ウィンドウサイズ変更時(reshape()関数)に更新 • 描画処理(drawMessage()関数) – – – – – – 平行射影行列の設定 モデルビュー行列の初期化 Zバッファやライティングの機能をオフにする 描画色・位置の設定 描画 設定を元に復元(各行列、描画設定) ウィンドウサイズの記録 • グローバル変数を定義 // ウィンドウのサイズを記録するための変数 static int win_width; static int win_height • ウィンドウサイズ変更時のコールバック関数 void reshape( int w, int h ) { ・・・・ // ウィンドウのサイズを記録(テキスト描画処理のため) win_width = w; win_height = h; } 文字の描画設定・描画処理(1) void drawMessage( int x, int y, const char * message ) { // 射影行列を初期化(初期化の前に現在の行列を退避) glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); gluOrtho2D( 0.0, win_width, win_height, 0.0 ); // モデルビュー行列を初期化(初期化の前に現在の行列を退避) glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); // Zバッファ・ライティングをオフにする glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); 文字の描画設定・描画処理(2) ・・・・ // メッセージの描画 glRasterPos2i( x, y ); for ( i=0; message[i]!='\0'; i++ ) glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, message[i] ); // 設定を全て復元 glEnable( GL_DEPTH_TEST ); glEnable( GL_LIGHTING ); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopMatrix(); } テクスチャマッピング テクスチャマッピング(復習) • マッピング – 面を描画する時に、面の表面に画像を貼り付け る技術 – 複雑なモデリングをすることなく、細かい模様な どを表現できる 基礎知識 図3-19 基礎と応用 図5.2 マッピングの方法(復習) • 物体への画像の貼り付け方 – マッピングの方向や繰り返し の方法 • uv座標系 基礎と応用 図5.3 – テクスチャ画像の座標は(u,v) で表せる – モデルデータの各頂点(x,y,z)ごとに、対応する テクスチャ画像の(u,v)座標を与えておく マッピングの例(復習) • 人体モデルへのマッピングの例 v u 各頂点にテクスチャの(u,v)座標を設定 テクスチャマッピング • 地面にテクスチャマッピングを適用して描画 – 各頂点に、テクスチャ座標(u,v)を指定 v (0.0, 1.0) u (0.0, 0.0) (1.0, 1.0) (1.0, 0.0) プログラムの修正 • コンパイル方法(bitmap.cを一緒にコンパイル) – gcc opengl.c bitmap.c ・・・(後は同じ) • プログラムの修正箇所 – テクスチャ画像を格納する変数を追加 – テクスチャ画像の読み込み処理、テクスチャマッ ピングの設定処理、を追加 • 画像の読み込みには bitmap.cpp の関数を使用 – 地面にテクスチャマッピングを行う処理を追加 • テクスチャマッピングの有効化 • 各頂点にテクスチャ座標を設定 ウィンドウサイズの記録 • グローバル変数を定義 // テクスチャ画像データ int tex_width; int tex_height; unsigned char * tex_image = NULL; • ヘッダファイルのインクルードの追加 – bitmap.h は、こちらで用意している BMP画像読 み込み関数の定義されたヘッダファイル // Bitmap読み込み関数のためのヘッダファイルのインクルード #include "bitmap.h" テクスチャ画像読み込み テクスチャマッピングの設定 void initEnvironment( void ) { ・・・・・・ // テクスチャ画像の読み込み loadBitmap( "kyushu.bmp", &tex_image, &tex_width, &tex_height ); if ( tex_image == NULL ) return; // テクスチャオブジェクトの設定 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_image ); // テクスチャマッピングの方法を設定 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); } テクスチャマッピングを使った描画 // 地面を描画(テクスチャマッピング) glEnable( GL_TEXTURE_2D ); glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL ); glBegin( GL_POLYGON ); glNormal3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 5.0, 0.0, 5.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 5.0, 0.0,-5.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f(-5.0, 0.0,-5.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f(-5.0, 0.0, 5.0 ); glEnd(); glDisable( GL_TEXTURE_2D ); テクスチャマッピングの手順 • テクスチャ画像の読み込み • テクスチャ画像を登録 • テクスチャマッピングのパラメタや、テクス チャ画像の適用方法を設定 • 各頂点ごとにテクスチャ座標(u,v)を指定す ることで、テクスチャ画像の一部がポリゴン に貼り付けられる テクスチャ画像の読み込み • 画像をファイルから配列に読み込む – OpenGLは、画像の読み込みはサポートしてい ないので、別のライブラリや、自作関数を使用す る必要がある – サンプルプログラムでは、24ビットBMP画像を配 列に読み込む関数を作成している 各1バイト(8ビット) 配列データ R G B R G B R G B R G B ・・・・・ ピクセル1 ピクセル2 ピクセル3 ピクセル4 テクスチャ画像の登録 • テクスチャマッピングを行うために、配列に 格納された画像データを登録する • glTextureImage2D()関数 – 画像データの形式、サイズなどを指定 • GL_RGB・・・RGB 形式 • GL_RGBA・・・RGB+不透明度(A) 形式 • GL_UNSIGNED_BYTE・・・各色ごとに1バイト – 画像データを設定 テクスチャマッピングのパラメタ設定 • glTexParameter()関数 – GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER • テクスチャの拡大縮小方法の設定 • GL_NEAREST・・・一番近くのピクセルのみ使用 • GL_LINEAR・・・近くのピクセルの色を補間して使用 – GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T • テクスチャの繰り返しを行うかどうかの設定 • GL_REPEATE or GL_CLAMP テクスチャマッピングの適用方法 • glTexEnv()関数 – GL_REPLACE • 単純にテクスチャ画像を貼り付ける • 光源処理は行われないので、常に色は一定 – GL_DECAL • テクスチャ画像のアルファ値に応じて、ポリゴンと テクスチャの色を混合 • ポリゴンを白にしておけば、光源による明るさの変化を 再現できる • テクスチャ画像にアルファ値がなければGL_REPLACE と同じになることに注意 テクスチャマッピングの適用方法 • glTexEnv()関数 (続き) – GL_MODULATE • ポリゴンの色にテクスチャ画像の値をかける • テクスチャ画像には、画像データの代わりに、明るさの 情報を入れておく – GL_BLEND • 別に設定した固定色とポリゴン画像を、テクスチャ画像 の値に応じて混合 • テクスチャ画像には、画像データの代わりに、混合比の 情報を格納しておく テクスチャマッピング • 各頂点ごとに、頂点座標・色・法線に加えて、 テクスチャ座標(u,v)を指定する v (0.0, 1.0) u (0.0, 0.0) (1.0, 1.0) (1.0, 0.0) 複数テクスチャの使用 • 複数テクスチャを使用する場合は、テクス チャごとに、テクスチャを切り替える • 毎回、glTextureImage2D()を行うと時間が かかる • glTextureBind()関数で、登録したテクス チャ情報を記録しておき、切り替えられる • テクスチャの切り替えはなるべく少なくする – 同じテクスチャ画像を使用するポリゴンはまとめ て描画する より高度な演習 より高度な演習 • 本講義の演習で扱ったのは、グラフィックス プログラミングの基本的な(最も重要な)内容 – コンピュータゲームなども、本講義の演習でやっ た内容を発展させることで、作ることができる • より高度な内容をやりたい人は、各自で勉強 してみることをすすめます – 本やインターネットで、自分で勉強 – 大学院講義「コンピュータグラフィックス特論Ⅱ」 • 後期開講、学部生も履修可能(大学院に入学後に自 動的に単位として認定される) より高度な演習の例(大学院の講義) • 幾何形状データの読み込み • 影の表現 • キーフレームアニメーション • 物理シミュレーションと衝突判定 • 動作データの読み込みと表示 • 逆運動学 • 詳しくは大学院の講義のページを参照 – http://www.cg.ces.kyutech.ac.jp/lecture/cg2/ 昔の演習問題の解答(確認) 変換行列の計算 演習問題(第7回) • 下記のようなシーンがある時、モデル座標系 からカメラ座標系への変換行列を求めよ – 物体の位置が(-5,0,3)にあり、Y軸周りに-30 度回転した向きにある – カメラの位置が(7,4,2)にあり、Y軸周りに90度回 転した向きにある x y y (-5,0,3) z z x x z y (7,4,2) 解答 cos 90 0 sin 90 0 0 sin 90 1 0 0 cos 90 0 0 01 00 00 0 1 0 0 7 1 1 0 4 0 0 1 2 0 0 0 1 0 0 0 5 cos 30 1 0 0 0 0 1 3 sin 30 0 0 1 0 0 sin 30 1 • 検算 – 変換行列を計算すると、以下のようになる 1/ 2 0 3/2 0 0 3/2 1 0 0 0 1/ 2 0 1 4 12 1 0 0 cos 30 0 0 0 0 0 1 変換行列の検算 cos 90 0 sin 90 0 0 sin 90 1 0 0 cos 90 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 3 / 2 1 0 0 0 0 0 0 1/ 2 0 0 1 0 1/ 2 0 3/2 0 0 3/2 1 0 0 0 1/ 2 0 01 00 00 0 1 0 0 7 1 1 0 4 0 0 1 2 0 0 0 1 0 0 1 0 0 1 4 12 1 0 0 7 1 1 0 4 0 0 1 2 0 0 0 1 0 0 0 5 3 / 2 1 0 0 0 0 1 3 1/ 2 0 0 1 0 12 0 4 3/2 1 0 1 1/ 2 0 0 5 cos 30 1 0 0 0 0 1 3 sin 30 0 0 1 0 0 1 0 0 0 0 0 3 / 2 0 0 1 1/ 2 0 sin 30 1 0 0 cos 30 0 0 0 0 0 1 検算 • モデル座標系の (0,0,0) に変換行列を適用し、変換後の座 標を計算すると、変換後の座標は (-1,-4,-12) となる。シー ンを見ると、モデル座標系の原点は、カメラから見て、カメラ の奥方向の、やや左下の位置にある。変換後の座標もそ のような値になっているので、この変換行列は妥当であると 考えられる。 • また、モデル座標系の (0,0,1) に変換行列を適用し、変換 後の座標を計算すると、変換後の座標は ( -1.87,-4,-12.5 ) となる。シーンを見ると、モデル座標系の (0,0,1) の位置は、 カメラから見て、モデル座標系の原点よりも、やや左方向の、 さらにやや奥の位置にある。変換後の座標もそのような値 になっているので、この変換行列は妥当であると考えられ る。 検算 1/ 2 0 3/2 0 1/ 2 0 3/2 0 0 3/2 1 0 0 0 1/ 2 0 0 3/2 1 0 0 0 1/ 2 0 1 0 1 4 0 4 0 12 12 1 1 1 1 0 3 / 2 1 1.87 4 0 4 4 1 1/ 2 12 12.5 12 1 1 1 1 演習問題(第8回) • 下記のようなシーンがある時、モデル座標系 からカメラ座標系への変換行列を求めよ – オブジェクト(車)の位置が(-1, 0, 5)にあり、Y 軸を中心として-30度回転した向きにある。 – カメラの位置が( 5, 12, 2)にあり、ワールド座標 系から見て水平方向に90度回転(ワールド座標 系のY軸を中心として90度回転)、水平面に対し て上下方向に-60 度回転(カメラ座標系のX軸 を中心として-60度回転)した状態にある。 演習問題(第8回) y z x (5,12,2) y y (-1,0,5) z x x z 解答 0 0 1 0 cos 60 sin 60 0 sin 60 cos 60 0 0 0 0 cos 90 0 0 0 sin 90 1 0 0 sin 90 1 0 0 cos 90 0 0 01 00 00 1 0 5 1 1 0 12 0 0 1 2 0 0 0 1 0 0 0 0 0 1 cos 30 1 0 0 0 0 1 5 sin 30 0 0 1 0 0 sin 30 0 1 0 0 0 cos 30 0 0 0 1 • 検算 – 変換行列をTと置いて計算すると、以下のように なる 1/ 2 3/ 4 T 3/4 0 0 1/ 2 3/2 0 3/2 3/4 1/ 4 0 0.5 0 0.87 3 6 3 3 0.75 0.5 0.43 0.81 0.43 0.87 0.25 13.38 6 3 3 0 0 0 1 1 3 変換行列の検算 0 0 1 0 cos 60 sin 60 0 sin 60 cos 60 0 0 0 0 cos 90 0 0 0 sin 90 1 0 0 sin 90 1 0 0 cos 90 0 0 1 0 0 0 00 1/ 2 3 / 2 0 0 3/2 1/ 2 01 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 00 1/ 2 3 / 2 0 0 3/2 1/ 2 01 0 0 1 0 0 1 0 3 / 2 1 0 0 0 0 0 0 1/ 2 0 0 1 0 1 0 0 0 0 1/ 2 1/ 2 3 / 2 0 0 3/2 1/ 2 0 3 / 2 0 0 1 0 0 0 0 0 0 1/ 2 3 / 4 3/4 0 0 0 1/ 2 3/2 0 3/2 3/4 1/ 4 0 0 3/2 1 0 0 0 1/ 2 0 6 3 3 6 3 3 1 3 01 00 00 1 0 5 1 1 0 12 0 0 1 2 0 0 0 1 0 0 0 0 1 0 0 3 12 6 1 5 1 1 0 12 0 0 1 2 0 0 0 1 0 0 0 0 0 1 3 / 2 1 0 0 0 0 1 5 1/ 2 0 0 1 0 6 0 12 3/2 3 0 1 1/ 2 0 0 1 cos 30 1 0 0 0 0 1 5 sin 30 0 0 1 0 0 1 0 0 0 0 0 3 / 2 0 0 1 1/ 2 0 sin 30 0 1 0 0 0 cos 30 0 0 0 1 検算 • モデル座標系の (0,0,0) に変換行列を適用し、変 換後の座標を計算すると、変換後の座標は (-3, 0.81, -13.38) となる。シーンを見ると、モデル座標 系の原点は、カメラから見て、カメラの奥方向の、 少し左、さらに少し下の位置にある。変換後の座標 もそのような値になっているので、この変換行列は 妥当であると考えられる。 • また、モデル座標系の (1,0,0.5) に変換行列を適 用し、変換後の座標を計算すると、変換後の座標 は (-3.93, -1.77, -13.02) となる。シーンを見ると、 モデル座標系の (1,0,0.5) の位置は、カメラから見 て、モデル座標系の原点よりも、やや手前、左下の 位置にある。変換後の座標もそのような値になって いるので、この変換行列は妥当であると考えられる。 検算 1/ 2 3/ 4 3/4 0 1/ 2 3/ 4 3/4 0 0 1/ 2 3/2 0 0 1/ 2 3/2 0 3/2 3/4 1/ 4 0 3/2 3/4 1/ 4 0 0 3 3 6 3 3 0 6 3 3 0.81 0 13.38 6 3 3 6 3 3 1 1 1 1 3 1 1/ 2 3 / 4 3 0.5 0.43 3 3.93 6 3 3 0 3/ 4 3 / 8 6 3 3 0.75 0.22 6 5.2 1.77 0.5 0.43 0.13 10.32 3 13.02 6 3 3 3 / 4 1/ 8 6 3 3 1 1 1 1 1 3
© Copyright 2024 ExpyDoc