メディア情報学実験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
© Copyright 2025 Paperzz