(no commit message)
[atyndall/cits2231.git] / scene.c
1 /**\r
2  * CITS2231 Graphics Scene Editor\r
3  * @author Ashley Tyndall (20915779)\r
4  */\r
5 \r
6 #include <stdlib.h>\r
7 #include <stdio.h>\r
8 #include <dirent.h>\r
9 #include <string.h>\r
10 #include <math.h>\r
11 #include <GL/gl.h>\r
12 #include <GL/glut.h>\r
13 \r
14 #include "bitmap.h"\r
15 \r
16 // Type definitions for vertex-coordinates, normals, texture-coordinates, \r
17 // and triangles (via the indices of 3 vertices).\r
18 typedef GLfloat vertex[3];\r
19 typedef GLfloat normal[3];\r
20 typedef GLfloat texCoord[2];\r
21 typedef GLint vertexIndex;\r
22 typedef vertexIndex triangle[3];\r
23 \r
24 // A type for a mesh\r
25 typedef struct {         \r
26     int nVertices;           //  The number of vertices in the mesh\r
27     vertex* vertices;        //  Array with coordinates of vertices\r
28     normal* normals;         //  Array with normals of vertices\r
29     texCoord* texCoords;     //  Array with texture-coordinates of vertices\r
30     int nTriangles;          //  The number of triangles in the mesh\r
31     triangle* triangles;     //  Array of trangles via 3 indices into "vertices"\r
32 } mesh;\r
33 \r
34 #define NMESH 54       // The number of meshes (in the models-textures dir)\r
35 mesh* meshes[NMESH];   // An array of pointers to the meshes - see getMesh\r
36 \r
37 // A type for a 2D texture, with height and width in pixels\r
38 typedef struct {\r
39     int height;\r
40     int width;\r
41     GLubyte *rgbData;   // Array of bytes with the colour data for the texture\r
42 } texture;\r
43 \r
44 #define NTEXTURE 30     // The number of textures (in the models-textures dir)\r
45 texture* textures[NTEXTURE];   // An array of texture pointers - see getTexture\r
46 \r
47 typedef struct {  \r
48     // You'll need to add scale, rotation, material, mesh number, etc.,\r
49     // to this structure\r
50     float x,y,z;\r
51 } SceneObject;\r
52 \r
53 // Menu enum\r
54 enum menu {\r
55   // Main menu\r
56   ROTATE_MOVE_CAMERA,\r
57   POSITION_SCALE,\r
58   ROTATION_TEXTURE_SCALE,\r
59   EXIT,\r
60 \r
61   // Material submenu\r
62   MATERIAL_ALL_RGB,\r
63   MATERIAL_AMBIENT_RGB,\r
64   MATERIAL_DIFFUSE_RGB,\r
65   MATERIAL_SPECULAR_RGB,\r
66   MATERIAL_ALL_ADSS,\r
67   MATERIAL_RED_ADSS,\r
68   MATERIAL_GREEN_ADSS,\r
69   MATERIAL_BLUE_ADSS,\r
70 \r
71   // Light submenu\r
72   LIGHT_MOVE_LIGHT_1,\r
73   LIGHT_RGBALL_LIGHT_1,\r
74   LIGHT_MOVE_LIGHT_2,\r
75   LIGHT_RGBALL_LIGHT_2\r
76 };\r
77 \r
78 // Menu arrays\r
79 const char *textureMenuEntries[NTEXTURE] = {\r
80   "1 Plain", "2 Rust", "3 Concrete", "4 Carpet", "5 Beach Sand",\r
81   "6 Rocky", "7 Brick", "8 Water", "9 Paper", "10 Marble",\r
82   "11 Wood", "12 Scales", "13 Fur", "14 Denim", "15 Hessian",\r
83   "16 Orange Peel", "17 Ice Crystals", "18 Grass", "19 Corrugated Iron", "20 Styrofoam",\r
84   "21 Bubble Wrap", "22 Leather", "23 Camouflage", "24 Asphalt", "25 Scratched Ice",\r
85   "26 Rattan", "27 Snow", "28 Dry Mud", "29 Old Concrete", "30 Leopard Skin"\r
86 };\r
87 \r
88 const char *objectMenuEntries[NMESH] = {\r
89   "1 Thin Dinosaur","2 Big Dog","3 Saddle Dinosaur", "4 Dragon", "5 Cleopatra",\r
90   "6 Bone I", "7 Bone II", "8 Rabbit", "9 Long Dragon", "10 Buddha",\r
91   "11 Sitting Rabbit", "12 Frog", "13 Cow", "14 Monster", "15 Sea Horse",\r
92   "16 Head", "17 Pelican", "18 Horse", "19 Kneeling Angel", "20 Porsche I",\r
93   "21 Truck", "22 Statue of Liberty", "23 Sitting Angel", "24 Metal Part", "25 Car",\r
94   "26 Apatosaurus", "27 Airliner", "28 Motorbike", "29 Dolphin", "30 Spaceman",\r
95   "31 Winnie the Pooh", "32 Shark", "33 Crocodile", "34 Toddler", "35 Fat Dinosaur",\r
96   "36 Chihuahua", "37 Sabre-toothed Tiger", "38 Lioness", "39 Fish", "40 Horse (head down)",\r
97   "41 Horse (head up)", "42 Skull", "43 Fighter Jet I", "44 Toad", "45 Convertible",\r
98   "46 Porsche II", "47 Hare", "48 Vintage Car", "49 Fighter Jet II", "50 Winged Monkey",\r
99   "51 Chef", "52 Parasaurolophus", "53 Rooster", "54 T-rex"\r
100 };\r
101 \r
102 #define MAXOBJECTS 256\r
103 SceneObject sceneObjs[MAXOBJECTS];  // An array with details of the objects in a scene\r
104 int nObjects=0;                     // How many objects there are in the scene currently.\r
105 \r
106 // Directories containing models\r
107 char *dirDefault1 = "models-textures";\r
108 char *dirDefault2 = "/cslinux/examples/CITS2231/project-files/models-textures";\r
109 \r
110 char dataDir[200];  // Stores the directory name for the meshes and textures.\r
111 \r
112 static GLfloat floorVertices[4][3] = {\r
113   { -1000.0, 0.0, 1000.0 },\r
114   { 1000.0, 0.0, 1000.0 },\r
115   { 1000.0, 0.0, -1000.0 },\r
116   { -1000.0, 0.0, -1000.0 },\r
117 };\r
118 \r
119 static GLfloat lightColor[] = {1.0, 1.0, 1.0, 1.0}; // White light\r
120 static GLfloat lightPosition[4];\r
121 \r
122 int moving, startx, starty;\r
123 int lightMoving = 0, lightStartX, lightStartY;\r
124 \r
125 /* Time varying or user-controled variables. */\r
126 static float jump = 0.0;\r
127 static float lightAngle = 0.0, lightHeight = 20;\r
128 GLfloat angle = -150;   /* in degrees */\r
129 GLfloat angle2 = 30;   /* in degrees */\r
130 \r
131 /**\r
132  * Prints out error message when file cannot be read\r
133  * @param fileName Name of file that could not be read\r
134  */\r
135 void fileErr(char* fileName) {\r
136     printf("Error reading file: %s\n", fileName);\r
137     printf("If not in the CSSE labs, you will need to include the directory containing\n");\r
138     printf("the models on the command line, or put it in the same folder as the exectutable.");\r
139     exit(EXIT_FAILURE);\r
140 }  \r
141 \r
142 /**\r
143  * Reads .bmp texture files and converts them to a texture object\r
144  * @param fileName .bmp texture file\r
145  * @return texture object\r
146  */\r
147 texture* loadTexture(char *fileName) {\r
148     texture* t = malloc(sizeof (texture));\r
149     BITMAPINFO *info;\r
150 \r
151     t->rgbData = LoadDIBitmap(fileName, &info);\r
152     t->height=info->bmiHeader.biHeight;\r
153     t->width=info->bmiHeader.biWidth;\r
154 \r
155     return t;\r
156 }\r
157 \r
158 /**\r
159  * Reads .x files and converts them to a mesh object\r
160  * @param fileName .x mesh file\r
161  * @return mesh object\r
162  */\r
163 mesh* loadMesh(char* fileName) {\r
164     mesh* m = malloc(sizeof (mesh));\r
165     FILE* fp = fopen(fileName, "r");\r
166     char line[256] = "";\r
167     int lineBuffSize = 256;\r
168 \r
169     if(fp == NULL) fileErr(fileName);\r
170 \r
171     while(strcmp(line,"Mesh {\r\n") != 0 && strcmp(line,"Mesh {\n") != 0 )\r
172         fgets(line, lineBuffSize, fp);\r
173 \r
174     fscanf(fp, "%d;\n", &(m->nVertices));\r
175     m->vertices = malloc(m->nVertices * sizeof(vertex));\r
176     for(int i=0; i < m->nVertices; i++)\r
177         fscanf(fp, "%f; %f; %f;%*[,;]\n", &(m->vertices[i][0]), &(m->vertices[i][1]), &(m->vertices[i][2]) );\r
178 \r
179     fscanf(fp, "%d;\n", &(m->nTriangles));\r
180     m->triangles = malloc(m->nTriangles * sizeof(triangle));\r
181     for(int i=0; i < m->nTriangles; i++)\r
182         fscanf(fp, "%*d; %d, %d, %d;%*[;,]", m->triangles[i], m->triangles[i]+1, m->triangles[i]+2);\r
183 \r
184     while(strcmp(line,"  MeshNormals {\r\n") != 0 && strcmp(line,"  MeshNormals {\n") != 0)\r
185         fgets(line, lineBuffSize, fp);\r
186 \r
187     fgets(line, lineBuffSize, fp);\r
188     m->normals = malloc(m->nVertices * sizeof(normal));\r
189     for(int i=0; i < m->nVertices; i++)\r
190         fscanf(fp, "%f; %f; %f;%*[;,]\n",\r
191                &(m->normals[i][0]), &(m->normals[i][1]), &(m->normals[i][2]));\r
192 \r
193     while(strcmp(line,"MeshTextureCoords {\r\n") != 0 && strcmp(line,"MeshTextureCoords {\n") != 0)\r
194         fgets(line, lineBuffSize, fp);\r
195 \r
196     fgets(line, lineBuffSize, fp);\r
197     m->texCoords = malloc(m->nVertices * sizeof(texCoord));\r
198     for(int i=0; i < m->nVertices; i++)\r
199         fscanf(fp, "%f;%f;%*[,;]\n", &(m->texCoords[i][0]), &(m->texCoords[i][1]) );\r
200     fclose(fp);\r
201     \r
202     return m;\r
203 }\r
204 \r
205 // [You may want to add to this function.]\r
206 /**\r
207  * Loads mesh[i] if it isn't already loaded.\r
208  * You must call getMesh(i) at least once before using mesh[i].\r
209  *\r
210  * @param i Mesh ID\r
211  */\r
212 void getMesh(int i) { // getMesh(i) loads mesh[i] if it isn't already loaded.  \r
213     char fileName[220];\r
214     if(i>=NMESH || i<0) {\r
215         printf("Error in getMesh - wrong model number");\r
216         exit(1);\r
217     }\r
218     if(meshes[i] != NULL)\r
219         return;\r
220     sprintf(fileName, "%s/model%d.x", dataDir, i+1);\r
221     meshes[i] = loadMesh(fileName);\r
222 }\r
223 \r
224 /**\r
225  * Loads texture i if it isn't already loaded\r
226  *\r
227  * After calling getTexture(i), you can make texture i the current texture using\r
228  *      glBindTexture(GL_TEXTURE_2D, i);\r
229  * Use i=0 to return to the default plain texture.\r
230  *\r
231  * You can then scale the texture via:\r
232  *      glMatrixMode(GL_TEXTURE);\r
233  * See the textbook, section 8.8.3.\r
234  *\r
235  * You must call getTexture(i) at least once before using texture i.\r
236  * @param i Texture ID\r
237  */\r
238 void getTexture(int i) {\r
239     char fileName[220];\r
240     if(i<1 || i>NTEXTURE) {\r
241         printf("Error in getTexture - wrong texture number");\r
242         exit(1);\r
243     }\r
244     if(textures[i-1] != NULL)\r
245         return;\r
246     sprintf(fileName, "%s/texture%d.bmp", dataDir, i);\r
247 \r
248     textures[i-1] = loadTexture(fileName);\r
249 \r
250     glBindTexture(GL_TEXTURE_2D, i);\r
251 \r
252     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textures[i-1]->width, textures[i-1]->height,\r
253                  0, GL_RGB, GL_UNSIGNED_BYTE, textures[i-1]->rgbData);\r
254     gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, textures[i-1]->width, textures[i-1]->height, GL_RGB, \r
255                       GL_UNSIGNED_BYTE, textures[i-1]->rgbData);\r
256     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
257     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
258     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
259     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);\r
260 \r
261     glBindTexture(GL_TEXTURE_2D, 0);  // Back to default texture\r
262 }\r
263 \r
264 /**\r
265  * Event hander for main menu events\r
266  * @param id ID of menu item selected\r
267  */\r
268 void processMainEvents(int id) {\r
269   switch (id) {\r
270     case ROTATE_MOVE_CAMERA:\r
271       // Do stuff\r
272       break;\r
273 \r
274     case POSITION_SCALE:\r
275       // Do stuff\r
276       break;\r
277 \r
278     case ROTATION_TEXTURE_SCALE:\r
279       // Do stuff\r
280       break;\r
281 \r
282     case EXIT:\r
283       exit(EXIT_SUCCESS);\r
284 \r
285   }\r
286 }\r
287 \r
288 /**\r
289  * Event hander for materials menu events\r
290  * @param id ID of menu item selected\r
291  */\r
292 void processMaterialEvents(int id) {\r
293   switch (id) {\r
294     case MATERIAL_ALL_RGB:\r
295       // Do stuff\r
296       break;\r
297 \r
298     case MATERIAL_AMBIENT_RGB:\r
299       // Do stuff\r
300       break;\r
301 \r
302     case MATERIAL_DIFFUSE_RGB:\r
303       // Do stuff\r
304       break;\r
305 \r
306     case MATERIAL_SPECULAR_RGB:\r
307       // Do stuff\r
308       break;\r
309 \r
310     case MATERIAL_ALL_ADSS:\r
311       // Do stuff\r
312       break;\r
313 \r
314     case MATERIAL_RED_ADSS:\r
315       // Do stuff\r
316       break;\r
317 \r
318     case MATERIAL_GREEN_ADSS:\r
319       // Do stuff\r
320       break;\r
321 \r
322     case MATERIAL_BLUE_ADSS:\r
323       // Do stuff\r
324       break;\r
325 \r
326   }\r
327 }\r
328 \r
329 /**\r
330  * Event hander for light menu events\r
331  * @param id ID of menu item selected\r
332  */\r
333 void processLightEvents(int id) {\r
334   switch (id) {\r
335     case LIGHT_MOVE_LIGHT_1:\r
336       // Do stuff\r
337       break;\r
338 \r
339     case LIGHT_RGBALL_LIGHT_1:\r
340       // Do stuff\r
341       break;\r
342 \r
343     case LIGHT_MOVE_LIGHT_2:\r
344       // Do stuff\r
345       break;\r
346 \r
347     case LIGHT_RGBALL_LIGHT_2:\r
348       // Do stuff\r
349       break;\r
350 \r
351   }\r
352 }\r
353 \r
354 /**\r
355  * Event hander for object menu events\r
356  * @param id ID of object selected\r
357  */\r
358 void processObjectEvents(int id) {\r
359 \r
360 }\r
361 \r
362 /**\r
363  * Event hander for texture menu events\r
364  * @param id ID of texutre selected\r
365  */\r
366 void processTextureEvents(int id) {\r
367 \r
368 }\r
369 \r
370 /**\r
371  * Event hander for ground texture menu events\r
372  * @param id ID of ground texture selected\r
373  */\r
374 void processGTextureEvents(int id) {\r
375 \r
376 }\r
377 \r
378 /**\r
379  * Rounds up numbers, from http://stackoverflow.com/questions/3407012/c-rounding-up-to-the-nearest-multiple-of-a-number\r
380  * @param numToRound Number to round\r
381  * @param multiple Multiple to round up to\r
382  * @return Rounded number\r
383  */\r
384 int roundUp(int numToRound, int multiple) {\r
385   if(multiple == 0) {\r
386     return numToRound;\r
387   }\r
388 \r
389   int remainder = numToRound % multiple;\r
390   if (remainder == 0)\r
391     return numToRound;\r
392   return numToRound + multiple - remainder;\r
393 }\r
394 \r
395 /**\r
396  * Makes a submenu from an array of items, splitting the list into subsubmenus\r
397  * of only 10 items.\r
398  * @param menuEntries Array of menu items\r
399  * @param menuEntriesSize Size of menuEntries\r
400  * @param callback Callback function for this array of menu items\r
401  * @return Reference to menu created\r
402  */\r
403 int makeSubmenuFromArray( const char *menuEntries[], unsigned int menuEntriesSize, void *callback ) {\r
404   if ( menuEntriesSize == 0 ) return -1;\r
405 \r
406   int menuNumber = roundUp(menuEntriesSize, 10) / 10;\r
407   int submenuObjects[menuNumber-1];\r
408 \r
409   for( int i = 0; i < menuNumber; i++ ) {\r
410     submenuObjects[i] = glutCreateMenu(callback);\r
411     int startNum = i*11 - (i-1);\r
412     for ( int j = startNum - 1; j < (startNum+9); j++ ) {\r
413       if ( j == menuEntriesSize ) break; // Detect if we've reached the end of the array\r
414       glutAddMenuEntry( menuEntries[j], j + 1 );\r
415     }\r
416   } \r
417 \r
418   int mainMenu = glutCreateMenu(callback);\r
419   for ( int i = 0; i < menuNumber; i++ ) {\r
420     char name[10]; // buffer to hold name\r
421     int startNum = i*11 - (i-1);\r
422     int endNum = startNum + 9;\r
423     if ( i == menuNumber - 1 ) { // We're on the last one\r
424       endNum = startNum + (menuEntriesSize - startNum); // Work out final number\r
425     }\r
426     sprintf(name, "%d-%d", startNum, endNum);\r
427     glutAddSubMenu( name, submenuObjects[i] );\r
428   }\r
429 \r
430   return mainMenu;\r
431 }\r
432 \r
433 /**\r
434  * Creates menu for program\r
435  */\r
436 void makeMenu() {\r
437   // Construct material menu\r
438   int materialMenu = glutCreateMenu(processMaterialEvents);\r
439   glutAddMenuEntry("All R/G/B", MATERIAL_ALL_RGB);\r
440   glutAddMenuEntry("Ambient R/G/B", MATERIAL_AMBIENT_RGB);\r
441   glutAddMenuEntry("Diffuse R/G/B", MATERIAL_DIFFUSE_RGB);\r
442   glutAddMenuEntry("Specular R/G/B", MATERIAL_SPECULAR_RGB);\r
443   glutAddMenuEntry("All Amb/Diff/Spec/Shine", MATERIAL_ALL_ADSS);\r
444   glutAddMenuEntry("Red Amb/Diff/Spec/Shine", MATERIAL_RED_ADSS);\r
445   glutAddMenuEntry("Green Amb/Diff/Spec/Shine", MATERIAL_GREEN_ADSS);\r
446   glutAddMenuEntry("Blue Amb/Diff/Spec/Shine", MATERIAL_BLUE_ADSS);\r
447 \r
448   // Construct light menu\r
449   int lightMenu = glutCreateMenu(processLightEvents);\r
450   glutAddMenuEntry("Move Light 1", LIGHT_MOVE_LIGHT_1);\r
451   glutAddMenuEntry("R/G/B/All Light 1", LIGHT_RGBALL_LIGHT_1);\r
452   glutAddMenuEntry("Move Light 2", LIGHT_MOVE_LIGHT_2);\r
453   glutAddMenuEntry("R/G/B/All Light 2", LIGHT_RGBALL_LIGHT_2);\r
454 \r
455   // Construct object menu\r
456   int objectMenuEntriesSize = sizeof(objectMenuEntries) / sizeof(objectMenuEntries[0]);\r
457   int objectMenu = makeSubmenuFromArray( objectMenuEntries, objectMenuEntriesSize, processObjectEvents );\r
458 \r
459   // Construct texture / ground texture menus\r
460   int textureMenuEntriesSize = sizeof(textureMenuEntries) / sizeof(textureMenuEntries[0]);\r
461   int textureMenu = makeSubmenuFromArray( textureMenuEntries, textureMenuEntriesSize, processTextureEvents );\r
462   int gTextureMenu = makeSubmenuFromArray( textureMenuEntries, textureMenuEntriesSize, processGTextureEvents );\r
463 \r
464   // Construct main menu\r
465   glutCreateMenu(processMainEvents);\r
466   //glutAddMenuEntry("Rotate/Move Camera", ROTATE_MOVE_CAMERA);\r
467   //glutAddSubMenu("Add object", objectMenu);\r
468   //glutAddMenuEntry("Position/Scale", POSITION_SCALE);\r
469   //glutAddMenuEntry("Rotation/Texture Scale", ROTATION_TEXTURE_SCALE);\r
470   //glutAddSubMenu("Material", materialMenu);\r
471   //glutAddSubMenu("Texture", textureMenu);\r
472   //glutAddSubMenu("Ground texture", gTextureMenu);\r
473   //glutAddSubMenu("Lights", lightMenu);\r
474   glutAddMenuEntry("Exit", EXIT);\r
475 \r
476   // Bind to right mouse button\r
477   glutAttachMenu(GLUT_RIGHT_BUTTON);\r
478 }\r
479 \r
480 /**\r
481  * Called when window is resized\r
482  * @param w New width\r
483  * @param h New height\r
484  */\r
485 void windowReshape(int w, int h) {\r
486   GLdouble near = -10.0;\r
487   GLdouble far = 10.0;\r
488 \r
489   glViewport(0, 0, (GLsizei) w, (GLsizei) h);\r
490   glMatrixMode(GL_PROJECTION);\r
491   glLoadIdentity();\r
492   if (w <= h) \r
493     glOrtho(near, far, near*(GLfloat)h/(GLfloat)w,\r
494              far*(GLfloat)h/(GLfloat)w, near, far);\r
495   else\r
496     glOrtho(near*(GLfloat)w/(GLfloat)h,\r
497              far*(GLfloat)w/(GLfloat)h, near, far, near, far);\r
498    glMatrixMode(GL_MODELVIEW); \r
499    glLoadIdentity();\r
500 }\r
501 \r
502 /**\r
503  * Called when mouse event occurs\r
504  * @param btn Mouse button\r
505  * @param state State of mouse button\r
506  * @param x Mouse x position\r
507  * @param y Mouse y position\r
508  */\r
509 /*void mouse(int btn, int state, int x, int y) {\r
510   \r
511 }*//*\r
512 static void\r
513 mouse(int button, int state, int x, int y)\r
514 {\r
515   if (button == GLUT_LEFT_BUTTON) {\r
516     if (state == GLUT_DOWN) {\r
517       moving = 1;\r
518       startx = x;\r
519       starty = y;\r
520     }\r
521     if (state == GLUT_UP) {\r
522       moving = 0;\r
523     }\r
524   }\r
525   if (button == GLUT_MIDDLE_BUTTON) {\r
526     if (state == GLUT_DOWN) {\r
527       lightMoving = 1;\r
528       lightStartX = x;\r
529       lightStartY = y;\r
530     }\r
531     if (state == GLUT_UP) {\r
532       lightMoving = 0;\r
533     }\r
534   }\r
535 }\r
536 \r
537 static void\r
538 motion(int x, int y)\r
539 {\r
540   if (moving) {\r
541     angle = angle + (x - startx);\r
542     angle2 = angle2 + (y - starty);\r
543     startx = x;\r
544     starty = y;\r
545     glutPostRedisplay();\r
546   }\r
547   if (lightMoving) {\r
548     lightAngle += (x - lightStartX)/40.0;\r
549     lightHeight += (lightStartY - y)/20.0;\r
550     lightStartX = x;\r
551     lightStartY = y;\r
552     glutPostRedisplay();\r
553   }\r
554 }*/\r
555 \r
556 void idle() {\r
557   angle = (int)(angle + 10) % 360;\r
558     angle2 = (int)(angle2 + 10) % 360;\r
559     glutPostRedisplay();\r
560 }\r
561 \r
562 /**\r
563  * Draw a floor.\r
564  */\r
565 void drawFloor() {\r
566   glDisable(GL_LIGHTING);\r
567 \r
568   //if (useTexture) {\r
569   //  glEnable(GL_TEXTURE_2D);\r
570   //}\r
571 \r
572   /*glBegin(GL_QUADS);\r
573     glTexCoord2f(0.0, 0.0);\r
574     glVertex3fv(floorVertices[0]);\r
575     glTexCoord2f(0.0, 16.0);\r
576     glVertex3fv(floorVertices[1]);\r
577     glTexCoord2f(16.0, 16.0);\r
578     glVertex3fv(floorVertices[2]);\r
579     glTexCoord2f(16.0, 0.0);\r
580     glVertex3fv(floorVertices[3]);\r
581   glEnd();*/\r
582 \r
583   /*if (useTexture) {\r
584     glDisable(GL_TEXTURE_2D);\r
585   }*/\r
586 \r
587   glEnable(GL_LIGHTING);\r
588 }\r
589 \r
590 /**\r
591  * Display function\r
592  */\r
593 void display() {\r
594   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
595   glLoadIdentity();\r
596   gluLookAt(\r
597     0.0, 0.0, 60.0,  /* eye is at (x,y,z) */\r
598     0.0, 0.0,  0.0,  /* center is at (x,y,z) */\r
599     0.0, 1.0,  0.0   /* up is in postivie Y direction */\r
600     );\r
601 \r
602   /* Reposition the light source. */\r
603   lightPosition[0] = 12*cos(lightAngle);\r
604   lightPosition[1] = lightHeight;\r
605   lightPosition[2] = 12*sin(lightAngle);\r
606   lightPosition[3] = 0.0;\r
607 \r
608   glPushMatrix();\r
609       /* Perform scene rotations based on user mouse input. */\r
610     glRotatef(angle2, 1.0, 0.0, 0.0);\r
611     glRotatef(angle, 0.0, 1.0, 0.0);\r
612 \r
613     glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);\r
614 \r
615     glEnable(GL_BLEND);\r
616     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
617     drawFloor();\r
618     glDisable(GL_BLEND);\r
619 \r
620     glPushMatrix();\r
621     \r
622       glTranslatef(0.0, 0.0, 0.0);\r
623       glutWireTeapot(30); // Draw teapot for test\r
624     glPopMatrix();\r
625 \r
626     glPushMatrix();\r
627       glDisable(GL_LIGHTING);\r
628       glColor3f(1.0, 1.0, 1.0);\r
629 \r
630       /* Draw a yellow ball at the light source. */\r
631       glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);\r
632       glutSolidSphere(1.0, 5, 5);\r
633 \r
634       glEnable(GL_LIGHTING);\r
635     glPopMatrix();\r
636 \r
637   glPopMatrix();\r
638 \r
639   glutSwapBuffers();\r
640 }\r
641 \r
642 /**\r
643  * init function; sets initial OpenGL state\r
644  */\r
645 void init() {\r
646   glMatrixMode(GL_PROJECTION);\r
647   glLoadIdentity();\r
648 \r
649   gluPerspective(\r
650      60.0,  /* field of view in degree */\r
651       1.0,  /* aspect ratio */ \r
652       0.0,  /* Z near */\r
653     900.0   /* Z far */\r
654     );    \r
655 \r
656   glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);\r
657   glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);\r
658   glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);\r
659   glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);\r
660   glEnable(GL_LIGHT0);\r
661   glEnable(GL_LIGHTING);\r
662 \r
663   glMatrixMode(GL_MODELVIEW);\r
664   glLoadIdentity();\r
665 }\r
666 \r
667 /**\r
668  * Main function\r
669  * @param argc Number of arguments\r
670  * @param argv Array of arguments\r
671  * @return Program exit code\r
672  */\r
673 int main(int argc, char **argv) {\r
674   if(argc>1)\r
675     strcpy(dataDir, argv[1]);\r
676   else if(opendir(dirDefault1))\r
677     strcpy(dataDir, dirDefault1);\r
678   else if(opendir(dirDefault2))\r
679     strcpy(dataDir, dirDefault2);\r
680   else fileErr(dirDefault1);\r
681 \r
682   for(int i=0; i<NMESH; i++) meshes[i]=NULL;\r
683   for(int i=0; i<NTEXTURE; i++) textures[i]=NULL;\r
684 \r
685   glutInit(&argc, argv);\r
686 \r
687   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);\r
688 \r
689   glutInitWindowSize(500, 500);\r
690   glutCreateWindow("Scene Editor");\r
691 \r
692   glShadeModel(GL_SMOOTH); // Enables Smooth Shading\r
693   glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background\r
694   glClearDepth(1.0f); // Depth Buffer Setup\r
695   glEnable(GL_DEPTH_TEST); // Enables Depth Testing\r
696   glDepthFunc(GL_LEQUAL);  // the type\r
697   glEnable(GL_CULL_FACE);\r
698   glEnable(GL_TEXTURE_2D);\r
699   glLineWidth(1.0);\r
700 \r
701   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);\r
702 \r
703   glutReshapeFunc(windowReshape);\r
704   glutDisplayFunc(display);\r
705   //glutMouseFunc(mouse);\r
706   //glutMotionFunc(motion);\r
707   glutIdleFunc(idle);\r
708 \r
709   makeMenu();\r
710 \r
711   init();\r
712 \r
713   glutMainLoop();\r
714 }\r

UCC git Repository :: git.ucc.asn.au