Modified lines:  5, 6, 85, 533, 534, 535, 536, 537, 538, 541, 542, 543, 544, 545, 546, 549, 550, 581, 582
Added line:  50, 51, 52, 53, 54, 55, 56, 57, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 651, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697
Removed line:  None
Generated by diff2html.pl
© Yves Bailly, MandrakeSoft S.A. 2001, Ryohei Morita 2007
diff2html.pl is licensed under the GNU GPL.

  112-0-Structures.c     112-1-Memory.c
  662 lines
24801 bytes
Last modified : Mon Nov 21 17:58:11 2011

    777 lines
28582 bytes
Last modified : Mon Nov 21 05:34:46 2011

1 // Keisanki Joron 2 (Introduction to Computing II)   1 // Keisanki Joron 2 (Introduction to Computing II)
2 // Dept. of Engineering Systems, University of Tsukuba   2 // Dept. of Engineering Systems, University of Tsukuba
3 // [UTF-8 / Unix]   3 // [UTF-8 / Unix]
4   4
5 // 2011/11/21b kameda[at]iit.tsukuba.ac.jp   5 // 2011/11/21 kameda[at]iit.tsukuba.ac.jp
6 // 12.0 (11.1のプログラムから構造体の定義場所をファイル内で変更)   6 // 12.1 操作の記録
7   7
8 #include <stdio.h>   8 #include <stdio.h>
9 #include <stdlib.h> // exit(), calloc()   9 #include <stdlib.h> // exit(), calloc()
10 #include <math.h> // sqrt()   10 #include <math.h> // sqrt()
11 #include <GL/glut.h>   11 #include <GL/glut.h>
12   12
13 // ***********************************************************************    13 // *********************************************************************** 
14 // structures ************************************************************   14 // structures ************************************************************
15   15
16 // +----------------------------------------------------   16 // +----------------------------------------------------
17 // 1つの点のための構造体   17 // 1つの点のための構造体
18 // +----------------------------------------------------   18 // +----------------------------------------------------
19 struct ic2POINT {   19 struct ic2POINT {
20   float x;   20   float x;
21   float y;   21   float y;
22   float z;   22   float z;
23 };   23 };
24   24
25 // +----------------------------------------------------   25 // +----------------------------------------------------
26 // 1つの色のための構造体   26 // 1つの色のための構造体
27 // +----------------------------------------------------   27 // +----------------------------------------------------
28 struct ic2COLOR {   28 struct ic2COLOR {
29   float r;   29   float r;
30   float g;   30   float g;
31   float b;   31   float b;
32 };   32 };
33   33
34 // +----------------------------------------------------   34 // +----------------------------------------------------
35 // 1つの三角形パッチのための構造体   35 // 1つの三角形パッチのための構造体
36 // 次の三角形パッチへのポインタを持つ。   36 // 次の三角形パッチへのポインタを持つ。
37 // v(st) × v(su) [外積]がこの面の法線ベクトルを成す(右ネジ式)   37 // v(st) × v(su) [外積]がこの面の法線ベクトルを成す(右ネジ式)
38 // +----------------------------------------------------   38 // +----------------------------------------------------
39 struct ic2PATCH {   39 struct ic2PATCH {
40   struct ic2POINT s;     // 頂点s   40   struct ic2POINT s;     // 頂点s
41   struct ic2POINT t;     // 頂点t   41   struct ic2POINT t;     // 頂点t
42   struct ic2POINT u;     // 頂点u   42   struct ic2POINT u;     // 頂点u
43   struct ic2POINT n;     // 法線ベクトル(正規化された方向ベクトル)   43   struct ic2POINT n;     // 法線ベクトル(正規化された方向ベクトル)
44   struct ic2POINT b;     // パッチの重心   44   struct ic2POINT b;     // パッチの重心
45   float l; // 法線ベクトル表示時の長さ補正 (l * n)   45   float l; // 法線ベクトル表示時の長さ補正 (l * n)
46   struct ic2COLOR c;     // 色の強度 (通常は0.0 - 1.0)   46   struct ic2COLOR c;     // 色の強度 (通常は0.0 - 1.0)
47   struct ic2PATCH *next; // 次の三角形パッチへのポインタ   47   struct ic2PATCH *next; // 次の三角形パッチへのポインタ
48 };   48 };
49   49
      50 // +----------------------------------------------------
      51 // 1つのキー入力のための構造体
      52 // +----------------------------------------------------
      53 struct ic2KEYINPUT {
      54   unsigned char key;
      55   struct ic2KEYINPUT *next;
      56 };
      57
50 // ***********************************************************************    58 // *********************************************************************** 
51 // global variables ******************************************************   59 // global variables ******************************************************
52   60
53 // +----------------------------------------------------   61 // +----------------------------------------------------
54 // Global Variables   62 // Global Variables
55 // +----------------------------------------------------   63 // +----------------------------------------------------
56   64
57 // Windowサイズ   65 // Windowサイズ
58 int window_w = 400;   66 int window_w = 400;
59 int window_h = 400;   67 int window_h = 400;
60   68
61 // 直交投影時のスケールファクタ [pixel / unit_of_imager]   69 // 直交投影時のスケールファクタ [pixel / unit_of_imager]
62 // ここでは正規化カメラの撮像面での 1.0 単位を 200画素に相当させる   70 // ここでは正規化カメラの撮像面での 1.0 単位を 200画素に相当させる
63 float ortho_unit = 200.0;    71 float ortho_unit = 200.0; 
64   72
65 // 透視投影に用いる焦点距離 [pixel]   73 // 透視投影に用いる焦点距離 [pixel]
66 // y方向に fovy度 開いて画像の縦が400画素のときの焦点距離で単位は画素。   74 // y方向に fovy度 開いて画像の縦が400画素のときの焦点距離で単位は画素。
67 // ウィンドウサイズ変更時の扱い:   75 // ウィンドウサイズ変更時の扱い:
68 // ・本プログラムではウィンドウサイズが途中で変わるときに見た目の大きさを保つ。   76 // ・本プログラムではウィンドウサイズが途中で変わるときに見た目の大きさを保つ。
69 // ・ここでは、概念的にはウィンドウサイズ変更は撮像面の大きさ変化を意味する。   77 // ・ここでは、概念的にはウィンドウサイズ変更は撮像面の大きさ変化を意味する。
70 // ・焦点距離が同一のまま撮像面の大きさのみ変化したとして投影を表現する。   78 // ・焦点距離が同一のまま撮像面の大きさのみ変化したとして投影を表現する。
71 //   79 //
72 // 撮像面の横幅400画素に対して水平画角35.0°となる焦点距離を初期値設定:   80 // 撮像面の横幅400画素に対して水平画角35.0°となる焦点距離を初期値設定:
73 // tan(35.0[deg]/2) = (400[pixel]/2) / f [pixel]   81 // tan(35.0[deg]/2) = (400[pixel]/2) / f [pixel]
74 // → f = 634.319 [pixel]   82 // → f = 634.319 [pixel]
75 double camera_f = 634.319;    83 double camera_f = 634.319; 
76   84
77 // WindowのID(描画管理用)   85 // WindowのID(描画管理用)
78 int window_id = -1;   86 int window_id = -1;
79   87
80 // トグルスイッチ (1 ... On, -1 ... Off)   88 // トグルスイッチ (1 ... On, -1 ... Off)
81 int tgl_showpredefined = -1; // プログラム内定義物体の表示   89 int tgl_showpredefined = -1; // プログラム内定義物体の表示
82 int tgl_shownormal = -1;     // 法線表示   90 int tgl_shownormal = -1;     // 法線表示
83 int tgl_movelightonly = -1;  // 一時的な光源操作 (必ず-1で初期化)   91 int tgl_movelightonly = -1;  // 一時的な光源操作 (必ず-1で初期化)
84 GLfloat mvmlocked[16]; // 光源操作時にロックされたMODELVIEW行列の内容   92 GLfloat mvmlocked[16]; // 光源操作時にロックされたMODELVIEW行列の内容
85 int tgl_perspective = -1;    // -1...正投影, 1...透視投影   93 int tgl_perspective = -1;    // -1...直交投影, 1...透視投影
86   94
87 // オブジェクトモデル   95 // オブジェクトモデル
88 struct ic2PATCH *firstpatchptr = NULL;   96 struct ic2PATCH *firstpatchptr = NULL;
89   97
      98 // キー操作記録
      99 struct ic2KEYINPUT *firstkeyinputptr = NULL;  // リンクトリストの先頭
      100 struct ic2KEYINPUT *latestkeyinputptr = NULL; // リンクトリストの最後尾
      101 int tgl_keyinput = -1; // -1 ... 非記録, 1 ... 記録中
      102
      103 // *********************************************************************** 
      104 // key memory ************************************************************
      105
      106 // +++--------------------------------------------------
      107 // 新しいキー入力構造体(ic2KEYINPUT)のメモリ確保と初期化
      108 // +++--------------------------------------------------
      109 static struct ic2KEYINPUT *ic2_NewKEYINPUT (void) {
      110   struct ic2KEYINPUT *newkeyinput = NULL;
      111
      112   newkeyinput = (struct ic2KEYINPUT *)calloc(1, sizeof(struct ic2KEYINPUT));
      113   return (newkeyinput);
      114 }
      115
      116 // -----------------------------------------------------
      117 // キー1つ分の記録
      118 // -----------------------------------------------------
      119 int ic2_LogKey(unsigned char key) {
      120   struct ic2KEYINPUT *newkeyinput = NULL; // キー入力構造体ヘのポインタ
      121
      122   // (1) Logの可否
      123   if (tgl_keyinput != 1)
      124     return 1;
      125
      126   // (2) メモリ確保/下請け
      127   if ((newkeyinput = ic2_NewKEYINPUT()) == NULL) {
      128     printf("ic2_LogKey: Memory allocation failed.\n");
      129     return 1;
      130   }
      131
      132   // (3) 値の保存
      133   newkeyinput->key = key;
      134
      135   // (4) ic2KEYINPUTリスト構造への組み込み
      136   // *newkeyinput を キー入力集合の最後尾に挿入
      137   if (firstkeyinputptr == NULL) {
      138     firstkeyinputptr = newkeyinput;
      139     latestkeyinputptr = newkeyinput;
      140   } else {
      141     latestkeyinputptr->next = newkeyinput;
      142     latestkeyinputptr = newkeyinput;
      143   }
      144   return 0;
      145 }
      146
      147 // -----------------------------------------------------
      148 // キーインプット構造体(ic2KEYINPUT)リストの表示
      149 // -----------------------------------------------------
      150 int ic2_PrintKEYINPUTList (struct ic2KEYINPUT *firstkeyinputptr) {
      151   struct ic2KEYINPUT *p;
      152   int np = 0;
      153
      154   printf("KEYINPUT: \n");
      155   for (p = firstkeyinputptr; p != NULL; p = p->next) {
      156     np++;
      157     printf("%c", p->key);
      158   }
      159   printf("\n");
      160   printf("KEYINPUT: %d keys.\n", np);
      161
      162   return np;
      163 }
      164
      165 // -----------------------------------------------------
      166 // キーインプット構造体(ic2KEYINPUT)リストの解放
      167 // -----------------------------------------------------
      168 int ic2_FreeKEYINPUTList (struct ic2KEYINPUT *keyinputptr) {
      169   struct ic2KEYINPUT *nextptr;
      170   int n = 0;
      171   
      172   while (keyinputptr != NULL) {
      173     nextptr = keyinputptr->next;
      174     free(keyinputptr);
      175     keyinputptr = nextptr;
      176   }
      177
      178   return n;
      179 }
      180
      181 // *********************************************************************** 
      182 // read model ************************************************************
      183
90 // +++--------------------------------------------------   184 // +++--------------------------------------------------
91 // 法線方向ベクトルの計算   185 // 法線方向ベクトルの計算
92 // +++--------------------------------------------------   186 // +++--------------------------------------------------
93 // glEnable(GL_NORMALIZE) で法線ベクトルは常に正規化して解釈させるのでここでは正規化不要   187 // glEnable(GL_NORMALIZE) で法線ベクトルは常に正規化して解釈させるのでここでは正規化不要
94 // 3頂点 s-t-u , 2ベクトル st and su, 法線ベクトル  n   188 // 3頂点 s-t-u , 2ベクトル st and su, 法線ベクトル  n
95 static void ic2_SetPatchNormal (struct ic2PATCH *p) {   189 static void ic2_SetPatchNormal (struct ic2PATCH *p) {
96   struct ic2POINT oa, ob;   190   struct ic2POINT oa, ob;
97   oa.x = p->t.x - p->s.x;   191   oa.x = p->t.x - p->s.x;
98   oa.y = p->t.y - p->s.y;   192   oa.y = p->t.y - p->s.y;
99   oa.z = p->t.z - p->s.z;   193   oa.z = p->t.z - p->s.z;
100   ob.x = p->u.x - p->s.x;   194   ob.x = p->u.x - p->s.x;
101   ob.y = p->u.y - p->s.y;   195   ob.y = p->u.y - p->s.y;
102   ob.z = p->u.z - p->s.z;   196   ob.z = p->u.z - p->s.z;
103   p->n.x = oa.y * ob.z - oa.z * ob.y;   197   p->n.x = oa.y * ob.z - oa.z * ob.y;
104   p->n.y = oa.z * ob.x - oa.x * ob.z;   198   p->n.y = oa.z * ob.x - oa.x * ob.z;
105   p->n.z = oa.x * ob.y - oa.y * ob.x;   199   p->n.z = oa.x * ob.y - oa.y * ob.x;
106 }   200 }
107   201
108 // +++--------------------------------------------------   202 // +++--------------------------------------------------
109 // パッチに関する追加属性の計算(重心と表示用長さ補正項)   203 // パッチに関する追加属性の計算(重心と表示用長さ補正項)
110 // +++--------------------------------------------------   204 // +++--------------------------------------------------
111 static void ic2_SetPatchMoreAttributes (struct ic2PATCH *p) {   205 static void ic2_SetPatchMoreAttributes (struct ic2PATCH *p) {
112   206
113   // パッチ重心の計算   207   // パッチ重心の計算
114   p->b.x = (p->s.x + p->t.x + p->u.x) / 3;   208   p->b.x = (p->s.x + p->t.x + p->u.x) / 3;
115   p->b.y = (p->s.y + p->t.y + p->u.y) / 3;   209   p->b.y = (p->s.y + p->t.y + p->u.y) / 3;
116   p->b.z = (p->s.z + p->t.z + p->u.z) / 3;   210   p->b.z = (p->s.z + p->t.z + p->u.z) / 3;
117   211
118   // 法線ベクトル表示時の長さ補正項の計算   212   // 法線ベクトル表示時の長さ補正項の計算
119   p->l = sqrt(p->n.x * p->n.x + p->n.y * p->n.y + p->n.z * p->n.z);   213   p->l = sqrt(p->n.x * p->n.x + p->n.y * p->n.y + p->n.z * p->n.z);
120   if (p->l != 0.0) {   214   if (p->l != 0.0) {
121     p->l = sqrt(p->l) / p->l;   215     p->l = sqrt(p->l) / p->l;
122   }   216   }
123 }   217 }
124   218
125 // +++--------------------------------------------------   219 // +++--------------------------------------------------
126 // 新しい三角形パッチ構造体(ic2PATCH)のメモリ確保と初期化   220 // 新しい三角形パッチ構造体(ic2PATCH)のメモリ確保と初期化
127 // +++--------------------------------------------------   221 // +++--------------------------------------------------
128 static struct ic2PATCH *ic2_NewPATCH (void) {   222 static struct ic2PATCH *ic2_NewPATCH (void) {
129   struct ic2PATCH *newpatch = NULL;   223   struct ic2PATCH *newpatch = NULL;
130   224
131   newpatch = (struct ic2PATCH *)calloc(1, sizeof(struct ic2PATCH));   225   newpatch = (struct ic2PATCH *)calloc(1, sizeof(struct ic2PATCH));
132   return (newpatch);   226   return (newpatch);
133 }   227 }
134   228
135 // +++--------------------------------------------------   229 // +++--------------------------------------------------
136 // 三角形パッチ構造体(ic2PATCH)1つ分の読み込み   230 // 三角形パッチ構造体(ic2PATCH)1つ分の読み込み
137 // +++--------------------------------------------------   231 // +++--------------------------------------------------
138 static int ic2_InsertPATCH (struct ic2PATCH **firstpatchptr, char *onelinedata) {   232 static int ic2_InsertPATCH (struct ic2PATCH **firstpatchptr, char *onelinedata) {
139   // (1) 文字列へのポインタは存在するか   233   // (1) 文字列へのポインタは存在するか
140   // (2) メモリ確保/下請け   234   // (2) メモリ確保/下請け
141   // (3) 値の読み込み   235   // (3) 値の読み込み
142   // (4) ic2PATCHリスト構造への組み込み   236   // (4) ic2PATCHリスト構造への組み込み
143   struct ic2PATCH *newpatch = NULL; // 三角形パッチ構造体ヘのポインタ   237   struct ic2PATCH *newpatch = NULL; // 三角形パッチ構造体ヘのポインタ
144   int number_of_element = 0;        // 読み込めた項目数   238   int number_of_element = 0;        // 読み込めた項目数
145   239
146   // (1) 文字列へのポインタは存在するか   240   // (1) 文字列へのポインタは存在するか
147   if (onelinedata == NULL) return 1;   241   if (onelinedata == NULL) return 1;
148   242
149   // (2) メモリ確保/下請け   243   // (2) メモリ確保/下請け
150   if ((newpatch = ic2_NewPATCH()) == NULL) {   244   if ((newpatch = ic2_NewPATCH()) == NULL) {
151     printf("ic2_InsertPATCH: Memory allocation failed.\n");   245     printf("ic2_InsertPATCH: Memory allocation failed.\n");
152     return 2;   246     return 2;
153   }   247   }
154   248
155   // (3) 値の読み込み   249   // (3) 値の読み込み
156   number_of_element =    250   number_of_element = 
157     sscanf(onelinedata, "%f %f %f  %f %f %f  %f %f %f  %f %f %f",    251     sscanf(onelinedata, "%f %f %f  %f %f %f  %f %f %f  %f %f %f", 
158    &newpatch->s.x, &newpatch->s.y, &newpatch->s.z,   252    &newpatch->s.x, &newpatch->s.y, &newpatch->s.z,
159    &newpatch->t.x, &newpatch->t.y, &newpatch->t.z,   253    &newpatch->t.x, &newpatch->t.y, &newpatch->t.z,
160    &newpatch->u.x, &newpatch->u.y, &newpatch->u.z,   254    &newpatch->u.x, &newpatch->u.y, &newpatch->u.z,
161    &newpatch->c.r, &newpatch->c.g, &newpatch->c.b);   255    &newpatch->c.r, &newpatch->c.g, &newpatch->c.b);
162   if (number_of_element != 12) {   256   if (number_of_element != 12) {
163     printf("ic2_InsertPATCH: format error (%d elements found)\n", number_of_element);   257     printf("ic2_InsertPATCH: format error (%d elements found)\n", number_of_element);
164     printf("ic2_InsertPATCH: \"%s\"\n", onelinedata);   258     printf("ic2_InsertPATCH: \"%s\"\n", onelinedata);
165     free(newpatch);   259     free(newpatch);
166     return 3;   260     return 3;
167   }   261   }
168   262
169   // (3.5) 法線ベクトルの計算   263   // (3.5) 法線ベクトルの計算
170   ic2_SetPatchNormal(newpatch);   264   ic2_SetPatchNormal(newpatch);
171   265
172   // (3.6) パッチに関する追加属性の計算(重心と表示用長さ補正項)   266   // (3.6) パッチに関する追加属性の計算(重心と表示用長さ補正項)
173   ic2_SetPatchMoreAttributes(newpatch);   267   ic2_SetPatchMoreAttributes(newpatch);
174   268
175   // (4) ic2PATCHリスト構造への組み込み   269   // (4) ic2PATCHリスト構造への組み込み
176   // *newpatch を 三角形パッチ集合の先頭に挿入   270   // *newpatch を 三角形パッチ集合の先頭に挿入
177   newpatch->next = *firstpatchptr;   271   newpatch->next = *firstpatchptr;
178   *firstpatchptr = newpatch;   272   *firstpatchptr = newpatch;
179   return 0;   273   return 0;
180 }   274 }
181   275
182 // +----------------------------------------------------   276 // +----------------------------------------------------
183 // モデルのファイルからの読込   277 // モデルのファイルからの読込
184 // +----------------------------------------------------   278 // +----------------------------------------------------
185 // 返値:負 ... エラー   279 // 返値:負 ... エラー
186 // 返値:0ないし正値 ... 読み込みに成功したパッチ数   280 // 返値:0ないし正値 ... 読み込みに成功したパッチ数
187 int ic2_ReadModel(char *filename, struct ic2PATCH **firstpatchptr) {   281 int ic2_ReadModel(char *filename, struct ic2PATCH **firstpatchptr) {
188   FILE *filetoopen = NULL; // A pointer to FILE structure   282   FILE *filetoopen = NULL; // A pointer to FILE structure
189   char oneline[256]; // 1行分のバッファ,固定長にしておくとsizeof()が利用可能   283   char oneline[256]; // 1行分のバッファ,固定長にしておくとsizeof()が利用可能
190   char firstword[256]; // コメント行かどうかの判定用   284   char firstword[256]; // コメント行かどうかの判定用
191   int  linenumber = 0; // ファイル中の行番号   285   int  linenumber = 0; // ファイル中の行番号
192   int  patchnumber = 0; // パッチ数   286   int  patchnumber = 0; // パッチ数
193   287
194   // We need at least one option to indicate a file to open   288   // We need at least one option to indicate a file to open
195   if (filename == NULL) {    289   if (filename == NULL) { 
196     printf("Error: You need to specify a one file to open.\n");   290     printf("Error: You need to specify a one file to open.\n");
197     return -1;   291     return -1;
198   }   292   }
199   293
200   // Try to open it   294   // Try to open it
201   filetoopen = fopen(filename, "r");   295   filetoopen = fopen(filename, "r");
202   if (filetoopen == NULL) {   296   if (filetoopen == NULL) {
203     printf("Error: Failed to open/read \"%s\".\n", filename);   297     printf("Error: Failed to open/read \"%s\".\n", filename);
204     return -2;   298     return -2;
205   }   299   }
206   printf("Reading model from \"%s\"\n", filename);   300   printf("Reading model from \"%s\"\n", filename);
207   301
208   // 1行ずつ読込   302   // 1行ずつ読込
209   while (fgets(oneline, sizeof(oneline), filetoopen) != NULL) {   303   while (fgets(oneline, sizeof(oneline), filetoopen) != NULL) {
210     linenumber++;   304     linenumber++;
211   305
212     // もし行内に1文字もなければ(1単語もなければ)次行へ   306     // もし行内に1文字もなければ(1単語もなければ)次行へ
213     if (sscanf(oneline, "%256s", firstword) < 1)   307     if (sscanf(oneline, "%256s", firstword) < 1)
214       continue;   308       continue;
215     // もし先頭が#で始まっていれば次行へ   309     // もし先頭が#で始まっていれば次行へ
216     if (firstword[0] == '#')    310     if (firstword[0] == '#') 
217       continue;   311       continue;
218     // 他のエラートラップ   312     // 他のエラートラップ
219     if (0) {   313     if (0) {
220       printf("Skip(line=%d): %s\n", linenumber, oneline);   314       printf("Skip(line=%d): %s\n", linenumber, oneline);
221       continue;   315       continue;
222     }   316     }
223   317
224     if (ic2_InsertPATCH(firstpatchptr, oneline)) {   318     if (ic2_InsertPATCH(firstpatchptr, oneline)) {
225       printf("Model reading is interrupted.\n");   319       printf("Model reading is interrupted.\n");
226       break;   320       break;
227     }   321     }
228     patchnumber++;   322     patchnumber++;
229   }   323   }
230   324
231   // And close it   325   // And close it
232   if (fclose(filetoopen) != 0) {   326   if (fclose(filetoopen) != 0) {
233     printf("Error: Failed to close \"%s\".\n", filename);   327     printf("Error: Failed to close \"%s\".\n", filename);
234     // error, but we get data anyway...   328     // error, but we get data anyway...
235   }   329   }
236   330
237   printf("Finish reading the model (%d patches).\n", patchnumber);   331   printf("Finish reading the model (%d patches).\n", patchnumber);
238   return patchnumber;   332   return patchnumber;
239 }   333 }
240   334
241 // -----------------------------------------------------   335 // -----------------------------------------------------
242 // 三角形パッチ構造体(ic2PATCH)リストの表示   336 // 三角形パッチ構造体(ic2PATCH)リストの表示
243 // -----------------------------------------------------   337 // -----------------------------------------------------
244 int ic2_PrintPATCHList (struct ic2PATCH *firstpatchptr) {   338 int ic2_PrintPATCHList (struct ic2PATCH *firstpatchptr) {
245   struct ic2PATCH *p;   339   struct ic2PATCH *p;
246   int np = 0;   340   int np = 0;
247   341
248   for (p = firstpatchptr; p != NULL; p = p->next) {   342   for (p = firstpatchptr; p != NULL; p = p->next) {
249     np++;   343     np++;
250     printf("PATCH: (%g, %g, %g), (%g, %g, %g), (%g, %g, %g), rgb=[%g, %g, %g] ",   344     printf("PATCH: (%g, %g, %g), (%g, %g, %g), (%g, %g, %g), rgb=[%g, %g, %g] ",
251    p->s.x, p->s.y, p->s.z,   345    p->s.x, p->s.y, p->s.z,
252    p->t.x, p->t.y, p->t.z,   346    p->t.x, p->t.y, p->t.z,
253    p->u.x, p->u.y, p->u.z,   347    p->u.x, p->u.y, p->u.z,
254    p->c.r, p->c.g, p->c.b);   348    p->c.r, p->c.g, p->c.b);
255     printf("n=(%g, %g, %g), b=(%g, %g, %g), l=%g\n",   349     printf("n=(%g, %g, %g), b=(%g, %g, %g), l=%g\n",
256    p->n.x, p->n.y, p->n.z,   350    p->n.x, p->n.y, p->n.z,
257    p->b.x, p->b.y, p->b.z,   351    p->b.x, p->b.y, p->b.z,
258    p->l);   352    p->l);
259   }   353   }
260   354
261   return np;   355   return np;
262 }   356 }
263   357
264 // ***********************************************************************    358 // *********************************************************************** 
265 // gl utilitiess *********************************************************   359 // gl utilitiess *********************************************************
266   360
267 // +----------------------------------------------------   361 // +----------------------------------------------------
268 // MODELVIEW Matrix と PROJECTION を表示する   362 // MODELVIEW Matrix と PROJECTION を表示する
269 // +----------------------------------------------------   363 // +----------------------------------------------------
270 void ic2_ShowMATRIX (char *str) {   364 void ic2_ShowMATRIX (char *str) {
271   GLfloat m[16]; // GL_MODELVIEW matrix   365   GLfloat m[16]; // GL_MODELVIEW matrix
272   GLfloat p[16]; // GL_PROJECTION matrix   366   GLfloat p[16]; // GL_PROJECTION matrix
273   367
274   glGetFloatv(GL_MODELVIEW_MATRIX , m);  // MODELVIEWのスタックトップmatrixをmにコピー   368   glGetFloatv(GL_MODELVIEW_MATRIX , m);  // MODELVIEWのスタックトップmatrixをmにコピー
275   glGetFloatv(GL_PROJECTION_MATRIX, p); // PROJECTIONのスタックトップmatrixをpにコピー   369   glGetFloatv(GL_PROJECTION_MATRIX, p); // PROJECTIONのスタックトップmatrixをpにコピー
276   if (str != NULL) printf("<< %s >>\n", str);   370   if (str != NULL) printf("<< %s >>\n", str);
277   printf("MODELVIEW Matrix                        PROJECTION Matrix\n");   371   printf("MODELVIEW Matrix                        PROJECTION Matrix\n");
278   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n",   372   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n",
279           m[ 0], m[ 4], m[ 8], m[12],     p[ 0], p[ 4], p[ 8], p[12]);   373           m[ 0], m[ 4], m[ 8], m[12],     p[ 0], p[ 4], p[ 8], p[12]);
280   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n",    374   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n", 
281           m[ 1], m[ 5], m[ 9], m[13],     p[ 1], p[ 5], p[ 9], p[13]);   375           m[ 1], m[ 5], m[ 9], m[13],     p[ 1], p[ 5], p[ 9], p[13]);
282   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n",    376   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n", 
283           m[ 2], m[ 6], m[10], m[14],     p[ 2], p[ 6], p[10], p[14]);   377           m[ 2], m[ 6], m[10], m[14],     p[ 2], p[ 6], p[10], p[14]);
284   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n",    378   printf("%7.3f  %7.3f  %7.3f  %7.3f      %7.3f  %7.3f  %7.3f  %7.3f\n", 
285           m[ 3], m[ 7], m[11], m[15],     p[ 3], p[ 7], p[11], p[15]);   379           m[ 3], m[ 7], m[11], m[15],     p[ 3], p[ 7], p[11], p[15]);
286 }   380 }
287   381
288 // ***********************************************************************    382 // *********************************************************************** 
289 // objects_embeded *******************************************************   383 // objects_embeded *******************************************************
290   384
291 // +----------------------------------------------------   385 // +----------------------------------------------------
292 // 正方形を描く   386 // 正方形を描く
293 // +----------------------------------------------------   387 // +----------------------------------------------------
294 void ic2_FigSquare (float s) {   388 void ic2_FigSquare (float s) {
295   glDisable(GL_LIGHTING);   // 光源によるシェーディングを一旦切る   389   glDisable(GL_LIGHTING);   // 光源によるシェーディングを一旦切る
296   390
297   // 正方形(Z=0の平面内、+/- 0.9)   391   // 正方形(Z=0の平面内、+/- 0.9)
298   glBegin(GL_LINE_LOOP); {   392   glBegin(GL_LINE_LOOP); {
299     glColor3f(1.0, 1.0, 1.0);   393     glColor3f(1.0, 1.0, 1.0);
300     glVertex3f(s * -1, s * -1, 0.0);   394     glVertex3f(s * -1, s * -1, 0.0);
301     glVertex3f(s * +1, s * -1, 0.0);   395     glVertex3f(s * +1, s * -1, 0.0);
302     glVertex3f(s * +1, s * +1, 0.0);   396     glVertex3f(s * +1, s * +1, 0.0);
303     glVertex3f(s * -1, s * +1, 0.0);   397     glVertex3f(s * -1, s * +1, 0.0);
304   } glEnd();   398   } glEnd();
305   399
306   // 3軸   400   // 3軸
307   glBegin(GL_LINES); {   401   glBegin(GL_LINES); {
308     glColor3f(1.0, 0.5, 0.5); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.85, 0.0,  0.0); // X (red)   402     glColor3f(1.0, 0.5, 0.5); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.85, 0.0,  0.0); // X (red)
309     glColor3f(0.5, 1.0, 0.5); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0,  0.70, 0.0); // Y (green)   403     glColor3f(0.5, 1.0, 0.5); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0,  0.70, 0.0); // Y (green)
310     glColor3f(0.5, 0.5, 1.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0,  0.0,  1.0); // Z (blue)   404     glColor3f(0.5, 0.5, 1.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0,  0.0,  1.0); // Z (blue)
311   } glEnd();   405   } glEnd();
312   406
313   glEnable(GL_LIGHTING);   // 光源によるシェーディングを開始する   407   glEnable(GL_LIGHTING);   // 光源によるシェーディングを開始する
314 }   408 }
315   409
316 // +----------------------------------------------------   410 // +----------------------------------------------------
317 // ティーポットを描く (glutの作り付け関数の1つ)   411 // ティーポットを描く (glutの作り付け関数の1つ)
318 // +----------------------------------------------------   412 // +----------------------------------------------------
319 void ic2_FigSolidTeapot (float s) {   413 void ic2_FigSolidTeapot (float s) {
320   GLfloat obj_ref[] = {1.0, 1.0, 0.3, 1.0}; // teapotの色情報 (DIFFUSE用)   414   GLfloat obj_ref[] = {1.0, 1.0, 0.3, 1.0}; // teapotの色情報 (DIFFUSE用)
321   GLfloat obj_shn[] = {10.0};               // teapotの色情報 (SHININESS用)   415   GLfloat obj_shn[] = {10.0};               // teapotの色情報 (SHININESS用)
322   416
323   // 色の設定   417   // 色の設定
324   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, obj_ref);   418   glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, obj_ref);
325   glMaterialfv(GL_FRONT, GL_SHININESS, obj_shn);   419   glMaterialfv(GL_FRONT, GL_SHININESS, obj_shn);
326   420
327   glutSolidTeapot(s);   421   glutSolidTeapot(s);
328 }   422 }
329   423
330 // ***********************************************************************    424 // *********************************************************************** 
331 // objects_model *********************************************************   425 // objects_model *********************************************************
332   426
333 // +----------------------------------------------------   427 // +----------------------------------------------------
334 // ファイルからの物体を表示   428 // ファイルからの物体を表示
335 // +----------------------------------------------------   429 // +----------------------------------------------------
336 int ic2_DrawModel (struct ic2PATCH *firstpatchptr) {   430 int ic2_DrawModel (struct ic2PATCH *firstpatchptr) {
337   struct ic2PATCH  *p; // パッチ構造体へのポインタ   431   struct ic2PATCH  *p; // パッチ構造体へのポインタ
338   432
339   for (p = firstpatchptr; p != NULL; p = p->next) {   433   for (p = firstpatchptr; p != NULL; p = p->next) {
340     GLfloat v[4];   434     GLfloat v[4];
341   435
342     // 面の色要素(反射特性)をDiffuseとSpecularについて指示   436     // 面の色要素(反射特性)をDiffuseとSpecularについて指示
343     v[0] = p->c.r; v[1] = p->c.g; v[2] = p->c.b; v[3] = 1.0;   437     v[0] = p->c.r; v[1] = p->c.g; v[2] = p->c.b; v[3] = 1.0;
344     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, v);   438     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, v);
345     v[0] = 10.0;   439     v[0] = 10.0;
346     glMaterialfv(GL_FRONT, GL_SHININESS, v);   440     glMaterialfv(GL_FRONT, GL_SHININESS, v);
347   441
348     // 面の法線を指示   442     // 面の法線を指示
349     glNormal3f(p->n.x, p->n.y, p->n.z);   443     glNormal3f(p->n.x, p->n.y, p->n.z);
350   444
351     // 面を構成する3頂点を指示   445     // 面を構成する3頂点を指示
352     glBegin(GL_TRIANGLES); {   446     glBegin(GL_TRIANGLES); {
353       glVertex3f(p->s.x, p->s.y, p->s.z);   447       glVertex3f(p->s.x, p->s.y, p->s.z);
354       glVertex3f(p->t.x, p->t.y, p->t.z);   448       glVertex3f(p->t.x, p->t.y, p->t.z);
355       glVertex3f(p->u.x, p->u.y, p->u.z);   449       glVertex3f(p->u.x, p->u.y, p->u.z);
356     } glEnd();   450     } glEnd();
357   451
358     // 法線の表示   452     // 法線の表示
359     if (tgl_shownormal == 1) {   453     if (tgl_shownormal == 1) {
360       glDisable(GL_LIGHTING);   454       glDisable(GL_LIGHTING);
361       glColor3f(0.3, 1.0, 0.4);   455       glColor3f(0.3, 1.0, 0.4);
362       glBegin(GL_LINES); {   456       glBegin(GL_LINES); {
363         glVertex3f(p->b.x, p->b.y, p->b.z);   457         glVertex3f(p->b.x, p->b.y, p->b.z);
364         glVertex3f(p->b.x + p->l * p->n.x, p->b.y + p->l * p->n.y, p->b.z + p->l * p->n.z);   458         glVertex3f(p->b.x + p->l * p->n.x, p->b.y + p->l * p->n.y, p->b.z + p->l * p->n.z);
365       } glEnd();   459       } glEnd();
366       glEnable(GL_LIGHTING);   460       glEnable(GL_LIGHTING);
367     }   461     }
368        462     
369   }   463   }
370   return 0;   464   return 0;
371 }   465 }
372   466
373 // ***********************************************************************    467 // *********************************************************************** 
374 // lighting **************************************************************    468 // lighting ************************************************************** 
375   469
376 // +----------------------------------------------------   470 // +----------------------------------------------------
377 // 光源を用意   471 // 光源を用意
378 // +----------------------------------------------------   472 // +----------------------------------------------------
379 //  X     Y     Z     Diff(R,G,B)   Spec(R,G,B)   473 //  X     Y     Z     Diff(R,G,B)   Spec(R,G,B)
380 //  1.0   2.0   3.0   0.2 0.2 0.2   0.4 0.4 0.4   474 //  1.0   2.0   3.0   0.2 0.2 0.2   0.4 0.4 0.4
381 // -1.0   2.0   3.0   0.4 0.4 0.4   0.4 0.4 0.4   475 // -1.0   2.0   3.0   0.4 0.4 0.4   0.4 0.4 0.4
382 //  0.0   4.0   0.0   1.0 1.0 1.0   1.0 1.0 1.0   476 //  0.0   4.0   0.0   1.0 1.0 1.0   1.0 1.0 1.0
383 void ic2_LightSetA (void) {   477 void ic2_LightSetA (void) {
384   static int initflag = 0;   478   static int initflag = 0;
385   479
386   if (initflag == 0) {   480   if (initflag == 0) {
387     glEnable(GL_DEPTH_TEST); // デプスバッファによる描画を行う   481     glEnable(GL_DEPTH_TEST); // デプスバッファによる描画を行う
388     glEnable(GL_NORMALIZE);  // 法線ベクトルを常に正規化して解釈させる   482     glEnable(GL_NORMALIZE);  // 法線ベクトルを常に正規化して解釈させる
389     glEnable(GL_LIGHTING);   // 光源によるシェーディングを開始する   483     glEnable(GL_LIGHTING);   // 光源によるシェーディングを開始する
390     glEnable(GL_LIGHT0);     // LIGHT0 を利用   484     glEnable(GL_LIGHT0);     // LIGHT0 を利用
391     glEnable(GL_LIGHT1);     // LIGHT1 を利用   485     glEnable(GL_LIGHT1);     // LIGHT1 を利用
392     glEnable(GL_LIGHT2);     // LIGHT2 を利用   486     glEnable(GL_LIGHT2);     // LIGHT2 を利用
393     initflag = 1;   487     initflag = 1;
394   }   488   }
395      489   
396   GLfloat val[4];   490   GLfloat val[4];
397   491
398   val[0] =  1.0; val[1] =  2.0; val[2] =  3.0; val[3] = 1.0; glLightfv(GL_LIGHT0, GL_POSITION, val);   492   val[0] =  1.0; val[1] =  2.0; val[2] =  3.0; val[3] = 1.0; glLightfv(GL_LIGHT0, GL_POSITION, val);
399   val[0] =  0.2; val[1] =  0.2; val[2] =  0.2; val[3] = 1.0; glLightfv(GL_LIGHT0, GL_DIFFUSE,  val);   493   val[0] =  0.2; val[1] =  0.2; val[2] =  0.2; val[3] = 1.0; glLightfv(GL_LIGHT0, GL_DIFFUSE,  val);
400   val[0] =  0.4; val[1] =  0.4; val[2] =  0.4; val[3] = 1.0; glLightfv(GL_LIGHT0, GL_SPECULAR, val);   494   val[0] =  0.4; val[1] =  0.4; val[2] =  0.4; val[3] = 1.0; glLightfv(GL_LIGHT0, GL_SPECULAR, val);
401   495
402   val[0] = -1.0; val[1] =  2.0; val[2] =  3.0; val[3] = 1.0; glLightfv(GL_LIGHT1, GL_POSITION, val);   496   val[0] = -1.0; val[1] =  2.0; val[2] =  3.0; val[3] = 1.0; glLightfv(GL_LIGHT1, GL_POSITION, val);
403   val[0] =  0.4; val[1] =  0.4; val[2] =  0.4; val[3] = 1.0; glLightfv(GL_LIGHT1, GL_DIFFUSE,  val);   497   val[0] =  0.4; val[1] =  0.4; val[2] =  0.4; val[3] = 1.0; glLightfv(GL_LIGHT1, GL_DIFFUSE,  val);
404   val[0] =  0.4; val[1] =  0.4; val[2] =  0.4; val[3] = 1.0; glLightfv(GL_LIGHT1, GL_SPECULAR, val);   498   val[0] =  0.4; val[1] =  0.4; val[2] =  0.4; val[3] = 1.0; glLightfv(GL_LIGHT1, GL_SPECULAR, val);
405   499
406   val[0] =  0.0; val[1] =  4.0; val[2] =  0.0; val[3] = 1.0; glLightfv(GL_LIGHT2, GL_POSITION, val);   500   val[0] =  0.0; val[1] =  4.0; val[2] =  0.0; val[3] = 1.0; glLightfv(GL_LIGHT2, GL_POSITION, val);
407   val[0] =  1.0; val[1] =  1.0; val[2] =  1.0; val[3] = 1.0; glLightfv(GL_LIGHT2, GL_DIFFUSE,  val);   501   val[0] =  1.0; val[1] =  1.0; val[2] =  1.0; val[3] = 1.0; glLightfv(GL_LIGHT2, GL_DIFFUSE,  val);
408   val[0] =  1.0; val[1] =  1.0; val[2] =  1.0; val[3] = 1.0; glLightfv(GL_LIGHT2, GL_SPECULAR, val);   502   val[0] =  1.0; val[1] =  1.0; val[2] =  1.0; val[3] = 1.0; glLightfv(GL_LIGHT2, GL_SPECULAR, val);
409 }   503 }
410   504
411 // ***********************************************************************    505 // *********************************************************************** 
412 // camera work ***********************************************************   506 // camera work ***********************************************************
413   507
414 // +----------------------------------------------------   508 // +----------------------------------------------------
415 // カメラの投影行列を設定   509 // カメラの投影行列を設定
416 // +----------------------------------------------------   510 // +----------------------------------------------------
417 // 利用する大域変数: window_w, window_h   511 // 利用する大域変数: window_w, window_h
418 // window_w/window_hの変化に対して、物体の見かけの大きさが変わらないように描画   512 // window_w/window_hの変化に対して、物体の見かけの大きさが変わらないように描画
419 // → ortho_unit が重要!   513 // → ortho_unit が重要!
420 //   514 //
421 void ic2_SetUpCamera_Ortho (void) {   515 void ic2_SetUpCamera_Ortho (void) {
422   float wlimit, hlimit;   516   float wlimit, hlimit;
423   wlimit = (window_w/2) / ortho_unit;    517   wlimit = (window_w/2) / ortho_unit; 
424   hlimit = (window_h/2) / ortho_unit;    518   hlimit = (window_h/2) / ortho_unit; 
425   519
426   // glOrtho(左端, 右端, 下端, 上端, 近接側クリッピング面,  遠方側クリッピング面)   520   // glOrtho(左端, 右端, 下端, 上端, 近接側クリッピング面,  遠方側クリッピング面)
427   glMatrixMode(GL_PROJECTION);   521   glMatrixMode(GL_PROJECTION);
428   glLoadIdentity(); // 毎フレーム再設定するのでPROJECTION行列スタックトップの初期化必要   522   glLoadIdentity(); // 毎フレーム再設定するのでPROJECTION行列スタックトップの初期化必要
429   glOrtho(-wlimit, wlimit, -hlimit, hlimit, -1.0, 1.0);   523   glOrtho(-wlimit, wlimit, -hlimit, hlimit, -1.0, 1.0);
430   524
431   // 通常はMODELVIEWを操作するので念のため元に戻しておく.   525   // 通常はMODELVIEWを操作するので念のため元に戻しておく.
432   glMatrixMode(GL_MODELVIEW);   526   glMatrixMode(GL_MODELVIEW);
433 }   527 }
434   528
435 // +----------------------------------------------------   529 // +----------------------------------------------------
436 // カメラの投影行列を設定   530 // カメラの投影行列を設定
437 // +----------------------------------------------------   531 // +----------------------------------------------------
438 // 利用する大域変数: window_w, window_h, camera_f   532 // 利用する大域変数: window_w, window_h, camera_f
439 // window_w/window_hの変化に対して、物体の見かけの大きさが変わらないように描画   533 // window_w/window_hの変化に対して、物体の見かけの大きさが変わらないように描画
440 // → 焦点距離 camera_f が重要!   534 // → 焦点距離 camera_f が重要!
441 // 注: glViewport()の設定により本演習では撮像面=ウィンドウの大きさ   535 // 注: glViewport()の設定により本演習では撮像面=ウィンドウの大きさ
442 //   536 //
443 void ic2_SetUpCamera_Perspective (void) {   537 void ic2_SetUpCamera_Perspective (void) {
444   float fovy; // 垂直画角    538   float fovy; // 垂直画角 
445   float aspect; // 撮像面のアスペクト比   539   float aspect; // 撮像面のアスペクト比
446   float depth_near_end =   0.1; // 近距離限界   540   float depth_near_end =   0.1; // 近距離限界
447   float depth_far_end  = 100.0; // 遠距離限界   541   float depth_far_end  = 100.0; // 遠距離限界
448   542
449   // 透視投影を規定するためのパラメータ   543   // 透視投影を規定するためのパラメータ
450   fovy = atan((window_h/2.0)/camera_f)*2.0*(180.0/M_PI);   544   fovy = atan((window_h/2.0)/camera_f)*2.0*(180.0/M_PI);
451   aspect = (float)window_w/window_h;   545   aspect = (float)window_w/window_h;
452   depth_near_end = 0.1;   546   depth_near_end = 0.1;
453   depth_far_end  = 100.0;   547   depth_far_end  = 100.0;
454   548
455   // 透視投影行列   549   // 透視投影行列
456   glMatrixMode(GL_PROJECTION);   550   glMatrixMode(GL_PROJECTION);
457   glLoadIdentity(); // 毎フレーム再設定するのでPROJECTION行列スタックトップの初期化必要   551   glLoadIdentity(); // 毎フレーム再設定するのでPROJECTION行列スタックトップの初期化必要
458   gluPerspective(fovy, aspect, depth_near_end, depth_far_end);   552   gluPerspective(fovy, aspect, depth_near_end, depth_far_end);
459      553   
460   // 通常はMODELVIEWを操作するので念のため元に戻しておく.   554   // 通常はMODELVIEWを操作するので念のため元に戻しておく.
461   glMatrixMode(GL_MODELVIEW);   555   glMatrixMode(GL_MODELVIEW);
462 }   556 }
463   557
464 // ***********************************************************************    558 // *********************************************************************** 
465 // rendering *************************************************************   559 // rendering *************************************************************
466   560
467 // +----------------------------------------------------   561 // +----------------------------------------------------
468 // スクリーンに描画する   562 // スクリーンに描画する
469 // +----------------------------------------------------   563 // +----------------------------------------------------
470 void ic2_DrawFrame (void) {   564 void ic2_DrawFrame (void) {
471   565
472   // (前処理) 以前にglClearColor()で指定した色で塗り潰す   566   // (前処理) 以前にglClearColor()で指定した色で塗り潰す
473   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    567   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
474   // (前処理) 今回CGを描画する範囲   568   // (前処理) 今回CGを描画する範囲
475   glViewport(0, 0, window_w, window_h);   569   glViewport(0, 0, window_w, window_h);
476   570
477   // (1) カメラの設置   571   // (1) カメラの設置
478   if (tgl_perspective == 1) {   572   if (tgl_perspective == 1) {
479     ic2_SetUpCamera_Perspective();   573     ic2_SetUpCamera_Perspective();
480   } else {   574   } else {
481     ic2_SetUpCamera_Ortho();   575     ic2_SetUpCamera_Ortho();
482   }   576   }
483   577
484   // (2) 光源の設置   578   // (2) 光源の設置
485   ic2_LightSetA();   579   ic2_LightSetA();
486   580
487   // (3) 物体の設置   581   // (3) 物体の設置
488   // 一時的な光源環境の操作時にはロックした行列を上乗せ   582   // 一時的な光源環境の操作時にはロックした行列を上乗せ
489   if (tgl_movelightonly == 1) {   583   if (tgl_movelightonly == 1) {
490     glMatrixMode(GL_MODELVIEW);   584     glMatrixMode(GL_MODELVIEW);
491     glPushMatrix();   585     glPushMatrix();
492     glLoadMatrixf(mvmlocked);   586     glLoadMatrixf(mvmlocked);
493   }       587   }    
494   if (tgl_showpredefined == 1) {   588   if (tgl_showpredefined == 1) {
495     // 物体描画:正方形   589     // 物体描画:正方形
496     ic2_FigSquare(0.9);   590     ic2_FigSquare(0.9);
497     // 物体描画:ティーポット   591     // 物体描画:ティーポット
498     ic2_FigSolidTeapot(0.5);   592     ic2_FigSolidTeapot(0.5);
499   }   593   }
500   ic2_DrawModel(firstpatchptr);   594   ic2_DrawModel(firstpatchptr);
501   // 一時的な光源環境の操作時には上乗せした行列を廃棄   595   // 一時的な光源環境の操作時には上乗せした行列を廃棄
502   if (tgl_movelightonly == 1) {   596   if (tgl_movelightonly == 1) {
503     glPopMatrix();   597     glPopMatrix();
504   }   598   }
505   599
506   // (後処理) スクリーンの切り替え   600   // (後処理) スクリーンの切り替え
507   glutSwapBuffers();   601   glutSwapBuffers();
508   602
509 }   603 }
510   604
511 // ***********************************************************************    605 // *********************************************************************** 
512 // callbacks *************************************************************    606 // callbacks ************************************************************* 
513   607
514 // +----------------------------------------------------   608 // +----------------------------------------------------
515 // キーが何か押されたときの対策用関数    609 // キーが何か押されたときの対策用関数 
516 // +----------------------------------------------------   610 // +----------------------------------------------------
517 // glutKeyboardFunc()にて登録予定   611 // glutKeyboardFunc()にて登録予定
518 // 引数 : key ... 入力文字    612 // 引数 : key ... 入力文字 
519 // 引数 : x   ... 文字が押されたときのマウスカーソルのX位置    613 // 引数 : x   ... 文字が押されたときのマウスカーソルのX位置 
520 // 引数 : y   ... 文字が押されたときのマウスカーソルのY位置    614 // 引数 : y   ... 文字が押されたときのマウスカーソルのY位置 
521 void ic2_NormalKeyInput (unsigned char key, int x, int y) {   615 void ic2_NormalKeyInput (unsigned char key, int x, int y) {
522   float delta_t = 0.1; // [unit]   616   float delta_t = 0.1; // [unit]
523   float delta_r = 1.0; // [degree]   617   float delta_r = 1.0; // [degree]
524   618
525   switch (key) {   619   switch (key) {
526   case 'q' :   620   case 'q' :
527   case 'Q' :   621   case 'Q' :
528   case 27 : // ESCキーのこと   622   case 27 : // ESCキーのこと
529     exit (0);   623     exit (0);
530     break;   624     break;
531   625
532   // Translation -_+ : [X]h_l [Y]n_u [Z]j_k   626   // Translation -_+ : [X]h_l [Y]n_u [Z]j_k
533   case 'h': glTranslatef(delta_t * -1, 0, 0); break;   627   case 'h': glTranslatef(delta_t * -1, 0, 0); ic2_LogKey(key); break;
534   case 'l': glTranslatef(delta_t * +1, 0, 0); break;   628   case 'l': glTranslatef(delta_t * +1, 0, 0); ic2_LogKey(key); break;
535   case 'n': glTranslatef(0, delta_t * -1, 0); break;   629   case 'n': glTranslatef(0, delta_t * -1, 0); ic2_LogKey(key); break;
536   case 'u': glTranslatef(0, delta_t * +1, 0); break;   630   case 'u': glTranslatef(0, delta_t * +1, 0); ic2_LogKey(key); break;
537   case 'j': glTranslatef(0, 0, delta_t * -1); break;   631   case 'j': glTranslatef(0, 0, delta_t * -1); ic2_LogKey(key); break;
538   case 'k': glTranslatef(0, 0, delta_t * +1); break;   632   case 'k': glTranslatef(0, 0, delta_t * +1); ic2_LogKey(key); break;
539   633
540   // Rotation -_+ : [Y]a_f [Z]s_d [X]x_w   634   // Rotation -_+ : [Y]a_f [Z]s_d [X]x_w
541   case 'x': glRotatef(delta_r * -1, 1, 0, 0); break;   635   case 'x': glRotatef(delta_r * -1, 1, 0, 0); ic2_LogKey(key);  break;
542   case 'w': glRotatef(delta_r * +1, 1, 0, 0); break;   636   case 'w': glRotatef(delta_r * +1, 1, 0, 0); ic2_LogKey(key);  break;
543   case 'a': glRotatef(delta_r * -1, 0, 1, 0); break;   637   case 'a': glRotatef(delta_r * -1, 0, 1, 0); ic2_LogKey(key);  break;
544   case 'f': glRotatef(delta_r * +1, 0, 1, 0); break;   638   case 'f': glRotatef(delta_r * +1, 0, 1, 0); ic2_LogKey(key);  break;
545   case 's': glRotatef(delta_r * -1, 0, 0, 1); break;   639   case 's': glRotatef(delta_r * -1, 0, 0, 1); ic2_LogKey(key);  break;
546   case 'd': glRotatef(delta_r * +1, 0, 0, 1); break;   640   case 'd': glRotatef(delta_r * +1, 0, 0, 1); ic2_LogKey(key);  break;
547   641
548   // [Scale] v_b   642   // [Scale] v_b
549   case 'v': glScalef(0.95, 0.95, 0.95); break;   643   case 'v': glScalef(0.95, 0.95, 0.95); ic2_LogKey(key);  break;
550   case 'b': glScalef(1.05, 1.05, 1.05); break;   644   case 'b': glScalef(1.05, 1.05, 1.05); ic2_LogKey(key);  break;
551   645
552   // [Reset]    646   // [Reset] 
553   case 'R':    647   case 'R': 
554     glMatrixMode(GL_MODELVIEW);   648     glMatrixMode(GL_MODELVIEW);
555     glPopMatrix(); // 保護されてた第1階層に降りる   649     glPopMatrix(); // 保護されてた第1階層に降りる
556     glPushMatrix(); // 保護されてた第1階層からコピーしてスタックトップを1つ上げる   650     glPushMatrix(); // 保護されてた第1階層からコピーしてスタックトップを1つ上げる
      651     ic2_LogKey(key);
557     break;   652     break;
558   653
559   // [Show Stacktop MODELVIEW Matrix]   654   // [Show Stacktop MODELVIEW Matrix]
560   case 'p':   655   case 'p':
561     ic2_ShowMATRIX("Current status");   656     ic2_ShowMATRIX("Current status");
562     break;   657     break;
563   658
564   // [Toggle Objects] T   659   // [Toggle Objects] T
565   case 'T': tgl_showpredefined *= -1; break;   660   case 'T': tgl_showpredefined *= -1; break;
566   // [Toggle Normals] N   661   // [Toggle Normals] N
567   case 'N': tgl_shownormal *= -1; break;   662   case 'N': tgl_shownormal *= -1; break;
568   // [Move only lights temporarily] L   663   // [Move only lights temporarily] L
569   case 'L':    664   case 'L': 
570     tgl_movelightonly *= -1;    665     tgl_movelightonly *= -1; 
571     if (tgl_movelightonly == 1) {   666     if (tgl_movelightonly == 1) {
572       // この時点のMODELVIEW行列を保存してロック状態にする   667       // この時点のMODELVIEW行列を保存してロック状態にする
573       glMatrixMode(GL_MODELVIEW);   668       glMatrixMode(GL_MODELVIEW);
574       glGetFloatv(GL_MODELVIEW_MATRIX , mvmlocked);   669       glGetFloatv(GL_MODELVIEW_MATRIX , mvmlocked);
575     } else {   670     } else {
576       // ロック状態を開始したときの状況に復帰   671       // ロック状態を開始したときの状況に復帰
577       glMatrixMode(GL_MODELVIEW);   672       glMatrixMode(GL_MODELVIEW);
578       glLoadMatrixf(mvmlocked);   673       glLoadMatrixf(mvmlocked);
579     }   674     }
580     break;   675     break;
581   // [Toggle Projection Method] P   676   // [Toggle Projection Method] O, P
582   case 'P': tgl_perspective *= -1; break;   677   case 'O': tgl_perspective = -1; ic2_LogKey(key); break;
      678   case 'P': tgl_perspective = +1; ic2_LogKey(key); break;
      679
      680   // [Key Memory - Animation]
      681   case 'S': 
      682     // リンクトリストの初期化
      683     ic2_FreeKEYINPUTList(firstkeyinputptr); 
      684     firstkeyinputptr = NULL;
      685     latestkeyinputptr = NULL;
      686     tgl_keyinput = 1; // 記録開始
      687     ic2_NormalKeyInput('O', 0, 0); // 投影の初期化(直交投影)
      688     ic2_NormalKeyInput('R', 0, 0); // MODELVIEW行列の初期化
      689     printf("Start recording\n"); 
      690     break;
      691   case 'E': 
      692     tgl_keyinput = -1; 
      693     printf("End recording\n"); 
      694     break;
      695   case 'A': 
      696     ic2_PrintKEYINPUTList(firstkeyinputptr); 
      697     break;
583   }   698   }
584   699
585   // 次のメインループ(glutMainLoop)での繰り返し時に描画を要求   700   // 次のメインループ(glutMainLoop)での繰り返し時に描画を要求
586   glutPostWindowRedisplay(window_id);   701   glutPostWindowRedisplay(window_id);
587 }   702 }
588   703
589 // +----------------------------------------------------   704 // +----------------------------------------------------
590 // ウィンドウサイズの変更が生じたときの対策用関数   705 // ウィンドウサイズの変更が生じたときの対策用関数
591 // +----------------------------------------------------   706 // +----------------------------------------------------
592 // glutReshapeFunc()にて登録   707 // glutReshapeFunc()にて登録
593 void ic2_ReshapeWindow (int w, int h) {   708 void ic2_ReshapeWindow (int w, int h) {
594   709
595   // 新しいウィンドウサイズを大域変数にセット   710   // 新しいウィンドウサイズを大域変数にセット
596   window_w = w; window_h = h;   711   window_w = w; window_h = h;
597   712
598   // 次のメインループ(glutMainLoop)での繰り返し時に描画を要求   713   // 次のメインループ(glutMainLoop)での繰り返し時に描画を要求
599   glutPostWindowRedisplay(window_id);   714   glutPostWindowRedisplay(window_id);
600 }   715 }
601   716
602 // +----------------------------------------------------   717 // +----------------------------------------------------
603 // OpenGLとしてのWindowの初期化   718 // OpenGLとしてのWindowの初期化
604 // +----------------------------------------------------   719 // +----------------------------------------------------
605 void ic2_BootWindow (char winname[]) {   720 void ic2_BootWindow (char winname[]) {
606   721
607   // ダブルバッファ,RGB表色モード,デプスバッファ を利用   722   // ダブルバッファ,RGB表色モード,デプスバッファ を利用
608   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);    723   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
609   724
610   // ウィンドウの大きさ   725   // ウィンドウの大きさ
611   glutInitWindowSize(window_w, window_h);   726   glutInitWindowSize(window_w, window_h);
612   727
613   // ウィンドウを開く   728   // ウィンドウを開く
614   window_id = glutCreateWindow(winname);   729   window_id = glutCreateWindow(winname);
615   730
616   // レンダリングにはSmooth Shadingを採用   731   // レンダリングにはSmooth Shadingを採用
617   glShadeModel(GL_SMOOTH);   732   glShadeModel(GL_SMOOTH);
618   733
619   // ウィンドウ全体を書き直すときの色(ここでは黒)   734   // ウィンドウ全体を書き直すときの色(ここでは黒)
620   glClearColor(0.0, 0.0, 0.0, 0.0);   735   glClearColor(0.0, 0.0, 0.0, 0.0);
621   736
622   // 初期MODELVIEW matrixの保護   737   // 初期MODELVIEW matrixの保護
623   glMatrixMode(GL_MODELVIEW);    738   glMatrixMode(GL_MODELVIEW); 
624   glPushMatrix(); // 以後本プログラムでは GL_MODELVIEW スタックの2層目以上で作業   739   glPushMatrix(); // 以後本プログラムでは GL_MODELVIEW スタックの2層目以上で作業
625   740
626   // Callback関数を設定 (イベント処理)   741   // Callback関数を設定 (イベント処理)
627   glutIdleFunc(ic2_DrawFrame); // 暇だったらフレームを描く(よい実装ではない)   742   glutIdleFunc(ic2_DrawFrame); // 暇だったらフレームを描く(よい実装ではない)
628   glutKeyboardFunc(ic2_NormalKeyInput); // キーが押されたときの対策   743   glutKeyboardFunc(ic2_NormalKeyInput); // キーが押されたときの対策
629   glutReshapeFunc(ic2_ReshapeWindow); // ウィンドウサイズ変更が検知されたときの対策   744   glutReshapeFunc(ic2_ReshapeWindow); // ウィンドウサイズ変更が検知されたときの対策
630 }   745 }
631   746
632 // ***********************************************************************    747 // *********************************************************************** 
633 // main  *****************************************************************   748 // main  *****************************************************************
634 // +----------------------------------------------------   749 // +----------------------------------------------------
635 // Main Function   750 // Main Function
636 // +----------------------------------------------------   751 // +----------------------------------------------------
637 int main (int argc, char *argv[]) {   752 int main (int argc, char *argv[]) {
638   int numberpatches = 0;   753   int numberpatches = 0;
639   754
640   // model ファイルの読み込み   755   // model ファイルの読み込み
641   if (argc <= 1) {   756   if (argc <= 1) {
642     printf("Error: no model file is specified.\n");   757     printf("Error: no model file is specified.\n");
643     return 1;   758     return 1;
644   }   759   }
645   numberpatches = ic2_ReadModel(argv[1], &firstpatchptr);   760   numberpatches = ic2_ReadModel(argv[1], &firstpatchptr);
646   if (numberpatches < 0) {   761   if (numberpatches < 0) {
647     printf("Error: invalid model \"%s\", reading failed.\n", argv[1]);   762     printf("Error: invalid model \"%s\", reading failed.\n", argv[1]);
648     return 1;   763     return 1;
649   }   764   }
650   printf("Number of Patches in the model = %d \n", numberpatches);   765   printf("Number of Patches in the model = %d \n", numberpatches);
651   766
652   // glutライブラリによる引数の解釈   767   // glutライブラリによる引数の解釈
653   glutInit(&argc, argv);   768   glutInit(&argc, argv);
654   769
655   // OpenGL Window の初期化   770   // OpenGL Window の初期化
656   ic2_BootWindow(argv[0]);   771   ic2_BootWindow(argv[0]);
657   772
658   // 無限ループの開始   773   // 無限ループの開始
659   glutMainLoop();   774   glutMainLoop();
660      775   
661   return 0;   776   return 0;
662 }   777 }

Generated by kameda[at]iit.tsukuba.ac.jp