今日の内容 前回の演習の復習 前回の復習 ポリゴンの描画方法(復習) 基本オブジェクトの描画 ポリゴンモデルの描画 演習課題.

Slides:



Advertisements
Similar presentations
シミュレーション演習 G. 総合演習 ( Mathematica 演 習) システム創成情報工学科 テキスト作成: 藤尾 光彦 講義担当: 尾下 真樹.
Advertisements

情報基礎演習I(プログラミング) 第9回 6月22日 水曜5限 江草由佳
ゲーム開発者向け最新技術論文の解説・実装講座
初年次セミナー 第13回 2次元グラフィックス(1).
今回の内容 シェーディング マッピング 光の効果の表現 表面の素材の表現 オブジェクトの形状表現 光の効果の表現 表面の素材の表現
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
豊洲 304教室 15 JULY コンピュータグラフィックス 2008年度版.
情報処理演習 (9)グラフィックス システム科学領域 日浦 慎作.
今回の内容 前回の復習 演習環境 サンプルプログラムの解説 プログラミング演習 OpenGLとGLUTの概要 サンプルプログラムの概要
プログラミング演習3 李 亜民クラス 第2回 ラスタライズ.
情報処理 第8回.
Microsoft PowerPoint98 Netscape Communicator 4.06[ja]
情報処理 第7回.
情報処理入門A・B 第7回 ワープロソフト入門(2)
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
3DCGコンテンツの基礎 第5回授業:最終課題制作
今日の内容 前回の復習 前回の演習の復習 視点操作の実現方法(復習) 視点操作の拡張 変換行列によるアニメーション 演習課題.
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
平成23年8月 情報学群 岡田 守 このスライドは, 前川佳徳編著による「コンピュータグラフィックス」(オーム社)を基に作成されている.
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月6日、H.16(‘04)] 今日のメニュー 1 前回の課題の復習
今日の内容 前回の復習 モデリング 3次元オブジェクトの表現方法 3次元オブジェクトの作成方法 オブジェクトを計算機上でどのように表現するか
コンピュータグラフィックスS 第6回 第6回 レンダリング・パイプライン システム創成情報工学科 尾下 真樹
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
シミュレーション演習 G. 総合演習 (Mathematica演習) システム創成情報工学科
経営工学基礎演習a PowerPointの利用.
CGと形状モデリング 授業資料 長井 超慧(東京大学)
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
コンピュータグラフィックスS 第13回 第13回 演習(4):シェーディング、マッピング システム創成情報工学科 尾下 真樹
DirectX 勉強会 第4回.
Computer Graphics 第3回 座標変換 芝浦工業大学情報工学科 青木 義満
CGと形状モデリング 授業資料 1,2限: 大竹豊(東京大学) 3,4限: 俵 丈展(理化学研究所)
第10回関数 Ⅱ (ローカル変数とスコープ).
電界中の電子の運動 シミュレータ作成 精密工学科プログラミング基礎 資料.
ポリゴンメッシュ (1) - データ構造とレンダリングに必要な計算 -
OpenGLを使ったプログラム作成 澤見研究室
第9回 卒業研究1
点・線分・多角形を レンダリングする方法 東京大学 精密工学専攻 大竹豊.
OpenGLライブラリを用いた3次元フラクタルの描画
第7回 プログラミングⅡ 第7回
Computer Graphics 第10回 レンダリング(4) マッピング
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
デジタル画像とC言語.
可視面・不可視面の判定方法と隠れ面(不可視面)の消去法について述べる.
DirectX勉強会 第2回.
プロジェクト演習Ⅱ インタラクティブゲーム制作
画像処理プログラミング 知的画像処理研究室 M2 小林 佳奈美.
プロジェクト演習Ⅳ インタラクティブゲーム制作 プログラミング4
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
プロジェクト演習Ⅳ・Ⅵ インタラクティブゲーム制作
アルゴリズムとプログラミング (Algorithms and Programming)
地理情報システム論(総)/ 国民経済計算論(商)
地理情報システム論 第4回 コンピュータシステムおける データ表現(2)
免許法認定公開講座: コンピュータグラフィックス
第5回 プログラミングⅡ 第5回
バネモデルの シミュレータ作成 精密工学科プログラミング基礎 資料.
精密工学科プログラミング基礎 第7回資料 (11/27実施)
シミュレーション演習 G. 総合演習 (Mathematica演習) システム創成情報工学科
点・線分・多角形を レンダリングする方法 東京大学 精密工学専攻 大竹豊.
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
情報処理Ⅱ 2005年11月25日(金).
プログラミング基礎a 第5回 C言語によるプログラミング入門 配列と文字列
湘南工科大学 2013年10月22日 情報理論2 湘南工科大学情報工学科 准教授 小林 学.
プログラミング入門2 第5回 配列 変数宣言、初期化について
CGと形状モデリング 授業資料 1,2限: 大竹豊(東京大学) 3,4限: 俵 丈展(理化学研究所)
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

コンピュータグラフィックスS 第7回 第7回 演習(2):ポリゴンモデルの描画 システム創成情報工学科 尾下 真樹 2015/5/26 コンピューターグラフィックスS 第7回 演習(2):ポリゴンモデルの描画 システム創成情報工学科 尾下 真樹

今日の内容 前回の演習の復習 前回の復習 ポリゴンの描画方法(復習) 基本オブジェクトの描画 ポリゴンモデルの描画 演習課題

前回の演習の復習

サンプルプログラム opengl_sample.c 地面と1枚の青い三角形が表示される マウスの右ボタンドラッグで、視点を上下に回転

前回の演習課題 1. コンパイル・実行できることを確認する 2. プログラムを修正して、以下の修正を行う コンピュータグラフィックスS 第4回 2015/5/26 前回の演習課題 1. コンパイル・実行できることを確認する 2. プログラムを修正して、以下の修正を行う ウィンドウのタイトルに、自分の学生番号が表示されるようにする 三角形の色を、青から黄に 変更する 3. 修正が終わったら、Moodle からプログラムを提出

演習資料(3種類)(確認) 演習資料(OpenGL演習) コンパイル方法の説明資料 OpenGL関数 簡易リファレンス この資料に従って、プログラムを拡張していく 次回以降の分の説明は、逐次追加する コンパイル方法の説明資料 コンパイル方法の詳しい説明 CL端末や自宅での方法も一応説明 OpenGL関数 簡易リファレンス OpenGLの関数を簡単に説明した資料

サンプルプログラムの構成 グローバル変数の定義 コールバック関数 initEnvironment() main() display() reshape() mouse() motion() idle() initEnvironment() main() opengl_sample.c

OpenGLの関数 gl~ で始まる関数 glu~ で始まる関数 glut~ で始まる関数 OpenGLの標準関数 OpenGL Utility Library の関数 OpenGLの関数を内部で呼んだり、引数を変換したりすることで、使いやすくした補助関数 glut~ で始まる関数 GLUT(OpenGL Utility Toolkit)の関数 正式にはOpenGL標準ではない

サンプルプログラムの構成 ユーザ・プログラム GLUT main()関数initEnvironment()関数 初期化処理 glutMainLoop() 入力待ち処理 display()関数 描画 reshape()関数 ウィンドウサイズ変更 mouse()関数motion()関数 マウス処理 アニメーション処理 idle()関数 終了処理 main()関数

描画関数の流れ // // ウィンドウ再描画時に呼ばれるコールバック関数 void display( void ) { // ウィンドウ再描画時に呼ばれるコールバック関数 void display( void ) { // 画面をクリア(ピクセルデータとZバッファの両方をクリア) // 変換行列を設定(ワールド座標系→カメラ座標系) // 光源位置を設定(モデルビュー行列の変更にあわせて再設定) // 地面を描画 // 変換行列を設定(物体のモデル座標系→カメラ座標系) // 物体(1枚のポリゴン)を描画 // バックバッファに描画した画面をフロントバッファに表示 }

今回の演習 前回のプログラムの描画処理を、1枚のポリゴンの代わりに、ポリゴンモデルを描画するように変更 変換行列については、基本的に変更しない(詳しくは後日の講義で勉強してから) y z y x 15 (0,1,0) camera_pitch z x

前回の復習

レンダリング・パイプライン レンダリング・パイプライン 入力されたデータを、流れ作業(パイプライン)で処理し、順次、画面に描画 各頂点ごとに処理 各ポリゴンごとに処理 レンダリング・パイプライン 入力されたデータを、流れ作業(パイプライン)で処理し、順次、画面に描画 3次元空間のポリゴンのデータ(頂点データの 配列)を入力 いくつかの処理を経て、画面上に描画される 座標変換 ラスタライズ x y z x y z 描画 頂点座標 スクリーン座標

処理の流れ 座標変換 ラスタライズ x y z x y z x y z 座標変換 ラスタライズ x y z x y z 各頂点ごとに処理 各ポリゴンごとに処理 座標変換 ラスタライズ x y z x y z 描画 頂点座標 スクリーン座標 (法線・色・テクスチャ座標) x y z 座標変換 ラスタライズ x y z x y z 教科書 基礎知識 図2-21

レンダリング Zバッファ法によるレンダリング 基本的には、OpenGLが自動的にZバッファ法を用いたレンダリングを行うので、自分のプログラムでは特別な処理は必要ない 最初に、Zテストを有効にするように、設定する必要がある void initEnvironment( void ) { ・・・・・・ // Zテストを有効にする glEnable( GL_DEPTH_TEST ); }

ポリゴンの描画 glBegin() ~ glEnd() 関数を使用 図形の種類 (各種の点・線・面が指定可能) ※ 頂点データの指定では、一つの関数で、図形を構成する頂点の座標・色・法線などの情報の一つを指定 図形の種類 (各種の点・線・面が指定可能) GL_POINTS(点)、GL_LINES(線分)、GL_TRIANGLES(三角面)、GL_QUADS(四角面)、GL_POLYGON(ポリゴン)、他 glBegin( 図形の種類 ); この間に図形を構成する頂点データを指定 glEnd();

頂点データの指定 glColor3f( r, g, b ) glNormal3f( nx, ny, nz ) これ以降の頂点の色を設定 glNormal3f( nx, ny, nz ) これ以降の頂点の法線を設定 glVertex3f( x, y, z ) 頂点座標を指定 色・法線は、最後に指定したものが使用される

ポリゴンの描画の例(1) 1枚の三角形を描画 各頂点の頂点座標、法線、色を指定して描画 ポリゴンを基準とする座標系(モデル座標系)で頂点位置・法線を指定 y (-1,1,0) glBegin( GL_TRIANGLES ); glColor3f( 0.0, 0.0, 1.0 ); glNormal3f( 0.0, 0.0, 1.0 ); glVertex3f(-1.0, 1.0, 0.0 ); glVertex3f( 0.0,-1.0, 0.0 ); glVertex3f( 1.0, 0.5, 0.0 ); glEnd(); (1,0.5,0) x z (0,-1,0) GL_TRIANGLES が指定されているので、3つの頂点をもとに、1枚の三角面を描画 (6つの頂点が指定されたら、2枚描画)

ポリゴンの向き 頂点の順番により、ポリゴンの向きを決定 表から見て反時計回りの順序で頂点を与える 視点と反対の向きでなら描画しない(背面除去) 頂点の順序を間違えると、描画されないので、注意 1 1 3 2 表 裏 2 3

基本オブジェクトの描画

基本オブジェクトの描画 GLUTには、基本的なポリゴンモデルを描画する関数が用意されている 立方体、球、円すい、16面体、円環体、ティーポット、等 あらかじめ用意されたポリゴンモデルを描画 例: glutWireCube(), glutSolidCube() それぞれ、ワイヤーフレームとポリゴンモデルで立方体を描画する関数

立方体の描画 glutSolidCube(size)を使って立方体を描画 void display( void ) { ・・・・・・ // 変換行列を設定(物体のモデル座標系→カメラ座標系) //(物体が (0.0, 1.0, 0.0) の位置にあり、静止しているとする) glTranslatef( 0.0, 1.0, 0.0 ); /* ポリゴンの描画はコメントアウト */ // 立方体を描画 glColor3f( 1.0, 0.0, 0.0 ); glutSolidCube( 1.5f ); }

球の描画 glutSolidSphere( radius, slices, stacks ) 球をポリゴンモデルで近似して描画 引数の値を変えて、ポリゴンモデルの変化を確認 void display( void ) { ・・・・・・ // 球を描画 glColor3f( 1.0, 0.0, 0.0 ); glutSolidSphere( 1.0, 8, 8 ); }

球の描画 glutSolidSphere( radius, slices, stacks ) 球をポリゴンモデルで近似して描画 引数の値を変えて、ポリゴンモデルの変化を確認 void display( void ) { ・・・・・・ // 球を描画 glColor3f( 1.0, 0.0, 0.0 ); glutSolidSphere( 1.0, 16, 16 ); } void display( void ) { ・・・・・・ // 球を描画 glColor3f( 1.0, 0.0, 0.0 ); glutSolidSphere( 1.0, 8, 8 ); }

ポリゴンモデルの描画

四角すいの描画 四角すいを構成する頂点と三角面 頂点座標 面の頂点、面の法線 y x z 三角面 { V0, V3, V1 } { 0.0, 0.53, 0.85 } { 0.0, 0.53, -0.85 } { 0.85, 0.53, 0.0 } { -0.85, 0.53, 0.0 } { 0.0, -1.0, 0.0 } y V0 (0.0, 0.8, 0.0) x V4 V2 V3 V1 (1.0, -0.8, 1.0) z

三面図 y V0 1 V4 V2 1 1 x V0 x V3(V4) V1(V2) V3 1 V1 z ※ yz平面は省略

面の法線の計算方法 ポリゴンの2辺の外積から計算できる 断面で考えれば、もっと 簡単に法線は求まる N V1 N=(V3 - V1)×( V2 - V1) 長さが 1 になるよう正規化 V3 y V2 N x 1.8 1.0

ポリゴンモデルの描画方法 いくつかの描画方法がある 形状データの表現方法の違い OpenGLへのデータの渡し方の違い 頂点データのみを使う方法と、頂点データ+面インデックスデータを使う方法がある 後者の方が、データをコンパクトにできる OpenGLへのデータの渡し方の違い OpenGLの頂点配列の機能を使うことで、より高速に描画できる

ポリゴンモデルの描画方法 方法1: glVertex() 関数に直接頂点座標を記述 方法2: 頂点データの配列を使用 頂点データ(直接記述)、頂点ごとに渡す 方法2: 頂点データの配列を使用 頂点データ、頂点ごとに渡す 方法3: 頂点データと面インデックスの配列を使用 頂点データ+面インデックス、頂点ごとに渡す 方法4: 頂点配列を使用 頂点データ、OpenGLにまとめて渡す 方法5: 頂点配列と面インデックス配列を使用 頂点データ+面インデックス、 OpenGLにまとめて渡す

ポリゴンモデルの描画方法 方法1: glVertex() 関数に直接頂点座標を記述 方法2: 頂点データの配列を使用 頂点データ(直接記述)、頂点ごとに渡す 方法2: 頂点データの配列を使用 頂点データ、頂点ごとに渡す 方法3: 頂点データと面インデックスの配列を使用 頂点データ+面インデックス、頂点ごとに渡す 方法4: 頂点配列を使用 頂点データ、OpenGLにまとめて渡す 方法5: 頂点配列と面インデックス配列を使用 頂点データ+面インデックス、 OpenGLにまとめて渡す

方法1 最も基本的な描画方法 サンプルプログラムと同様の描画方法 glVertex() 関数の引数に直接頂点座標を記述

四角すいの描画(1) 四角すいを描画する新たな関数を追加 void renderPyramid1() { glBegin( GL_TRIANGLES ); // +Z方向の面 glNormal3f( 0.0, 0.53, 0.85 ); glVertex3f( 0.0, 1.0, 0.0 ); glVertex3f(-1.0,-0.8, 1.0 ); glVertex3f( 1.0,-0.8, 1.0 ); ・・・・・・ 以下、残りの7枚分のデータを記述 glEnd(); }

四角すいの描画(2) 描画関数から四角すいの描画関数を呼び出し 修正の場所を間違えないように注意 renderPyramid()関数では色は指定されていないので、呼び出す前に色を設定している void display( void ) { ・・・・・・ // 角すいの描画 glColor3f( 1.0, 0.0, 0.0 ); renderPyramid1(); }

ポリゴンモデルの描画方法 方法1: glVertex() 関数に直接頂点座標を記述 方法2: 頂点データの配列を使用 頂点データ(直接記述)、頂点ごとに渡す 方法2: 頂点データの配列を使用 頂点データ、頂点ごとに渡す 方法3: 頂点データと面インデックスの配列を使用 頂点データ+面インデックス、頂点ごとに渡す 方法4: 頂点配列を使用 頂点データ、OpenGLにまとめて渡す 方法5: 頂点配列と面インデックス配列を使用 頂点データ+面インデックス、 OpenGLにまとめて渡す

方法2 頂点データの配列を使用 配列を使う方法 利点 頂点データを配列として定義しておく glVertex() 関数の引数として配列データを順番に与える 利点 モデルデータが配列になってるので扱いやすい

頂点データの配列を使用(1) 配列データの定義 // 全頂点数 const int num_full_vertices = 18; // 全頂点の頂点座標 static float pyramid_full_vertices[][ 3 ] = { { 0.0, 1.0, 0.0 }, {-1.0,-0.8, 1.0 }, { 1.0,-0.8, 1.0 }, ・・・・ {-1.0,-0.8,-1.0 }, { 1.0,-0.8,-1.0 }, {-1.0,-0.8, 1.0 } }; // 全頂点の法線ベクトル static float pyramid_full_normals[][ 3 ] = { { 0.00, 0.53, 0.85 }, { 0.00, 0.53, 0.85 }, { 0.00, 0.53, 0.85 }, ・・・・ { 0.00,-1.00, 0.00 }, { 0.00,-1.00, 0.00 }, { 0.00,-1.00, 0.00 } };

法線・頂点を指定 (i番目の頂点のデータを指定) 頂点データの配列を使用(2) 各頂点の配列データを呼び出す void renderPyramid2() { int i; glBegin( GL_TRIANGLES ); for ( i=0; i<num_full_vertices; i++ ) glNormal3f( pyramid_full_normals[i][0], pyramid_full_normals[i][1], pyramid_full_normals[i][2] ); glVertex3f( pyramid_full_vertices[i][0], pyramid_full_vertices[i][1], pyramid_full_vertices[i][2] ); } glEnd(); 法線・頂点を指定 (i番目の頂点のデータを指定) 各頂点ごとに繰り返し

頂点データの配列を使用(3) 描画関数から描画関数を呼び出し 新しく追加した方の関数を使って描画するように修正 実行結果の画像は変化しないことを確認 void display( void ) { ・・・・・・ // 角すいの描画 glColor3f( 1.0, 0.0, 0.0 ); // renderPyramid1(); renderPyramid2(); }

ポリゴンモデルの描画方法 方法1: glVertex() 関数に直接頂点座標を記述 方法2: 頂点データの配列を使用 頂点データ(直接記述)、頂点ごとに渡す 方法2: 頂点データの配列を使用 頂点データ、頂点ごとに渡す 方法3: 頂点データと面インデックスの配列を使用 頂点データ+面インデックス、頂点ごとに渡す 方法4: 頂点配列を使用 頂点データ、OpenGLにまとめて渡す 方法5: 頂点配列と面インデックス配列を使用 頂点データ+面インデックス、 OpenGLにまとめて渡す

ここまでの方法の問題点 別の問題点 ある頂点を複数のポリゴンが共有している時、各ポリゴンごとに同じ頂点のデータを何度も 記述する必要がある 例:四角すいの頂点数は5個だが、これまでの方法では、三角面数6×3個=18個の頂点を記述する必要がある OpenGLは、与えられた全ての頂点に座標変換などの処理を適用するので、同じモデルを描画する時でも、なるべく頂点数が少ない方が高速

方法3 三角面インデックスを使用 頂点とポリゴンの情報を別々の配列に格納 描画関数では、配列のデータを順に参照しながら描画 頂点データの数を最小限にできる 描画関数では、配列のデータを順に参照しながら描画 必要な配列(サンプルプログラムの例) 頂点座標(x,y,z)×頂点数 三角面を構成する頂点番号(v0,v1,v2)×三角面数 三角面の法線(x,y,z)×三角面数

三角面インデックス 頂点データの配列と、三角面インデックスの配列に分けて管理する 三角面インデックス 面1 面2 面3 面4 面5 面6 面1 面2 面3 面4 面5 面6 面1 面2 面3 面4 面5 面6 何番目の頂点データを使うかという情報 頂点データ(座標, 法線, 色など) ※ 頂点の重複がなくなる ※ 頂点の重複がある 頂点データ(座標, 法線, 色など)

配列を使った四角すいの描画(1) 配列データの定義 const int num_pyramid_vertices = 5; // 頂点数 const int num_pyramid_triangles = 6; // 三角面数 // 角すいの頂点座標の配列 float pyramid_vertices[ num_pyramid_vertices ][ 3 ] = { { 0.0, 1.0, 0.0 }, { 1.0,-0.8, 1.0 }, { 1.0,-0.8,-1.0 }, ・・・・・・ }; // 三角面インデックス(各三角面を構成する頂点の頂点番号)の配列 int pyramid_tri_index[ num_pyramid_triangles ][ 3 ] = { { 0,3,1 }, { 0,2,4 }, { 0,1,2 }, { 0,4,3 }, { 1,3,2 }, { 4,2,3 } // 三角面の法線ベクトルの配列(三角面を構成する頂点座標から計算) float pyramid_tri_normals[ num_pyramid_triangles ][ 3 ] = { { 0.00, 0.53, 0.85 }, // +Z方向の面 ・・・・・・

配列を使った四角すいの描画(2) 配列データを参照しながら三角面を描画 void renderPyramid3() { int i, j, v_no; glBegin( GL_TRIANGLES ); for ( i=0; i<num_pyramid_triangles; i++ ) glNormal3f( pyramid_tri_normals[i][0],・・[i][1],・・ [i][2] ); for ( j=0; j<3; j++ ) v_no = pyramid_tri_index[ i ][ j ]; glVertex3f( pyramid_vertices[ v_no ][0], ・・・[ v_no ][1], ・・・ } glEnd(); 各三角面ごとに繰り返し 面の法線を指定 (i番目の面のデータを指定) 三角面の各頂点ごとに繰り返し 頂点番号を取得 (i番目の面のj番目の頂点が、何番目の頂点を使うかを取得) 頂点座標を指定 (v_no番目の頂点のデータを指定)

配列を使った四角すいの描画(3) 描画関数から描画関数を呼び出し 新しく追加した方の関数を使って描画するように修正 実行結果の画像は変化しないことを確認 void display( void ) { ・・・・・・ // 角すいの描画 glColor3f( 1.0, 0.0, 0.0 ); // ・・・・・・ renderPyramid3(); }

ポリゴンモデルの描画方法 方法1: glVertex() 関数に直接頂点座標を記述 方法2: 頂点データの配列を使用 頂点データ(直接記述)、頂点ごとに渡す 方法2: 頂点データの配列を使用 頂点データ、頂点ごとに渡す 方法3: 頂点データと面インデックスの配列を使用 頂点データ+面インデックス、頂点ごとに渡す 方法4: 頂点配列を使用 頂点データ、OpenGLにまとめて渡す 方法5: 頂点配列と面インデックス配列を使用 頂点データ+面インデックス、 OpenGLにまとめて渡す

頂点配列を使った描画方法 頂点配列 詳細は、本日の演習では省略 配列データを一度に全部 OpenGL に渡して描画を行う機能 渡すデータの量は同じでも、余分なオーバーヘッドを省けるため、処理を高速化できる モバイル端末用の OpenGL ES では、この頂点配列を使った描画しかできない(glVertex()は使えない) 詳細は、本日の演習では省略

別のポリゴンモデルの描画

直方体の描画 別のポリゴンモデル(直方体)の描画 1枚は空欄にしているので、各自、適切な頂点番号を考えて追加する y ? ? x z 四角面 { V2, V3, V1 , V0 } { V7, V6, V4 , V5 } { V2, V0, V4 , V6 } { V3, V7, V5 , V1 } { V3, V2, V6 , V7 } { V0, V1, V5 , V4 } 法線 { 0.0, 0.0, 1.0 } { 0.0, 0.0, -1.0 } { 1.0, 0.0, 0.0 } { -1.0, 0.0, 0.0 } { 0.0, 1.0, 0.0 } { 0.0, -1.0, 0.0 } (-0.8, 2.0, -0.4) V7 V6 y V3 V2 (0.8, 2.0, 0.4) V5 ? ? x V4 V1 V0 (0.8, 0.0, 0.4) z

三面図 y V3(V7) 2 V2(V6) V5(V7) V4(V6) 0.8 x x V1(V3) 0.4 V0(V2) V1(V5) 0.4 z ※ yz平面は省略

配列を使った直方体の描画(1) 描画方法 方法3を使用 法線や色の情報は、面ごとに指定 三角面の代わりに、四角面を使用する

ポリゴンモデルの描画方法(確認) 方法1: glVertex() 関数に直接頂点座標を記述 方法2: 頂点データの配列を使用 頂点データ(直接記述)、頂点ごとに渡す 方法2: 頂点データの配列を使用 頂点データ、頂点ごとに渡す 方法3: 頂点データと面インデックスの配列を使用 頂点データ+面インデックス、頂点ごとに渡す 方法4: 頂点配列を使用 頂点データ、OpenGLにまとめて渡す 方法5: 頂点配列と面インデックス配列を使用 頂点データ+面インデックス、 OpenGLにまとめて渡す

配列を使った直方体の描画(2) 配列データの定義 四角面を使うので、各面の頂点数が4個になる { 0.8, 0.0, 0.4 }, // 0 const int num_cube_vertices = 8; // 頂点数 const int num_cube_quads = 6; // 四角面数 // 頂点座標の配列 float cube_vertices[ num_cube_vertices ][ 3 ] = { { 0.8, 0.0, 0.4 }, // 0 ・・・・・・ {-0.8, 2.0,-0.4 }, // 7 }; // 四角面インデックス(各四角面を構成する頂点の頂点番号)の配列 int cube_index[ num_cube_quads ][ 4 ] = { { 2,3,1,0 }, { 7,6,4,5 }, { 2,0,4,6 }, { 3,7,5,1 }, { ?, ?, ?, ? }, { 0,1,5,4 } ?

配列を使った直方体の描画(3) 配列データの定義(続き) 今回は各面の色も指定する // 四角面の法線ベクトルの配列(四角面を構成する頂点座標から計算) float cube_normals[ num_cube_quads ][ 3 ] = { { 0.00, 0.00, 1.00 }, { 0.00, 0.00,-1.00 }, ・・・・・・ { 0.00,-1.00, 0.00 } }; // 四角面のカラーの配列 float cube_colors[ num_cube_quads ][ 3 ] = { { 0.00, 1.00, 0.00 }, { 1.00, 0.00, 1.00 }, { 1.00, 1.00, 0.00 } };

配列を使った直方体の描画(4) 配列データを参照しながら四角面を描画 void renderCube() { int i, j, v_no; glBegin( GL_QUADS ); for ( i=0; i<num_cube_quads; i++ ) glNormal3f( cube_normals[i][0],・・[i][1],・・ [i][2] ); glColor3f( cube_colors[i][0], ・・・[i][1], ・・・[i][2] ); for ( j=0; j<4; j++ ) v_no = cube_index[ i ][ j ]; glVertex3f( cube_vertices[v_no][0], ・・[v_no][1], ・・[v_no][2] ); } glEnd();

配列を使った直方体の描画(5) 描画関数から直方体の描画関数を呼び出し 色の指定は不要 void display( void ) { ・・・・・・ // 直方体を描画 renderCube(); }

演習課題

ポリゴンモデルの描画 ここまでのポリゴンモデルをまとめて描画 前回の演習課題のプログラム をもとに変更を加える 変換行列を利用して、3つのポリゴンモデルを同時に描画 変換行列については、後日学習するので、今回は、サンプルプログラムをそのまま使用しておく 右のスクリーンショットと同じ 画面になるように、プログラム の空欄を埋める 前回の演習課題のプログラム をもとに変更を加える

ポリゴンモデルの描画 ここまでのポリゴンモデルをまとめて描画 変換行列を利用して、3つのポリゴンモデルを同時に描画 void display( void ) { ・・・・・・ /* // 変換行列を設定(物体のモデル座標系→カメラ座標系) //(物体が (0.0, 1.0, 0.0) の位置にあり、静止しているとする) glTranslatef( 0.0, 1.0, 0.0 ); これまでのポリゴンの描画はコメントアウト */

? ? ・・・・・・ // 球を描画 glPushMatrix(); glTranslatef( 1.5, 1.0, -1.0 ); glColor3f( 1.0, 0.0, 0.0 ); ???????? glPopMatrix(); // 角すいの描画 glTranslatef( -1.5, 1.0, -1.0 ); glColor3f( ???, ???, ??? ); renderPyramid3(); // 直方体の描画 glTranslatef( 0.0, 0.0, 1.0 ); renderCube(); } ? ?

演習課題の提出 前回と同じく、Moodleからプログラムを提出 講義時間中に提出できなかった人は、 6月1日(月) 18:00 までに提出 ファイル名は、前回同様、学生番号.c とする 間違えて前回のファイルを提出しないように注意する 講義時間中に提出できなかった人は、 6月1日(月) 18:00 までに提出 演習問題と同様、成績に加える 未完成のプログラムが提出されていれば、減点 今回の演習課題ができていないと、次回以降の演習もできないため、必ず演習を行っておくこと

文字化けについての注意 日本語の文字化けが生じることがある 文字化けのないプログラムを提出すること プログラムのコメント中の日本語の文字化け Moodleに提出したプログラムをダウンロードして編集 Windowsでファイルを編集 文字コードの異なる他のソフトからコピー&ペースト などのことを行うと生じる可能性がある 文字化けした状態で保存すると、復元は不可能 文字化けのないプログラムを提出すること 万一、文字化けが生じたら、途中で保存したファイルや最初のファイルまで戻って、やり直す

まとめ 前回の復習 前回の演習の復習 ポリゴンの描画方法 基本オブジェクトの描画 ポリゴンモデルの描画 演習課題

次回予告 座標変換 ワールド座標系(モデル座標系)で表された頂点座標を、スクリーン座標系での頂点座標に変換する y y y x x z z カメラ座標系 スクリーン座標系

演習問題 プログラム演習を始める前に、Moodleの 演習問題に回答すること 本講義時間中しか回答できない 回答は、講義終了後に表示される コンピュータグラフィックスS 第7回 2015/5/26 演習問題 プログラム演習を始める前に、Moodleの 演習問題に回答すること 本講義時間中しか回答できない 回答は、講義終了後に表示される