Modified lines:  6, 189
Added line:  66, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 133, 134, 135, 216, 217, 307, 308, 309, 536
Removed line:  None
Generated by diff2html.pl
© Yves Bailly, MandrakeSoft S.A. 2001, Ryohei Morita 2007
diff2html.pl is licensed under the GNU GPL.

  ../110-3/110-3-ModelShow.c     110-4-NormalVector.c
  520 lines
19149 bytes
Last modified : Sun Nov 13 17:46:11 2011

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

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