Modified lines:  6
Added line:  69, 70, 71, 113, 114, 115, 116, 117, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 443, 817, 818, 819, 820, 821, 822
Removed line:  623, 624, 625
Generated by diff2html.pl
© Yves Bailly, MandrakeSoft S.A. 2001, Ryohei Morita 2007
diff2html.pl is licensed under the GNU GPL.

  ../112-2/112-2-Replay.c     112-3-AnimationFile.c
  820 lines
29999 bytes
Last modified : Mon Nov 21 17:55:25 2011

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

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