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