Modified lines:  6, 415, 434
Added line:  28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 48, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 479, 480, 481, 482, 581, 582
Removed line:  601
Generated by diff2html.pl
© Yves Bailly, MandrakeSoft S.A. 2001, Ryohei Morita 2007
diff2html.pl is licensed under the GNU GPL.

  ../110-6/110-6-MoveLight.c     111-1-Perspective.c
  613 lines
22499 bytes
Last modified : Sun Nov 13 17:59:49 2011

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

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