(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 #include <time.h>\r
14 \r
15 #include "bitmap.h"\r
16 #include "globals.h"\r
17 #include "helper.h"\r
18 #include "types.h"\r
19 #include "scene.h"\r
20 \r
21 \r
22 /**\r
23  * Event hander for main menu events\r
24  * @param id ID of menu item selected\r
25  */\r
26 void processMainEvents(int id) {\r
27   switch (id) {\r
28     case M_ROTATE_MOVE_CAMERA:\r
29       // Do stuff\r
30       break;\r
31 \r
32     case M_POSITION_SCALE:\r
33       // Do stuff\r
34       break;\r
35 \r
36     case M_ROTATION_TEXTURE_SCALE:\r
37       // Do stuff\r
38       break;\r
39 \r
40     case M_EXIT:\r
41       exit(EXIT_SUCCESS);\r
42 \r
43   }\r
44 }\r
45 \r
46 /**\r
47  * Event hander for materials menu events\r
48  * @param id ID of menu item selected\r
49  */\r
50 void processMaterialEvents(int id) {\r
51   switch (id) {\r
52     case M_MATERIAL_ALL_RGB:\r
53       // Do stuff\r
54       break;\r
55 \r
56     case M_MATERIAL_AMBIENT_RGB:\r
57       // Do stuff\r
58       break;\r
59 \r
60     case M_MATERIAL_DIFFUSE_RGB:\r
61       // Do stuff\r
62       break;\r
63 \r
64     case M_MATERIAL_SPECULAR_RGB:\r
65       // Do stuff\r
66       break;\r
67 \r
68     case M_MATERIAL_ALL_ADSS:\r
69       // Do stuff\r
70       break;\r
71 \r
72     case M_MATERIAL_RED_ADSS:\r
73       // Do stuff\r
74       break;\r
75 \r
76     case M_MATERIAL_GREEN_ADSS:\r
77       // Do stuff\r
78       break;\r
79 \r
80     case M_MATERIAL_BLUE_ADSS:\r
81       // Do stuff\r
82       break;\r
83 \r
84   }\r
85 }\r
86 \r
87 /**\r
88  * Event hander for light menu events\r
89  * @param id ID of menu item selected\r
90  */\r
91 void processLightEvents(int id) {\r
92   switch (id) {\r
93     case M_LIGHT_MOVE_LIGHT_1:\r
94       // Do stuff\r
95       break;\r
96 \r
97     case M_LIGHT_RGBALL_LIGHT_1:\r
98       // Do stuff\r
99       break;\r
100 \r
101     case M_LIGHT_MOVE_LIGHT_2:\r
102       // Do stuff\r
103       break;\r
104 \r
105     case M_LIGHT_RGBALL_LIGHT_2:\r
106       // Do stuff\r
107       break;\r
108 \r
109   }\r
110 }\r
111 \r
112 /**\r
113  * Event hander for object menu events\r
114  * @param id ID of object selected\r
115  */\r
116 void processObjectEvents(int id) {\r
117 \r
118 }\r
119 \r
120 /**\r
121  * Event hander for texture menu events\r
122  * @param id ID of texutre selected\r
123  */\r
124 void processTextureEvents(int id) {\r
125 \r
126 }\r
127 \r
128 /**\r
129  * Event hander for ground texture menu events\r
130  * @param id ID of ground texture selected\r
131  */\r
132 void processGTextureEvents(int id) {\r
133 \r
134 }\r
135 \r
136 /**\r
137  * Creates menu for program\r
138  */\r
139 void makeMenu() {\r
140   // Construct material menu\r
141   int materialMenu = glutCreateMenu(processMaterialEvents);\r
142   glutAddMenuEntry("All R/G/B", M_MATERIAL_ALL_RGB);\r
143   glutAddMenuEntry("Ambient R/G/B", M_MATERIAL_AMBIENT_RGB);\r
144   glutAddMenuEntry("Diffuse R/G/B", M_MATERIAL_DIFFUSE_RGB);\r
145   glutAddMenuEntry("Specular R/G/B", M_MATERIAL_SPECULAR_RGB);\r
146   glutAddMenuEntry("All Amb/Diff/Spec/Shine", M_MATERIAL_ALL_ADSS);\r
147   glutAddMenuEntry("Red Amb/Diff/Spec/Shine", M_MATERIAL_RED_ADSS);\r
148   glutAddMenuEntry("Green Amb/Diff/Spec/Shine", M_MATERIAL_GREEN_ADSS);\r
149   glutAddMenuEntry("Blue Amb/Diff/Spec/Shine", M_MATERIAL_BLUE_ADSS);\r
150 \r
151   // Construct light menu\r
152   int lightMenu = glutCreateMenu(processLightEvents);\r
153   glutAddMenuEntry("Move Light 1", M_LIGHT_MOVE_LIGHT_1);\r
154   glutAddMenuEntry("R/G/B/All Light 1", M_LIGHT_RGBALL_LIGHT_1);\r
155   glutAddMenuEntry("Move Light 2", M_LIGHT_MOVE_LIGHT_2);\r
156   glutAddMenuEntry("R/G/B/All Light 2", M_LIGHT_RGBALL_LIGHT_2);\r
157 \r
158   // Construct object menu\r
159   int objectMenu = makeSubmenuFromArray( objectMenuEntries, NMESH, processObjectEvents );\r
160 \r
161   // Construct texture / ground texture menus\r
162   int textureMenu = makeSubmenuFromArray( textureMenuEntries, NTEXTURE, processTextureEvents );\r
163   int gTextureMenu = makeSubmenuFromArray( textureMenuEntries, NTEXTURE, processGTextureEvents );\r
164 \r
165   // Construct main menu\r
166   glutCreateMenu(processMainEvents);\r
167   //glutAddMenuEntry("Rotate/Move Camera", M_ROTATE_MOVE_CAMERA);\r
168   //glutAddSubMenu("Add object", objectMenu);\r
169   //glutAddMenuEntry("Position/Scale", M_POSITION_SCALE);\r
170   //glutAddMenuEntry("Rotation/Texture Scale", M_ROTATION_TEXTURE_SCALE);\r
171   //glutAddSubMenu("Material", materialMenu);\r
172   //glutAddSubMenu("Texture", textureMenu);\r
173   //glutAddSubMenu("Ground texture", gTextureMenu);\r
174   //glutAddSubMenu("Lights", lightMenu);\r
175   glutAddMenuEntry("Exit", M_EXIT);\r
176 \r
177   // Bind to right mouse button\r
178   glutAttachMenu(GLUT_RIGHT_BUTTON);\r
179 }\r
180 \r
181 /**\r
182  * Called when window is resized\r
183  * @param w New width\r
184  * @param h New height\r
185  */\r
186 void windowReshape(int w, int h) {\r
187   glViewport(0, 0, (GLsizei) w, (GLsizei) h);\r
188   glMatrixMode(GL_PROJECTION);\r
189   glLoadIdentity();\r
190   if (w <= h) \r
191     glOrtho(near, far, near*(GLfloat)h/(GLfloat)w,\r
192              far*(GLfloat)h/(GLfloat)w, near, far);\r
193   else\r
194     glOrtho(near*(GLfloat)w/(GLfloat)h,\r
195              far*(GLfloat)w/(GLfloat)h, near, far, near, far);\r
196    glMatrixMode(GL_MODELVIEW); \r
197    glLoadIdentity();\r
198 }\r
199 \r
200 /**\r
201  * Called when mouse event occurs\r
202  * @param btn Mouse button\r
203  * @param state State of mouse button\r
204  * @param x Mouse x position\r
205  * @param y Mouse y position\r
206  */\r
207 void mouse(int button, int state, int x, int y) {\r
208   if (button == GLUT_LEFT_BUTTON) {\r
209     if (state == GLUT_DOWN) {\r
210       moving = 1;\r
211       startx = x;\r
212       starty = y;\r
213     }\r
214     if (state == GLUT_UP) {\r
215       moving = 0;\r
216     }\r
217   }\r
218   if (button == GLUT_MIDDLE_BUTTON) {\r
219     if (state == GLUT_DOWN) {\r
220       lightMoving = 1;\r
221       lightStartX = x;\r
222       lightStartY = y;\r
223     }\r
224     if (state == GLUT_UP) {\r
225       lightMoving = 0;\r
226     }\r
227   }\r
228 }\r
229 \r
230 /**\r
231  * Called when motion event occurs\r
232  * @param x Mouse x position\r
233  * @param y Mouse y position\r
234  */\r
235 void motion(int x, int y) {\r
236   if (moving) {\r
237     angle = angle + (x - startx);\r
238     angle2 = angle2 + (y - starty);\r
239     startx = x;\r
240     starty = y;\r
241     glutPostRedisplay();\r
242   }\r
243   if (lightMoving) {\r
244     lightAngle += (x - lightStartX)/40.0;\r
245     lightHeight += (lightStartY - y)/20.0;\r
246     lightStartX = x;\r
247     lightStartY = y;\r
248     glutPostRedisplay();\r
249   }\r
250 }\r
251 \r
252 /**\r
253  * Display function\r
254  */\r
255 void display() {\r
256   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\r
257   glLoadIdentity();\r
258   gluLookAt(\r
259     0.0, 0.0, 10.0,  /* eye is at (x,y,z) */\r
260     0.0, 0.0,  0.0,  /* center is at (x,y,z) */\r
261     0.0, 1.0,  0.0   /* up is in postivie Y direction */\r
262     );\r
263 \r
264 \r
265   // **NOTE: Currently this rotation function is all that moves the camera off\r
266   //         the flat surface. Need to integrate function into gluLookAt\r
267   glRotatef(30.0, 1.0, 0.0, 0.0);\r
268 \r
269   /* Reposition the light source. */\r
270   lightPosition[0] = 12*cos(lightAngle);\r
271   lightPosition[1] = lightHeight;\r
272   lightPosition[2] = 12*sin(lightAngle);\r
273   lightPosition[3] = 0.0;\r
274 \r
275   glPushMatrix();\r
276 \r
277     /* Perform scene rotations based on user mouse input. */\r
278     glRotatef(angle, 0.0, 1.0, 0.0);\r
279     //glRotatef(angle2, 1.0, 0.0, 0.0); **NOTE: Only one degree of freedom\r
280 \r
281     glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);\r
282 \r
283     drawFloor();\r
284 \r
285     drawLine();\r
286     \r
287     // Draw teapot for a test object\r
288     glPushMatrix();\r
289       glTranslatef(0.0, 0.5, 0.0); // **NOTE: Teapot does not rest on surface\r
290       glColor3f(0.5, 0.5, 0.5);\r
291       glutSolidTeapot(1);\r
292     glPopMatrix();\r
293 \r
294     // Draw a white ball over the light source\r
295     glPushMatrix();\r
296       glDisable(GL_LIGHTING);\r
297       glColor3f(1.0, 1.0, 1.0);\r
298       glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);\r
299       glutSolidSphere(1.0, 50, 50);\r
300       glEnable(GL_LIGHTING);\r
301     glPopMatrix();\r
302 \r
303   glPopMatrix();\r
304 \r
305   glutSwapBuffers();\r
306 }\r
307 \r
308 /**\r
309  * init function; sets initial OpenGL state\r
310  */\r
311 void init() {\r
312   glMatrixMode(GL_PROJECTION);\r
313   glLoadIdentity();\r
314 \r
315   gluPerspective(\r
316     60.0,  /* field of view in degree */\r
317      1.0,  /* aspect ratio */\r
318     near,  /* Z near */\r
319      far   /* Z far */\r
320     );\r
321 \r
322   \r
323   glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);\r
324   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);\r
325   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);\r
326   glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);\r
327   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, glightmodel);\r
328   glEnable(GL_LIGHT0);\r
329   glEnable(GL_LIGHTING);\r
330   glEnable(GL_COLOR_MATERIAL);\r
331   glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );\r
332   glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular0);\r
333   glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emission0);\r
334 \r
335   \r
336 \r
337   glMatrixMode(GL_MODELVIEW);\r
338   glLoadIdentity();\r
339 }\r
340 \r
341 /**\r
342  * Main function\r
343  * @param argc Number of arguments\r
344  * @param argv Array of arguments\r
345  * @return Program exit code\r
346  */\r
347 int main(int argc, char **argv) {\r
348   if(argc>1)\r
349     strcpy(dataDir, argv[1]);\r
350   else if(opendir(dirDefault1))\r
351     strcpy(dataDir, dirDefault1);\r
352   else if(opendir(dirDefault2))\r
353     strcpy(dataDir, dirDefault2);\r
354   else fileErr(dirDefault1);\r
355 \r
356   for(int i=0; i<NMESH; i++) meshes[i]=NULL;\r
357   for(int i=0; i<NTEXTURE; i++) textures[i]=NULL;\r
358 \r
359   glutInit(&argc, argv);\r
360 \r
361   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);\r
362 \r
363   glutInitWindowSize(500, 500);\r
364   glutCreateWindow("Scene Editor");\r
365 \r
366   glShadeModel(GL_SMOOTH); // Enables Smooth Shading\r
367   glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background\r
368   glClearDepth(1.0f); // Depth Buffer Setup\r
369   glEnable(GL_DEPTH_TEST); // Enables Depth Testing\r
370   glDepthFunc(GL_LEQUAL);  // the type\r
371   glEnable(GL_CULL_FACE);\r
372   glEnable(GL_TEXTURE_2D);\r
373   glLineWidth(1.0);\r
374 \r
375   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);\r
376 \r
377   glutReshapeFunc(windowReshape);\r
378   glutDisplayFunc(display);\r
379   glutMouseFunc(mouse);\r
380   glutMotionFunc(motion);\r
381 \r
382   makeMenu();\r
383 \r
384   init();\r
385 \r
386   glutMainLoop();\r
387 }\r

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