Modified lines:  5, 6
Added line:  14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50
Removed line:  53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89
Generated by diff2html.pl
© Yves Bailly, MandrakeSoft S.A. 2001, Ryohei Morita 2007
diff2html.pl is licensed under the GNU GPL.

  ../111-1/111-1-Perspective.c     112-0-Structures.c
  662 lines
24764 bytes
Last modified : Mon Nov 21 05:34:28 2011

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

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