Modified lines:  5, 6
Added line:  33, 34, 35, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 379
Removed line:  464
Generated by diff2html.pl
© Yves Bailly, MandrakeSoft S.A. 2001, Ryohei Morita 2007
diff2html.pl is licensed under the GNU GPL.

  ../110-2/110-2-TogglePredefined.c     110-3-ModelShow.c
  489 lines
18111 bytes
Last modified : Sun Nov 13 17:49:22 2011

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

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