コンピューターグラフィックス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 2026 ExpyDoc