11. 3DCGモデルの表示

【プログラミング序論D】 目次, 講義ページ, 授業科目, www.kameda-lab.org 2017/01/12a

09.節, 10.節の内容をここで統合します。
本節でやっとポリゴンが色付きで表示できるようになります。
(正確には、ここの色は3DCG本来の光源・物体の反射率・カメラ撮像、の過程を経ていない着色なので、リアリティには欠けます)
(5週ではいろいろと無理が‥)

特に指定していませんが、どの節の場合でも、実行前に、プロジェクトディレクトリに ic2_DefaultModel.txt を配置しておくようにしてください。


11.01. プログラム同居

09.03.節, 10.02.節のソースファイル群はお互いに干渉しないように作られているので、main()関数が入っているファイル以外は同じプロジェクトに置いてもコンパイルに問題が発生しません。
全て過去のプログラムファイルそのままです。

【プログラム11-01】

  1. ic2-CommonHeaders.h
  2. ic2-ModelHeaders.h
  3. 07-03-EmbededObjects.c
  4. 07-04-Initialization.c
  5. 07-05-MainFunction.c
  6. 08-01-GLTools.c
  7. 09-02-Projection.c
  8. 09-03-Callback.c
  9. 09-03-Rendering.c
  10. 10-02-ReadModel.c

演習

11-01-ex1: main関数
09.03.節のmain()を含むソース(07-05-MainFunction.c)と 10.02.節のmain()を含むソース(10-02-MainFunction.c)とを同じプロジェクト内に置いてはいけない理由を説明しなさい。

11-01-ex2: main関数の交代
11-01-ex1において、10-02-MainFunction.c のほうのみをプロジェクト内に置いてビルドした場合、何が起き、どのようなプログラムが生成されるか説明しなさい。

11-01-ex3: ファイル読込のライブラリ化
10.02.節から持ち込んだソース群をライブラリ化して、09.03.節のソース群をコンパイルできるようにしなさい。ライブラリ名は「IC2ReadModel」とします。


11.02. プログラム統合

2つあるヘッダファイルを1つに統合します。
演習11-01-ex3を実施した人には不要な行為ですね。)
ヘッダファイルの統合に伴い、(連動して)1箇所だけ他のプログラムファイル内で変更点が発生します。

【プログラム11-02】

  1. ic2-CommonHeaders.h (11-01からの差分)
  2. 11-02-ReadModel.c (10-02からの差分)
  3. 07-03-EmbededObjects.c, 07-04-Initialization.c, 07-05-MainFunction.c, 08-01-GLTools.c, 09-02-Projection.c, 09-03-Callback.c, 09-03-Rendering.c

演習

11-02-ex1: ヘッダファイル統合
ヘッダファイル統合において、書き換えが必要だった内容と、その理由を丁寧に説明しなさい。


11.03. プログラム完全統合

あとは、main()を書き直して、モデルファイルの受付をできるようにします。
ここだけは、07-05-MainFunction.c (09.03.節でmain()関数を含んでいたソースファイル)と 10-02-MainFunction.c とをよく見比べながら書いていく必要があります。
(こういうときだけはeclipseよりmeldのほうが便利かもしれません。上手に使い分けてください。)

【プログラム11-03】

  1. 11-03-MainFunction.c (07-05からの差分)
  2. 07-03-EmbededObjects.c, 07-04-Initialization.c, 08-01-GLTools.c, 09-02-Projection.c, 09-03-Callback.c, 09-03-Rendering.c, 11-02-ReadModel.c, ic2-CommonHeaders.h

演習

11-03-ex1: 実行時引数
本節のプログラムの実行時引数について説明しなさい。

11-03-ex2: 11-03-MainFunction.c におけるエラートラップ
11-03-MainFunction.c におけるエラートラップとその対策について、列挙してそれぞれについて説明しなさい。

11-03-ex3: Meld
似た内容のテキストファイルを2つ用意し、エディタMeldを起動して利用してみなさい。


11.04. ポリゴン表示

いよいよ読み込んだポリゴンリストを描画する関数 ic2_DrawModel() を用意します。
ic2_DrawModel() は 11-04-FileObjects.c の中で記述します。
ポリゴンは全て3角形パッチなので、描画にはGL_TRIANGLESという形式を利用します。
なお、モデルのパッチリストを保持している firstpatchptr はイベント駆動型プログラミングではイベントトリガ時に引き渡すいい方法がないので、大域変数化します。

【プログラム11-04】

  1. ic2-CommonHeaders.h (11-03からの差分)
  2. 11-04-FileObjects.c (新規)
  3. 11-04-MainFunction.c (11-03からの差分)
  4. 11-04-Rendering.c (09-03からの差分)
  5. 07-03-EmbededObjects.c, 07-04-Initialization.c, 08-01-GLTools.c, 09-02-Projection.c, 09-03-Callback.c, 11-02-ReadModel.c

演習

11-04-ex1: 外部宣言
ヘッダファイルの外部宣言 (extern) において、外部宣言時にその変数への値の代入が可能かどうか、その理由と共に答えなさい。

11-04-ex2: 描画形式
GL_TRIANGLESの描画形式について説明しなさい。


11.05. ポリゴン表示・Depth付

描画できた!‥と思ったら、何か変ですね。
これは、前節のプログラムがポリゴンを「描いた順でどんどん上書きしてしまって」いるからです。
これを止めるためには、Depth bufferingという機能を利用する必要があります。
(Z-buffer法と呼ばれることもあります)
(はじめてDepth bufferを使ってリアルタイムポリゴンレンダリングハードウェアを見たときは物凄い衝撃でした‥あれから何十年経ったのやら。)

Depth bufferingの利用には、3段階の手順が必要です。
1. Depth bufferを使う予定であることを起動時に表明する。
2. フレームを新たに書き直すときに、Depth bufferも毎回初期化する。
3. ポリゴンをレンダリングするとき(する前に)Depth bufferを使って前後判定を行うことを指示する。
(Depth bufferを参照して、ポリゴン中の描画部分(画素)がカメラに対して一番手前にくることがわかった場合は、その画素をポリゴンの色で塗るとともに、当該画素のDepth値を書き換えることがシステム内で行われます)
これに合わせる形で、プログラムを3箇所修正します。

【プログラム11-05】

  1. 11-05-Initialization.c (07-04からの差分)
  2. 11-05-Rendering.c (11-04からの差分)
  3. 07-03-EmbededObjects.c, 08-01-GLTools.c, 09-02-Projection.c, 09-03-Callback.c, 11-02-ReadModel.c, 11-04-FileObjects.c, 11-04-MainFunction.c, ic2-CommonHeaders.h

演習

11-05-ex1: Depth buffering
Depth buffering (Z-buffer法) について説明しなさい。

11-05-ex2: Depth buffer の初期化
Depth buffer の初期化において、ハードウェアは具体的に何をしているか説明しなさい。

11-05-ex3: ロゴマークと3DCGの同時表示
ロゴマークと読み込んだ3DCGを同時に表示するようにプログラムを改造しなさい。ただしロゴマークは各自オリジナルのものに入れ替えること。
また、このときに、回転・移動・スケーリングの様子をオリジナルなものに入替なさい。(元プログラム同様、周期的に変化させること)
ロゴマークは3DCGに食い込む形で表示されることになるでしょう。

11-05-ex4: 3DCGの周期運動
09-03-ex5と同様に、移動と回転を伴って読み込んだ3DCGが周期運動するようにプログラムを改造しなさい。

11-05-ex5: ポリゴン数とシステム負荷
ポリゴン数の多い3DCGファイルを用いて、ポリゴン数とシステム負荷との関係を調べてみなさい。

11-05-ex6: ポリゴン数とシステム負荷の調査
10万ポリゴン以上のモデルを用意し、本節のプログラムのシステム負荷を調べてみなさい。

11-05-ex7: キーボードによる1回転指示
キーボードのh,j,k,lを1度押すと、3DCGがそれぞれ左に1回転、右に1回転、上へ1回転、下へ1回転するようにプログラムを改良しなさい。

11-05-ex8: キーボードによる連続的回転指示
キーボードのh,j,k,lを押し続けている間、3DCGがそれぞれ左回転、右回転、上回転、下回転するようにプログラムを改良しなさい。

11-05-ex9: キーボードによる移動指示の追加
ex8に加え、キーボードのカーソルキー等を用いて、そのキーを押している間、3DCGを前後左右上下移動できるようにプログラムを改良しなさい。
glutSpecialFunc()関数を使えば標準的なキー以外についてもCallbackを仕掛けることができます。


おまけ (3DCGフォーマット準拠)

人形データ 02


kameda[at]iit.tsukuba.ac.jp