2 * CITS2231 Graphics Scene Editor
\r
3 * @author Ashley Tyndall (20915779)
\r
12 #include <GL/glut.h>
\r
16 #include "globals.h"
\r
22 * Event hander for main menu events
\r
23 * @param id ID of menu item selected
\r
25 void processMainEvents(int id) {
\r
27 case M_ROTATE_MOVE_CAMERA:
\r
28 manipulateState = STATE_CAMERA_ROTATE_MOVE;
\r
30 case M_POSITION_SCALE:
\r
31 manipulateState = STATE_OBJECT_POSITION_SCALE;
\r
33 case M_ROTATION_TEXTURE_SCALE:
\r
34 manipulateState = STATE_OBJECT_ROTATION_TEXTURE_SCALE;
\r
43 * Event hander for materials menu events
\r
44 * @param id ID of menu item selected
\r
46 void processMaterialEvents(int id) {
\r
48 case M_MATERIAL_ALL_RGB:
\r
52 case M_MATERIAL_AMBIENT_RGB:
\r
56 case M_MATERIAL_DIFFUSE_RGB:
\r
60 case M_MATERIAL_SPECULAR_RGB:
\r
64 case M_MATERIAL_ALL_ADSS:
\r
68 case M_MATERIAL_RED_ADSS:
\r
72 case M_MATERIAL_GREEN_ADSS:
\r
76 case M_MATERIAL_BLUE_ADSS:
\r
84 * Event hander for light menu events
\r
85 * @param id ID of menu item selected
\r
87 void processLightEvents(int id) {
\r
89 case M_LIGHT_MOVE_LIGHT_1:
\r
93 case M_LIGHT_RGBALL_LIGHT_1:
\r
97 case M_LIGHT_MOVE_LIGHT_2:
\r
101 case M_LIGHT_RGBALL_LIGHT_2:
\r
109 * Event hander for object menu events
\r
110 * @param id ID of object selected
\r
112 void processObjectEvents(int id) {
\r
113 addSceneObject(id);
\r
114 glutPostRedisplay();
\r
118 * Event hander for texture menu events
\r
119 * @param id ID of texutre selected
\r
121 void processTextureEvents(int id) {
\r
122 if ( curObject >= 0 ) {
\r
123 sceneObjs[curObject].texture = id;
\r
124 glutPostRedisplay();
\r
129 * Event hander for ground texture menu events
\r
130 * @param id ID of ground texture selected
\r
132 void processGTextureEvents(int id) {
\r
133 currentGroundTexture = id;
\r
134 glutPostRedisplay();
\r
138 * Creates menu for program
\r
141 // Construct material menu
\r
142 int materialMenu = glutCreateMenu(processMaterialEvents);
\r
143 glutAddMenuEntry("All R/G/B", M_MATERIAL_ALL_RGB);
\r
144 glutAddMenuEntry("Ambient R/G/B", M_MATERIAL_AMBIENT_RGB);
\r
145 glutAddMenuEntry("Diffuse R/G/B", M_MATERIAL_DIFFUSE_RGB);
\r
146 glutAddMenuEntry("Specular R/G/B", M_MATERIAL_SPECULAR_RGB);
\r
147 glutAddMenuEntry("All Amb/Diff/Spec/Shine", M_MATERIAL_ALL_ADSS);
\r
148 glutAddMenuEntry("Red Amb/Diff/Spec/Shine", M_MATERIAL_RED_ADSS);
\r
149 glutAddMenuEntry("Green Amb/Diff/Spec/Shine", M_MATERIAL_GREEN_ADSS);
\r
150 glutAddMenuEntry("Blue Amb/Diff/Spec/Shine", M_MATERIAL_BLUE_ADSS);
\r
152 // Construct light menu
\r
153 int lightMenu = glutCreateMenu(processLightEvents);
\r
154 glutAddMenuEntry("Move Light 1", M_LIGHT_MOVE_LIGHT_1);
\r
155 glutAddMenuEntry("R/G/B/All Light 1", M_LIGHT_RGBALL_LIGHT_1);
\r
156 glutAddMenuEntry("Move Light 2", M_LIGHT_MOVE_LIGHT_2);
\r
157 glutAddMenuEntry("R/G/B/All Light 2", M_LIGHT_RGBALL_LIGHT_2);
\r
159 // Construct object menu
\r
160 int objectMenu = makeSubmenuFromArray( objectMenuEntries, NMESH, processObjectEvents );
\r
162 // Construct texture / ground texture menus
\r
163 int textureMenu = makeSubmenuFromArray( textureMenuEntries, NTEXTURE, processTextureEvents );
\r
164 int gTextureMenu = makeSubmenuFromArray( textureMenuEntries, NTEXTURE, processGTextureEvents );
\r
166 // Construct main menu
\r
167 glutCreateMenu(processMainEvents);
\r
168 glutAddMenuEntry("Rotate/Move Camera", M_ROTATE_MOVE_CAMERA);
\r
169 glutAddSubMenu("Add object", objectMenu);
\r
170 glutAddMenuEntry("Position/Scale", M_POSITION_SCALE);
\r
171 glutAddMenuEntry("Rotation/Texture Scale", M_ROTATION_TEXTURE_SCALE);
\r
172 //glutAddSubMenu("Material", materialMenu);
\r
173 glutAddSubMenu("Texture", textureMenu);
\r
174 glutAddSubMenu("Ground texture", gTextureMenu);
\r
175 //glutAddSubMenu("Lights", lightMenu);
\r
176 glutAddMenuEntry("Exit", M_EXIT);
\r
178 // Bind to right mouse button
\r
179 glutAttachMenu(GLUT_RIGHT_BUTTON);
\r
183 * Called when window is resized
\r
184 * @param w New width
\r
185 * @param h New height
\r
187 void windowReshape(int w, int h) {
\r
188 glViewport(0, 0, (GLsizei) w, (GLsizei) h);
\r
194 * Called when mouse event occurs
\r
195 * @param btn Mouse button
\r
196 * @param state State of mouse button
\r
197 * @param x Mouse x position
\r
198 * @param y Mouse y position
\r
200 void mouse(int button, int state, int x, int y) {
\r
202 case GLUT_LEFT_BUTTON:
\r
203 case GLUT_MIDDLE_BUTTON:
\r
204 if ( state == GLUT_DOWN ) {
\r
205 buttonSelected = button;
\r
206 } else if ( state == GLUT_UP ) {
\r
207 buttonSelected = -1;
\r
216 * Keybord event handler
\r
217 * w/s increase/decrease the z
\r
218 * a/d increase/decrease the x
\r
219 * q/e increase/decrease the y
\r
220 * z/x increase/decrease the angle
\r
221 * @param key Key pressed
\r
222 * @param x x co-ordinate of mouse
\r
223 * @param y y co-ordinate of mouse
\r
225 void keyboard(unsigned char key, int x, int y) {
\r
262 printf("Factor of change is now %f\n", factor);
\r
267 printf("Factor of change is now %f\n", factor);
\r
271 printf("Camera is now at (%f, %f, %f), angle %f\n", camx, camy, camz, keyrot);
\r
272 glutPostRedisplay();
\r
276 * Called when motion event occurs
\r
277 * @param x Mouse x position
\r
278 * @param y Mouse y position
\r
280 void motion(int x, int y) {
\r
281 if ( buttonSelected == -1 ) return; // No button selected, no action
\r
283 switch ( manipulateState ) {
\r
284 case STATE_CAMERA_ROTATE_MOVE:
\r
285 rotate += (x - startx);
\r
287 if ( buttonSelected == GLUT_LEFT_BUTTON ) {
\r
288 // w: rotate, h: zoom
\r
289 zoom += (y - starty);
\r
290 } else if ( buttonSelected == GLUT_MIDDLE_BUTTON ) {
\r
291 // w: rotate, h: tilt
\r
292 camAngle += (y - starty);
\r
300 case STATE_OBJECT_POSITION_SCALE:
\r
301 //SceneObject co = sceneObjs[curObject];
\r
303 if ( buttonSelected == GLUT_LEFT_BUTTON ) {
\r
304 // w: left/right, h: near/far
\r
306 } else if ( buttonSelected == GLUT_MIDDLE_BUTTON ) {
\r
307 // w: big/small, h: up/down
\r
311 case STATE_OBJECT_ROTATION_TEXTURE_SCALE:
\r
312 if ( buttonSelected == GLUT_LEFT_BUTTON ) {
\r
313 // w: rotate on width, h: rotate on h
\r
314 } else if ( buttonSelected == GLUT_MIDDLE_BUTTON ) {
\r
315 // w & h, rotate on h
\r
321 glutPostRedisplay();
\r
328 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
\r
330 // Redraw projection matrix
\r
331 glMatrixMode(GL_PROJECTION);
\r
335 if ( width <= height ) {
\r
336 aspect = (float)height / (float)width;
\r
338 aspect = (float)width / (float)height;
\r
348 glMatrixMode(GL_MODELVIEW);
\r
352 0.0, 0.0, 15.0 + (zoom*zoomFactor), /* eye is at (x,y,z) */
\r
353 0.0, 0.0, 0.0, /* center is at (x,y,z) */
\r
354 0.0, 10.0, 0.0 /* up is in postivie Y direction */
\r
357 glRotatef(camAngle*camAngleFactor, 1.0, 0.0, 0.0);
\r
359 /* Reposition the light source 0. */
\r
360 lightPosition0[0] = 12*cos(lightAngle0);
\r
361 lightPosition0[1] = lightHeight0;
\r
362 lightPosition0[2] = 12*sin(lightAngle0);
\r
363 lightPosition0[3] = 0.0;
\r
365 direction0[0] = lightPosition0[0];
\r
366 direction0[2] = lightPosition0[2];
\r
368 /* Reposition the light source 1. */
\r
369 lightPosition1[0] = 12*cos(lightAngle1);
\r
370 lightPosition1[1] = lightHeight1;
\r
371 lightPosition1[2] = 12*sin(lightAngle1);
\r
372 lightPosition1[3] = 0.0;
\r
374 direction1[0] = lightPosition1[0];
\r
375 direction1[2] = lightPosition1[2];
\r
379 /* Perform scene rotations based on user mouse/keyboard input. */
\r
380 glRotatef(rotate*rotateFactor, 0.0, 1.0, 0.0);
\r
381 glTranslatef(camx, camy, camz);
\r
382 glRotatef(keyrot, 1.0, 0.0, 0.0);
\r
384 glLightfv(GL_LIGHT0, GL_POSITION, lightPosition0);
\r
385 glLightfv(GL_LIGHT1, GL_POSITION, lightPosition1);
\r
389 // Draw sceneObjs array
\r
390 for ( int i = 0; i < nObjects; i++ ) {
\r
392 SceneObject so = sceneObjs[i];
\r
394 // Apply rotation vector
\r
395 glRotatef(so.rotation.amount, so.rotation.vector[0], so.rotation.vector[1], so.rotation.vector[2]);
\r
397 // Apply scaling vector
\r
398 glScalef(so.scale[0], so.scale[1], so.scale[2]);
\r
400 // Apply translation vector
\r
401 glTranslatef(so.x, so.y, so.z);
\r
404 if ( so.texture > 0 ) {
\r
405 getTexture(so.texture);
\r
406 glBindTexture(GL_TEXTURE_2D, so.texture);
\r
408 glBindTexture(GL_TEXTURE_2D, 0);
\r
411 // Draw actual object
\r
412 if ( so.mesh > 0 ) {
\r
414 } else if ( so.mesh == -1 ) { // a mesh of -1 draws the teapot
\r
415 // The teapot does not obey the right-hand rule
\r
416 glFrontFace(GL_CW);
\r
417 glutSolidTeapot(1);
\r
418 glFrontFace(GL_CCW);
\r
421 glBindTexture(GL_TEXTURE_2D, 0);
\r
426 // Draw a white ball over the light source
\r
428 glDisable(GL_LIGHTING);
\r
429 glColor3f(1.0, 1.0, 1.0);
\r
430 glTranslatef(lightPosition0[0], lightPosition0[1], lightPosition0[2]);
\r
431 glutSolidSphere(0.5, 50, 50);
\r
432 glEnable(GL_LIGHTING);
\r
435 // Draw a white ball over the light source
\r
437 glDisable(GL_LIGHTING);
\r
438 glColor3f(1.0, 1.0, 1.0);
\r
439 glTranslatef(lightPosition1[0], lightPosition1[1], lightPosition1[2]);
\r
440 glutSolidSphere(0.5, 50, 50);
\r
441 glEnable(GL_LIGHTING);
\r
452 * init function; sets initial OpenGL state
\r
455 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);
\r
456 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);
\r
457 glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);
\r
458 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction0);
\r
460 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
\r
461 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
\r
462 glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
\r
463 glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction1);
\r
465 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, glightmodel);
\r
466 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
\r
468 glEnable(GL_LIGHT0);
\r
469 glEnable(GL_LIGHT1);
\r
470 glEnable(GL_LIGHTING);
\r
475 * @param argc Number of arguments
\r
476 * @param argv Array of arguments
\r
477 * @return Program exit code
\r
479 int main(int argc, char **argv) {
\r
481 strcpy(dataDir, argv[1]);
\r
482 else if(opendir(dirDefault1))
\r
483 strcpy(dataDir, dirDefault1);
\r
484 else if(opendir(dirDefault2))
\r
485 strcpy(dataDir, dirDefault2);
\r
486 else fileErr(dirDefault1);
\r
488 for(int i=0; i<NMESH; i++) meshes[i]=NULL;
\r
489 for(int i=0; i<NTEXTURE; i++) textures[i]=NULL;
\r
491 glutInit(&argc, argv);
\r
493 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
\r
495 glutInitWindowSize(500, 500);
\r
496 glutCreateWindow("Scene Editor");
\r
498 glShadeModel(GL_SMOOTH); // Enables Smooth Shading
\r
499 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
\r
500 glClearDepth(1.0f); // Depth Buffer Setup
\r
502 glEnable(GL_DEPTH_TEST); // Enables Depth Testing
\r
503 glDepthFunc(GL_LEQUAL); // the type
\r
504 glEnable(GL_NORMALIZE);
\r
507 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
\r
509 glutReshapeFunc(windowReshape);
\r
510 glutDisplayFunc(display);
\r
511 glutMouseFunc(mouse);
\r
512 glutKeyboardFunc(keyboard);
\r
513 glutMotionFunc(motion);
\r