補足資料 - CG第1研究室

メディア情報学実験I 「CG」
第2週
OpenGL 課題1∼5
1
実験の目的
•  OpenGLライブラリを用いたCGプログラミング
の手法を学ぶ
•  プログラミングを通して,CGの基礎技術を体験
的に学ぶ
•  インタラクティブな3次元CGアニメーションを
作成する方法について学ぶ
2
OpenGLとは
•  グラフィックAPI (Application Programming
Interface) の1つ
•  クロスプラットフォーム
3
OpenGLの構成
•  基本的に以下の3種類のライブラリをプログラムに
リンクして実行
–  OpenGLライブラリ
•  ヘッダファイル: GL/gl.h
•  リンクオプション: -lGL
•  glから始まる名前の関数群
–  OpenGLユーティリティライブラリ(GLU)
•  ヘッダファイル: GL/glu.h
•  リンクオプション: -lGLU
•  gluから始まる名前の関数群
–  GLUTライブラリ(GLUT)
•  ヘッダファイル: GL/glut.h
•  リンクオプション: -lglut
•  glutから始まる名前の関数群
4
コンパイル方法
•  gcc -o sample1 sample1.c -O2 -Wall -L/usr/
X11R6/lib -lm -lX11 -lGL -lGLU -lglut -lXext
-lXmu –lXi
•  Makefile
–  コンパイルをするために必要な依存関係などのルール
や実際に実行するプログラムやスクリプトなどを記述
したファイル
–  make コマンドで実行
–  本実験に必要なMakefile:
•  samples ディレクトリの中
5
プログラム構成
•  OpenGLプログラムはイベント駆動方式
–  C言語の一般的なプログラムは上から順に実行
–  イベント駆動方式では,イベント(マウスやキー操
作)に応じて実行状態を変化
6
OpenGLプログラムを始める前の準備
•  ホーム直下に jikken1-CG ディレクトリを作成
–  mkdir jikken1-CG
–  cd jikken1-CG ß 作成したディレクトリに移動
•  実験のWebページからsamples.tgzをダウンロードし
て jikken1-CG に保存
–  tar xvzf samples.tgz -C ~/jikken1-CG/
•  samples ディレクトリに移動
–  cd samples
•  プログラムを作るときは基本的に「作業ディレクト
リ」を作る
–  ホームディレクトリにソースコードを散らかさない!
7
3次元CGプログラミング
–sample1-
Sampleプログラムをみてみよう
intmain(intargc,char*argv[])
voiddisplay(void)
{
{
/*glutの初期化 */
/*ウィンドウの背景を指定された
glutInit(&argc,argv);
色で塗りつぶす */
init(argv[0]);
glClear(GL_COLOR_BUFFER_BIT);
/*ディスプレイコールバック関数の指定 */
/*OpenGLコマンドを強制的に実行
glutDisplayFunc(display);
(描画実行) */
glFlush();
/*イベント待ちの無限ループへ入る */
}
glutMainLoop();
/*ループが終わったら0を返して終了 */
return0;
}
8
3次元CGプログラミング
voidinit(char*winname)
{
/*ウィンドウの左上の位置を(0,0)とする */
glutInitWindowPosiRon(0,0);
/*ウィンドウのサイズを500×500ドットとする */
glutInitWindowSize(500,500);
/*色の指定にRGBAモードを用いる */
glutInitDisplayMode(GLUT_RGBA);
/*winnameで指定された名前でウィンドウを開く */
glutCreateWindow(winname);
/*ウィンドウの背景色の指定 */
/*R(赤),G(緑),B(青),A(透明度)の順で指定*/
glClearColor(0.0,0.0,0.0,1.0);
}
–sample1-
x
y
ディスプレイ
(0,0)
9
3.2 図形の描画
•  OpenGLでは頂点座標を基に基本図形を定義
–  glBeginからglEnd で囲まれた頂点群を図形タイプに従っ
て描画
/*図形定義の開始 */
glBegin(図形のタイプ);
/*頂点の設定 */
glVertex3f(x0,y0,z0);
glVertex3f(x1,y1,z1);
……
glVertex3f(xn,yn,zn);
/*図形定義の終了 */
glEnd();
10
座標系
•  3次元から2次元への座標変換を行うために,
CGでは,いくつかの座標系が設定され,適切な
順序で座標変換が行われる.座標系としては主
に:
•  オブジェクト座標系
•  ワールド座標系
•  カメラ座標系
•  クリップ座標系
•  正規デバイス座標系
•  スクリーン座標系
11
座標系
•  オブジェクト座標系
–  描画対象となる物体(オブジェ
クト)がもつ座標系
–  物体の実寸値やシミュレーショ
ン計算において都合のよい座標
値が定義
オブジェクト座標系
(2,2,2)
•  ワールド座標系
–  3次元空間中に物体を配置す
る時に基準となる座標
–  単体のオブジェクトを表示す
る場合には,オブジェクト座
標系を世界座標系と見なすこ
ともある
オブジェクト座標系
(2,2,2)
ワールド座標系
(2.4,-0.2,1.5)
12
3.3 投影法
•  ワールド座標系の3次元物体をスクリーン座標系
に映すことを投影と呼ぶ
A
A
B
A’
B’
平行投影
A’
B
B’
透視投影
13
投影法とビューボリューム
•  ウィンドウを設定し,視点から見える視野の範囲
を限定
–  クリッピング :ウィンドウ外の物体の投影を除く作業
–  ビューボリューム:投影によりウィンドウに表示され
る領域
aspect=w/h
w
h
視点
fovy
znear
zfar
14
投影法とビューボリューム
–実装-
•  平行投影
–  glOrtho(xleft, xright, ybottom, ytop, znear, zfar)
•  透視投影
–  gluPerspective(fovy, aspect, znear, zfar)
gluLookAt(ex, ey, ez, cx, cy, cz, ux, uy, uz)
視点の位置
目標の位置
「上」方向
aspect=w/h
w
h
視点
fovy
znear
zfar
15
透視投影 補足
•  透視投影
–  gluPerspective(fovy, aspect, znear, zfar)
gluLookAt(ex, ey, ez, cx, cy, cz, ux, uy, uz)
aspect=w/h
w
(ex,ey,ez)
h
視点
fovy
(ux,uy,uz)
(cx,cy,cz)
znear
zfar
16
3.4 幾何変換
•  ワールド座標空間において,物体の位置や姿勢
を変えたり,拡大・縮小の変形を加える操作
–  平行移動
–  回転
–  拡大・縮小
•  プログラムに書く順番と作用する順番に注意!
–  OpenGLはスタックを用いて実装される
17
合成変換
•  OpenGLはスタックに変換行列が格納され,
実行時Popされていく
–  平行移動à回転をさせたい場合
プログラム中に
Transratef();
Rotatef();
と書いた場合
Rotatef();
Transratef();
プログラム中に
Rotatef();
Transratef();
と書いた場合
Transratef();
Rotatef();
18
3.5 アニメーション
•  アニメーションを行うには,頻繁に画面の書き換
えを行う必要がある
–  glutPostRedisplay() 関数:
プログラム中でウィンドウの再描画イベントを発生さ
せる
•  アイドリング時の呼び出す
•  ダブルバッファリングの実装
–  画面を2つに分け,一方を表示している間に (見えない
ところで) もう一方に図形を描き,それが完了したらこ
の2つの画面を入れ換えるという方法
•  glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA )
•  glutSwapBuffers()
19
glPushMatrix とglPopMatrix
•  アニメーションを行っているときに,display関
数内でglTransratefなどの変換行列ある場合
àアニメーションで1回描画するたびに変換行列
が積算される
•  最初の時点での座標系を一旦保存しておき,後
でもとの座標系に戻す必要がある
–  glPushMatrix
•  座標系を一旦保存しておく
–  glPopMatrix
•  一旦もとの座標系に戻す
20