(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 /**\r
113  * Prints out error message when file cannot be read\r
114  * @param fileName Name of file that could not be read\r
115  */\r
116 void fileErr(char* fileName) {\r
117     printf("Error reading file: %s\n", fileName);\r
118     printf("If not in the CSSE labs, you will need to include the directory containing\n");\r
119     printf("the models on the command line, or put it in the same folder as the exectutable.");\r
120     exit(EXIT_FAILURE);\r
121 }  \r
122 \r
123 /**\r
124  * Reads .bmp texture files and converts them to a texture object\r
125  * @param fileName .bmp texture file\r
126  * @return texture object\r
127  */\r
128 texture* loadTexture(char *fileName) {\r
129     texture* t = malloc(sizeof (texture));\r
130     BITMAPINFO *info;\r
131 \r
132     t->rgbData = LoadDIBitmap(fileName, &info);\r
133     t->height=info->bmiHeader.biHeight;\r
134     t->width=info->bmiHeader.biWidth;\r
135 \r
136     return t;\r
137 }\r
138 \r
139 /**\r
140  * Reads .x files and converts them to a mesh object\r
141  * @param fileName .x mesh file\r
142  * @return mesh object\r
143  */\r
144 mesh* loadMesh(char* fileName) {\r
145     mesh* m = malloc(sizeof (mesh));\r
146     FILE* fp = fopen(fileName, "r");\r
147     char line[256] = "";\r
148     int lineBuffSize = 256;\r
149 \r
150     if(fp == NULL) fileErr(fileName);\r
151 \r
152     while(strcmp(line,"Mesh {\r\n") != 0 && strcmp(line,"Mesh {\n") != 0 )\r
153         fgets(line, lineBuffSize, fp);\r
154 \r
155     fscanf(fp, "%d;\n", &(m->nVertices));\r
156     m->vertices = malloc(m->nVertices * sizeof(vertex));\r
157     for(int i=0; i < m->nVertices; i++)\r
158         fscanf(fp, "%f; %f; %f;%*[,;]\n", &(m->vertices[i][0]), &(m->vertices[i][1]), &(m->vertices[i][2]) );\r
159 \r
160     fscanf(fp, "%d;\n", &(m->nTriangles));\r
161     m->triangles = malloc(m->nTriangles * sizeof(triangle));\r
162     for(int i=0; i < m->nTriangles; i++)\r
163         fscanf(fp, "%*d; %d, %d, %d;%*[;,]", m->triangles[i], m->triangles[i]+1, m->triangles[i]+2);\r
164 \r
165     while(strcmp(line,"  MeshNormals {\r\n") != 0 && strcmp(line,"  MeshNormals {\n") != 0)\r
166         fgets(line, lineBuffSize, fp);\r
167 \r
168     fgets(line, lineBuffSize, fp);\r
169     m->normals = malloc(m->nVertices * sizeof(normal));\r
170     for(int i=0; i < m->nVertices; i++)\r
171         fscanf(fp, "%f; %f; %f;%*[;,]\n",\r
172                &(m->normals[i][0]), &(m->normals[i][1]), &(m->normals[i][2]));\r
173 \r
174     while(strcmp(line,"MeshTextureCoords {\r\n") != 0 && strcmp(line,"MeshTextureCoords {\n") != 0)\r
175         fgets(line, lineBuffSize, fp);\r
176 \r
177     fgets(line, lineBuffSize, fp);\r
178     m->texCoords = malloc(m->nVertices * sizeof(texCoord));\r
179     for(int i=0; i < m->nVertices; i++)\r
180         fscanf(fp, "%f;%f;%*[,;]\n", &(m->texCoords[i][0]), &(m->texCoords[i][1]) );\r
181     fclose(fp);\r
182     \r
183     return m;\r
184 }\r
185 \r
186 // [You may want to add to this function.]\r
187 /**\r
188  * Loads mesh[i] if it isn't already loaded.\r
189  * You must call getMesh(i) at least once before using mesh[i].\r
190  *\r
191  * @param i Mesh ID\r
192  */\r
193 void getMesh(int i) { // getMesh(i) loads mesh[i] if it isn't already loaded.  \r
194     char fileName[220];\r
195     if(i>=NMESH || i<0) {\r
196         printf("Error in getMesh - wrong model number");\r
197         exit(1);\r
198     }\r
199     if(meshes[i] != NULL)\r
200         return;\r
201     sprintf(fileName, "%s/model%d.x", dataDir, i+1);\r
202     meshes[i] = loadMesh(fileName);\r
203 }\r
204 \r
205 /**\r
206  * Loads texture i if it isn't already loaded\r
207  *\r
208  * After calling getTexture(i), you can make texture i the current texture using\r
209  *      glBindTexture(GL_TEXTURE_2D, i);\r
210  * Use i=0 to return to the default plain texture.\r
211  *\r
212  * You can then scale the texture via:\r
213  *      glMatrixMode(GL_TEXTURE);\r
214  * See the textbook, section 8.8.3.\r
215  *\r
216  * You must call getTexture(i) at least once before using texture i.\r
217  * @param i Texture ID\r
218  */\r
219 void getTexture(int i) {\r
220     char fileName[220];\r
221     if(i<1 || i>NTEXTURE) {\r
222         printf("Error in getTexture - wrong texture number");\r
223         exit(1);\r
224     }\r
225     if(textures[i-1] != NULL)\r
226         return;\r
227     sprintf(fileName, "%s/texture%d.bmp", dataDir, i);\r
228 \r
229     textures[i-1] = loadTexture(fileName);\r
230 \r
231     glBindTexture(GL_TEXTURE_2D, i);\r
232 \r
233     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textures[i-1]->width, textures[i-1]->height,\r
234                  0, GL_RGB, GL_UNSIGNED_BYTE, textures[i-1]->rgbData);\r
235     gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, textures[i-1]->width, textures[i-1]->height, GL_RGB, \r
236                       GL_UNSIGNED_BYTE, textures[i-1]->rgbData);\r
237     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);\r
238     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);\r
239     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
240     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);\r
241 \r
242     glBindTexture(GL_TEXTURE_2D, 0);  // Back to default texture\r
243 }\r
244 \r
245 /**\r
246  * Event hander for main menu events\r
247  * @param id ID of menu item selected\r
248  */\r
249 void processMainEvents(int id) {\r
250   switch (id) {\r
251     case ROTATE_MOVE_CAMERA:\r
252       // Do stuff\r
253       break;\r
254 \r
255     case POSITION_SCALE:\r
256       // Do stuff\r
257       break;\r
258 \r
259     case ROTATION_TEXTURE_SCALE:\r
260       // Do stuff\r
261       break;\r
262 \r
263     case EXIT:\r
264       exit(EXIT_SUCCESS);\r
265 \r
266   }\r
267 }\r
268 \r
269 /**\r
270  * Event hander for materials menu events\r
271  * @param id ID of menu item selected\r
272  */\r
273 void processMaterialEvents(int id) {\r
274   switch (id) {\r
275     case MATERIAL_ALL_RGB:\r
276       // Do stuff\r
277       break;\r
278 \r
279     case MATERIAL_AMBIENT_RGB:\r
280       // Do stuff\r
281       break;\r
282 \r
283     case MATERIAL_DIFFUSE_RGB:\r
284       // Do stuff\r
285       break;\r
286 \r
287     case MATERIAL_SPECULAR_RGB:\r
288       // Do stuff\r
289       break;\r
290 \r
291     case MATERIAL_ALL_ADSS:\r
292       // Do stuff\r
293       break;\r
294 \r
295     case MATERIAL_RED_ADSS:\r
296       // Do stuff\r
297       break;\r
298 \r
299     case MATERIAL_GREEN_ADSS:\r
300       // Do stuff\r
301       break;\r
302 \r
303     case MATERIAL_BLUE_ADSS:\r
304       // Do stuff\r
305       break;\r
306 \r
307   }\r
308 }\r
309 \r
310 /**\r
311  * Event hander for light menu events\r
312  * @param id ID of menu item selected\r
313  */\r
314 void processLightEvents(int id) {\r
315   switch (id) {\r
316     case LIGHT_MOVE_LIGHT_1:\r
317       // Do stuff\r
318       break;\r
319 \r
320     case LIGHT_RGBALL_LIGHT_1:\r
321       // Do stuff\r
322       break;\r
323 \r
324     case LIGHT_MOVE_LIGHT_2:\r
325       // Do stuff\r
326       break;\r
327 \r
328     case LIGHT_RGBALL_LIGHT_2:\r
329       // Do stuff\r
330       break;\r
331 \r
332   }\r
333 }\r
334 \r
335 /**\r
336  * Event hander for object menu events\r
337  * @param id ID of object selected\r
338  */\r
339 void processObjectEvents(int id) {\r
340 \r
341 }\r
342 \r
343 /**\r
344  * Event hander for texture menu events\r
345  * @param id ID of texutre selected\r
346  */\r
347 void processTextureEvents(int id) {\r
348 \r
349 }\r
350 \r
351 /**\r
352  * Event hander for ground texture menu events\r
353  * @param id ID of ground texture selected\r
354  */\r
355 void processGTextureEvents(int id) {\r
356 \r
357 }\r
358 \r
359 /**\r
360  * Rounds up numbers, from http://stackoverflow.com/questions/3407012/c-rounding-up-to-the-nearest-multiple-of-a-number\r
361  * @param numToRound Number to round\r
362  * @param multiple Multiple to round up to\r
363  * @return Rounded number\r
364  */\r
365 int roundUp(int numToRound, int multiple) {\r
366   if(multiple == 0) {\r
367     return numToRound;\r
368   }\r
369 \r
370   int remainder = numToRound % multiple;\r
371   if (remainder == 0)\r
372     return numToRound;\r
373   return numToRound + multiple - remainder;\r
374 }\r
375 \r
376 /**\r
377  * Makes a submenu from an array of items, splitting the list into subsubmenus\r
378  * of only 10 items.\r
379  * @param menuEntries Array of menu items\r
380  * @param menuEntriesSize Size of menuEntries\r
381  * @param callback Callback function for this array of menu items\r
382  * @return Reference to menu created\r
383  */\r
384 int makeSubmenuFromArray( const char *menuEntries[], unsigned int menuEntriesSize, void *callback ) {\r
385   if ( menuEntriesSize == 0 ) return -1;\r
386 \r
387   int menuNumber = roundUp(menuEntriesSize, 10) / 10;\r
388   int submenuObjects[menuNumber-1];\r
389 \r
390   for( int i = 0; i < menuNumber; i++ ) {\r
391     submenuObjects[i] = glutCreateMenu(callback);\r
392     int startNum = i*11 - (i-1);\r
393     for ( int j = startNum - 1; j < (startNum+9); j++ ) {\r
394       if ( j == menuEntriesSize ) break; // Detect if we've reached the end of the array\r
395       glutAddMenuEntry( menuEntries[j], j + 1 );\r
396     }\r
397   } \r
398 \r
399   int mainMenu = glutCreateMenu(callback);\r
400   for ( int i = 0; i < menuNumber; i++ ) {\r
401     char name[10]; // buffer to hold name\r
402     int startNum = i*11 - (i-1);\r
403     int endNum = startNum + 9;\r
404     if ( i == menuNumber - 1 ) { // We're on the last one\r
405       endNum = startNum + (menuEntriesSize - startNum); // Work out final number\r
406     }\r
407     sprintf(name, "%d-%d", startNum, endNum);\r
408     glutAddSubMenu( name, submenuObjects[i] );\r
409   }\r
410 \r
411   return mainMenu;\r
412 }\r
413 \r
414 /**\r
415  * Creates menu for program\r
416  */\r
417 void makeMenu() {\r
418   // Construct material menu\r
419   int materialMenu = glutCreateMenu(processMaterialEvents);\r
420   glutAddMenuEntry("All R/G/B", MATERIAL_ALL_RGB);\r
421   glutAddMenuEntry("Ambient R/G/B", MATERIAL_AMBIENT_RGB);\r
422   glutAddMenuEntry("Diffuse R/G/B", MATERIAL_DIFFUSE_RGB);\r
423   glutAddMenuEntry("Specular R/G/B", MATERIAL_SPECULAR_RGB);\r
424   glutAddMenuEntry("All Amb/Diff/Spec/Shine", MATERIAL_ALL_ADSS);\r
425   glutAddMenuEntry("Red Amb/Diff/Spec/Shine", MATERIAL_RED_ADSS);\r
426   glutAddMenuEntry("Green Amb/Diff/Spec/Shine", MATERIAL_GREEN_ADSS);\r
427   glutAddMenuEntry("Blue Amb/Diff/Spec/Shine", MATERIAL_BLUE_ADSS);\r
428 \r
429   // Construct light menu\r
430   int lightMenu = glutCreateMenu(processLightEvents);\r
431   glutAddMenuEntry("Move Light 1", LIGHT_MOVE_LIGHT_1);\r
432   glutAddMenuEntry("R/G/B/All Light 1", LIGHT_RGBALL_LIGHT_1);\r
433   glutAddMenuEntry("Move Light 2", LIGHT_MOVE_LIGHT_2);\r
434   glutAddMenuEntry("R/G/B/All Light 2", LIGHT_RGBALL_LIGHT_2);\r
435 \r
436   // Construct object menu\r
437   int objectMenuEntriesSize = sizeof(objectMenuEntries) / sizeof(objectMenuEntries[0]);\r
438   int objectMenu = makeSubmenuFromArray( objectMenuEntries, objectMenuEntriesSize, processObjectEvents );\r
439 \r
440   // Construct texture / ground texture menus\r
441   int textureMenuEntriesSize = sizeof(textureMenuEntries) / sizeof(textureMenuEntries[0]);\r
442   int textureMenu = makeSubmenuFromArray( textureMenuEntries, textureMenuEntriesSize, processTextureEvents );\r
443   int gTextureMenu = makeSubmenuFromArray( textureMenuEntries, textureMenuEntriesSize, processGTextureEvents );\r
444 \r
445   // Construct main menu\r
446   glutCreateMenu(processMainEvents);\r
447   //glutAddMenuEntry("Rotate/Move Camera", ROTATE_MOVE_CAMERA);\r
448   //glutAddSubMenu("Add object", objectMenu);\r
449   //glutAddMenuEntry("Position/Scale", POSITION_SCALE);\r
450   //glutAddMenuEntry("Rotation/Texture Scale", ROTATION_TEXTURE_SCALE);\r
451   //glutAddSubMenu("Material", materialMenu);\r
452   //glutAddSubMenu("Texture", textureMenu);\r
453   //glutAddSubMenu("Ground texture", gTextureMenu);\r
454   //glutAddSubMenu("Lights", lightMenu);\r
455   glutAddMenuEntry("Exit", EXIT);\r
456 \r
457   // Bind to right mouse button\r
458   glutAttachMenu(GLUT_RIGHT_BUTTON);\r
459 }\r
460 \r
461 /**\r
462  * Called when window is resized\r
463  * @param w New width\r
464  * @param h New height\r
465  */\r
466 void windowReshape(int w, int h) {\r
467   GLdouble near = -10.0;\r
468   GLdouble far = 10.0;\r
469 \r
470   glViewport(0, 0, (GLsizei) w, (GLsizei) h);\r
471   glMatrixMode(GL_PROJECTION);\r
472   glLoadIdentity();\r
473   if (w <= h) \r
474     glOrtho(near, far, near*(GLfloat)h/(GLfloat)w,\r
475              far*(GLfloat)h/(GLfloat)w, near, far);\r
476   else\r
477     glOrtho(near*(GLfloat)w/(GLfloat)h,\r
478              far*(GLfloat)w/(GLfloat)h, near, far, near, far);\r
479    glMatrixMode(GL_MODELVIEW); \r
480    glLoadIdentity();\r
481 }\r
482 \r
483 /**\r
484  * Called when mouse event occurs\r
485  * @param btn Mouse button\r
486  * @param state State of mouse button\r
487  * @param x Mouse x position\r
488  * @param y Mouse y position\r
489  */\r
490 void mouse(int btn, int state, int x, int y) {\r
491   \r
492 }\r
493 \r
494 /**\r
495  * Display function\r
496  */\r
497 void display() {\r
498    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
499    glLoadIdentity();\r
500 \r
501    glTranslatef( 0.0f,  0.0f,  0.0f);\r
502    glBegin(GL_QUADS);\r
503      glVertex3f( 0.0f,  1.0f, -1.0f);\r
504      glVertex3f( 0.0f,  1.0f,  1.0f);\r
505      glVertex3f( 0.0f, -1.0f,  1.0f);\r
506      glVertex3f( 0.0f, -1.0f, -1.0f);\r
507    glEnd();\r
508 \r
509 \r
510    glTranslatef( 0.0f, 0.0f, -5.0f); // Move into the Screen 10.0\r
511    glutSolidTeapot(1);\r
512 \r
513 glMatrixMode(GL_PROJECTION);\r
514   glLoadIdentity();\r
515    gluLookAt(0.7f, 0.4f, 0.9f, -2.0f, -1.0f, -7.0f, 1.0f, 10.0f, 1.0f);\r
516 \r
517    glMatrixMode(GL_MODELVIEW);\r
518    glLoadIdentity();\r
519    glutSwapBuffers();\r
520 }\r
521 \r
522 /**\r
523  * Main function\r
524  * @param argc Number of arguments\r
525  * @param argv Array of arguments\r
526  * @return Program exit code\r
527  */\r
528 int main(int argc, char **argv) {\r
529 \r
530     if(argc>1)\r
531           strcpy(dataDir, argv[1]);\r
532     else if(opendir(dirDefault1))\r
533           strcpy(dataDir, dirDefault1);\r
534     else if(opendir(dirDefault2))\r
535       strcpy(dataDir, dirDefault2);\r
536     else fileErr(dirDefault1);\r
537 \r
538     for(int i=0; i<NMESH; i++) meshes[i]=NULL;\r
539     for(int i=0; i<NTEXTURE; i++) textures[i]=NULL;\r
540 \r
541     glutInit(&argc, argv);\r
542 \r
543     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);\r
544     glutInitWindowSize(500, 500);\r
545     glutCreateWindow("Scene Editor");\r
546 \r
547     glShadeModel(GL_SMOOTH); // Enables Smooth Shading\r
548     glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background\r
549     glClearDepth(1.0f); // Depth Buffer Setup\r
550     glEnable(GL_DEPTH_TEST); // Enables Depth Testing\r
551     glDepthFunc(GL_LEQUAL);  // the type\r
552 \r
553     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);          // Really Nice Perspective Calculations\r
554 \r
555     glutReshapeFunc(windowReshape);\r
556     glutDisplayFunc(display);\r
557     glutMouseFunc(mouse);\r
558 \r
559     makeMenu();\r
560 \r
561     glMatrixMode(GL_PROJECTION);\r
562     glLoadIdentity();\r
563     gluPerspective( 60, 1, 0.1, 1000.0);\r
564     glMatrixMode(GL_MODELVIEW);\r
565 \r
566     glutMainLoop();\r
567 }\r

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