00001 #include "Demo.h"
00002 #include "Textures.h"
00003
00004 Demo::Demo ()
00005 {
00006
00007 fullscreen_enabled = false;
00008 culling_mode = C_NONE;
00009 level_of_detail_enabled = false;
00010 is_initialized = false;
00011 demo_time = DEMO_NOT_YET_STARTED;
00012
00013
00014 frame_rate = 0;
00015 incremental_rate = 0;
00016 last_frame_rate_time = 0;
00017
00018
00019 first_scene = NULL;
00020 current_scene = NULL;
00021
00022
00023 window_width = 640;
00024 window_height = 480;
00025
00026
00027 monitor_camera = new Camera ();
00028 }
00029
00030 Demo::~Demo ()
00031 {
00032
00033 Textures::Release ();
00034
00035
00036 SceneListElem * current_scene;
00037 SceneListElem * scene_to_be_deleted;
00038
00039 current_scene = first_scene;
00040 while (current_scene != NULL)
00041 {
00042 scene_to_be_deleted = current_scene;
00043 current_scene = current_scene->next;
00044 delete scene_to_be_deleted;
00045 }
00046 }
00047
00048 void Demo::Init (int argc, char * argv [])
00049 {
00050 PrintUsage ();
00051
00052
00053 Demo::current_demo = this;
00054
00055
00056 glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ACCUM);
00057
00058 if (argc == 3)
00059 {
00060 int size_x, size_y;
00061 size_x = atoi (argv[1]);
00062 size_y = atoi (argv[2]);
00063
00064 if (size_x > 0 && size_y > 0)
00065 {
00066 window_width = size_x;
00067 window_height = size_y;
00068 }
00069 }
00070 if (argc == 2)
00071 {
00072 glutGameModeString (argv[1]);
00073 if (glutGameModeGet (GLUT_GAME_MODE_POSSIBLE ))
00074 {
00075 fullscreen_enabled = true;
00076 glutEnterGameMode ();
00077 }
00078 }
00079
00080 if (!fullscreen_enabled)
00081 {
00082 glutInitWindowSize (window_width, window_height);
00083 glutCreateWindow("Demo");
00084 }
00085
00086
00087 glutDisplayFunc (Demo::static_display);
00088 glutIdleFunc (Demo::static_idle);
00089 glutReshapeFunc (Demo::static_reshape);
00090 glutKeyboardFunc (Demo::static_keyboard);
00091 glutSpecialFunc (Demo::static_keyboard_special);
00092
00093
00094 glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
00095 glEnable (GL_DEPTH_TEST);
00096 glDepthFunc (GL_LEQUAL);
00097 glShadeModel (GL_SMOOTH);
00098 glEnable (GL_COLOR_MATERIAL);
00099 glEnable (GL_LIGHTING);
00100
00101
00102 SetGlobalAmbientPlayback (0.0f, 0.0f, 0.0f, 0.0f);
00103 SetGlobalAmbientMonitor (0.4f, 0.4f, 0.4f, 1.0f);
00104 SetGlobalSpecularReflection (1.0f, 1.0f, 1.0f, 1.0f);
00105 SetGlobalShininess (64);
00106
00107 glMaterialfv (GL_FRONT, GL_SPECULAR, global_specular_reflection);
00108 glMateriali(GL_FRONT, GL_SHININESS, global_shininess);
00109
00110 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00111
00112
00113 Textures::Load ();
00114
00115
00116 SceneListElem * current_scene;
00117 current_scene = first_scene;
00118 while (current_scene != NULL)
00119 {
00120 if (current_scene->scene != NULL)
00121 {current_scene->scene->Init ();}
00122 current_scene = current_scene->next;
00123 }
00124
00125
00126 srand (timeGetTime ());
00127
00128
00129 level_of_detail_enabled = true;
00130 culling_mode = C_BOUNDING_BOX;
00131
00132 is_initialized = true;
00133 }
00134
00135 void Demo::Play ()
00136 {
00137 if (!is_initialized)
00138 {printf ("Demo has to be initialized first\n"); return;}
00139
00140 if (first_scene == NULL)
00141 {printf ("Demo contains no scenes\n");}
00142
00143 demo_time = 0;
00144 last_measure_time = (int)glutGet (GLUT_ELAPSED_TIME);
00145 monitoring_mode = false;
00146 demo_playing = true;
00147 current_scene = first_scene;
00148
00149 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, global_ambient_playback);
00150
00151 glutShowWindow ();
00152 glutMainLoop ();
00153 }
00154
00155 void Demo::AddScene (Scene * scene, int duration, int blend_in)
00156 {
00157 SceneListElem * current_scene;
00158
00159
00160 if (blend_in > 0 && first_scene == NULL)
00161 {
00162 first_scene = new SceneList;
00163 first_scene->next = NULL;
00164 first_scene->scene = NULL;
00165 first_scene->start_time = 0;
00166 first_scene->blend = duration;
00167 first_scene->end_time = blend_in;
00168 }
00169
00170 if (first_scene == NULL)
00171 {
00172 first_scene = new SceneList;
00173 first_scene->next = NULL;
00174 first_scene->blend = duration;
00175 first_scene->start_time = 0;
00176 first_scene->end_time = duration;
00177 first_scene->scene = scene;
00178 }
00179 else
00180 {
00181 current_scene = first_scene;
00182 while (current_scene->next != NULL) current_scene = current_scene->next;
00183
00184 current_scene->next = new SceneListElem;
00185 current_scene->next->next = NULL;
00186 current_scene->next->blend = current_scene->end_time + duration - blend_in;
00187 current_scene->next->start_time = current_scene->end_time - blend_in;
00188 current_scene->next->end_time = current_scene->next->start_time + duration;
00189 current_scene->blend = current_scene->next->start_time;
00190 current_scene->next->scene = scene;
00191 }
00192 }
00193
00194 void Demo::SwitchMonitor ()
00195 {
00196 monitoring_mode = !monitoring_mode;
00197 if (!monitoring_mode)
00198 {
00199
00200 last_measure_time = (int)glutGet (GLUT_ELAPSED_TIME);
00201 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, global_ambient_playback);
00202 demo_playing = true;
00203 }
00204 else
00205 {
00206
00207 current_scene->scene->CopyPosition (demo_time - current_scene->start_time, monitor_camera);
00208 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, global_ambient_monitor);
00209 demo_playing = false;
00210 }
00211 }
00212
00213 void Demo::SwitchPlayback ()
00214 {
00215 demo_playing = !demo_playing;
00216 if (demo_playing)
00217 {
00218 last_measure_time = (int)glutGet (GLUT_ELAPSED_TIME);
00219 }
00220 }
00221
00222 void Demo::UpdateTime ()
00223 {
00224 int current_measure_time;
00225
00226 current_measure_time = (int)glutGet (GLUT_ELAPSED_TIME);
00227
00228
00229 if (demo_playing)
00230 {
00231 demo_time += current_measure_time - last_measure_time;
00232 last_measure_time = current_measure_time;
00233 }
00234
00235
00236 if (current_measure_time - last_frame_rate_time > 1000)
00237 {
00238 frame_rate = incremental_rate;
00239 incremental_rate = 0;
00240 last_frame_rate_time += 1000;
00241
00242 if (!monitoring_mode)
00243 {
00244 sprintf (buffer, "%03d s, fps: %d", demo_time / 1000, frame_rate);
00245 glutSetWindowTitle (buffer);
00246 }
00247 }
00248 else incremental_rate ++;
00249
00250
00251 if (monitoring_mode)
00252 {
00253 Position mon = monitor_camera->position->GetPosition (0);
00254 sprintf (buffer, "time: %d, fps: %d, pos: {%g, %g, %g, %g, %g, %g}", demo_time, frame_rate, mon.x, mon.y, mon.z, mon.roll, mon.pitch, mon.yaw);
00255 glutSetWindowTitle (buffer);
00256 }
00257 }
00258
00259 void Demo::DisplayLoop ()
00260 {
00261 float ratio;
00262
00263 UpdateTime ();
00264
00265 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00266
00267 if (current_scene != NULL)
00268 {
00269 if (current_scene->end_time <= demo_time)
00270 {current_scene = current_scene->next;}
00271
00272 if (current_scene != NULL)
00273 {
00274 if (current_scene->blend > demo_time)
00275 {ratio = 1.0f;}
00276 else
00277 {ratio = 1 - (((float)(demo_time - current_scene->blend)) / ((float)(current_scene->end_time - current_scene->blend)));}
00278
00279
00280 if (ratio == 1.0f)
00281 {
00282 if (current_scene->scene != NULL)
00283 {
00284 if (!monitoring_mode )
00285 {current_scene->scene->Render (demo_time - current_scene->start_time, culling_mode, level_of_detail_enabled);}
00286 else
00287 {current_scene->scene->Monitor (demo_time - current_scene->start_time, monitor_camera, culling_mode, level_of_detail_enabled);}
00288 }
00289 }
00290 else
00291 {
00292
00293
00294 if (current_scene->scene != NULL)
00295 {
00296 if (!monitoring_mode)
00297 {current_scene->scene->Render (demo_time - current_scene->start_time, culling_mode, level_of_detail_enabled);}
00298 else
00299 {current_scene->scene->Monitor (demo_time - current_scene->start_time, monitor_camera, culling_mode, level_of_detail_enabled);}
00300 }
00301 glAccum (GL_LOAD, ratio);
00302 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00303
00304 if (current_scene->next != NULL && current_scene->next->scene != NULL)
00305 {
00306 if (!monitoring_mode)
00307 {current_scene->next->scene->Render (demo_time - current_scene->next->start_time, culling_mode, level_of_detail_enabled);}
00308 else
00309 {current_scene->next->scene->Monitor (demo_time - current_scene->next->start_time, monitor_camera, culling_mode, level_of_detail_enabled);}
00310 }
00311
00312 glAccum (GL_ACCUM, 1 - ratio);
00313 glAccum (GL_RETURN, 1.0f);
00314 }
00315 }
00316 else
00317 {
00318
00319 demo_time = DEMO_NOT_YET_STARTED;
00320 demo_playing = false;
00321 if (fullscreen_enabled)
00322 {
00323 glutLeaveGameMode ();
00324 exit (0);
00325 }
00326 }
00327 }
00328
00329 glutSwapBuffers ();
00330 }
00331
00332 void Demo::IdleLoop ()
00333 {
00334
00335 glutPostRedisplay ();
00336 }
00337
00338 void Demo::Reshape (int w, int h)
00339 {
00340 glViewport (0, 0, w, h);
00341 }
00342
00343 void Demo::Keyboard (unsigned char key, int x, int y)
00344 {
00345 switch (key)
00346 {
00347
00348 case 'm': if (demo_time != DEMO_NOT_YET_STARTED)
00349 {SwitchMonitor ();}
00350 printf ("Switched Monitor Mode\n");
00351 break;
00352
00353 case 'p': if (demo_time != DEMO_NOT_YET_STARTED)
00354 {SwitchPlayback ();}
00355 printf ("Switched Playback Mode\n");
00356 break;
00357
00358 case 'c': switch (culling_mode)
00359 {
00360 case C_BOUNDING_BOX: culling_mode = C_SPHERE;
00361 printf ("View frustum culling mode set to: sphere\n");
00362 break;
00363 case C_SPHERE: culling_mode = C_MIXED;
00364 printf ("View frustum culling mode set to: mixed\n");
00365 break;
00366 case C_MIXED: culling_mode = C_NONE;
00367 printf ("View frustum culling disabled\n");
00368 break;
00369 case C_NONE: culling_mode = C_BOUNDING_BOX;
00370 printf ("View frustum culling mode set to: bounding box\n");
00371 break;
00372 }
00373 break;
00374
00375 case 'l': level_of_detail_enabled = !level_of_detail_enabled;
00376 if (level_of_detail_enabled)
00377 {printf ("Level of detail is now ENABLED\n");}
00378 else
00379 {printf ("Level of detail is now DISABLED\n");}
00380 break;
00381
00382 case 127: if (monitoring_mode)
00383 {monitor_camera->MoveRight (DELTA_Y);}
00384 break;
00385
00386 case 27: if (fullscreen_enabled)
00387 {
00388 glutLeaveGameMode ();
00389 exit (0);
00390 }
00391 break;
00392
00393 default: printf ("key does nothing\n");
00394 }
00395 }
00396
00397 void Demo::KeyboardSpecial (int key, int x, int y)
00398 {
00399 Position p;
00400
00401 switch (key)
00402 {
00403
00404 case GLUT_KEY_HOME: if (monitoring_mode)
00405 {monitor_camera->MoveForward (DELTA_X);}
00406 break;
00407
00408 case GLUT_KEY_END: if (monitoring_mode)
00409 {monitor_camera->MoveForward (-DELTA_X);}
00410 break;
00411
00412 case GLUT_KEY_PAGE_DOWN: if (monitoring_mode)
00413 {monitor_camera->MoveRight (-DELTA_Y);}
00414 break;
00415
00416 case GLUT_KEY_INSERT: if (monitoring_mode)
00417 {monitor_camera->MoveUp (DELTA_Z);}
00418 break;
00419
00420 case GLUT_KEY_PAGE_UP: if (monitoring_mode)
00421 {monitor_camera->MoveUp (-DELTA_Z);}
00422 break;
00423
00424 case GLUT_KEY_UP: if (monitoring_mode)
00425 {
00426 p = monitor_camera->position->GetPosition (0);
00427 monitor_camera->position->SetConstantPosition (p.x, p.y, p.z, p.roll, p.pitch + DELTA_PITCH, p.yaw);
00428 }
00429 break;
00430
00431 case GLUT_KEY_DOWN: if (monitoring_mode)
00432 {
00433 p = monitor_camera->position->GetPosition (0);
00434 monitor_camera->position->SetConstantPosition (p.x, p.y, p.z, p.roll, p.pitch - DELTA_PITCH, p.yaw);
00435 }
00436 break;
00437
00438 case GLUT_KEY_LEFT: if (monitoring_mode)
00439 {
00440 p = monitor_camera->position->GetPosition (0);
00441 monitor_camera->position->SetConstantPosition (p.x, p.y, p.z, p.roll, p.pitch, p.yaw + DELTA_YAW);
00442 }
00443 break;
00444
00445 case GLUT_KEY_RIGHT: if (monitoring_mode)
00446 {
00447 p = monitor_camera->position->GetPosition (0);
00448 monitor_camera->position->SetConstantPosition (p.x, p.y, p.z, p.roll, p.pitch, p.yaw - DELTA_YAW);
00449 }
00450 break;
00451
00452 default: printf ("special key does nothing\n");
00453 }
00454 }
00455
00456 void Demo::SetGlobalAmbientPlayback (float red, float green, float blue, float alpha)
00457 {
00458 global_ambient_playback[0] = red;
00459 global_ambient_playback[1] = green;
00460 global_ambient_playback[2] = blue;
00461 global_ambient_playback[3] = alpha;
00462 }
00463
00464 void Demo::SetGlobalAmbientMonitor (float red, float green, float blue, float alpha)
00465 {
00466 global_ambient_monitor[0] = red;
00467 global_ambient_monitor[1] = green;
00468 global_ambient_monitor[2] = blue;
00469 global_ambient_monitor[3] = alpha;
00470 }
00471
00472 void Demo::SetGlobalSpecularReflection (float red, float green, float blue, float alpha)
00473 {
00474 global_specular_reflection[0] = red;
00475 global_specular_reflection[1] = green;
00476 global_specular_reflection[2] = blue;
00477 global_specular_reflection[3] = alpha;
00478 }
00479
00480 void Demo::SetGlobalShininess (int shininess_)
00481 {
00482 global_shininess = shininess_;
00483 }
00484
00485 Demo * Demo::current_demo = NULL;
00486
00487 void Demo::static_display ()
00488 {
00489 if (Demo::current_demo != NULL) Demo::current_demo->DisplayLoop ();
00490 }
00491
00492 void Demo::static_idle ()
00493 {
00494 if (Demo::current_demo != NULL) Demo::current_demo->IdleLoop ();
00495 }
00496
00497 void Demo::static_reshape (int w, int h)
00498 {
00499 if (Demo::current_demo != NULL) Demo::current_demo->Reshape (w, h);
00500 }
00501
00502 void Demo::static_keyboard (unsigned char key, int x, int y)
00503 {
00504 if (Demo::current_demo != NULL) Demo::current_demo->Keyboard (key, x, y);
00505 }
00506
00507 void Demo::static_keyboard_special (int key, int x, int y)
00508 {
00509 if (Demo::current_demo != NULL) Demo::current_demo->KeyboardSpecial (key, x, y);
00510 }
00511
00512 void Demo::PrintUsage ()
00513 {
00514 printf ("\n");
00515 printf ("Usage:\n");
00516 printf ("\n");
00517 printf ("windowed mode: demo.exe [WIDTH HEIGHT]\n");
00518 printf ("fullscreen mode: demo.exe WIDTHxHEIGHT:BPP@REFRESHRATE\n");
00519 printf ("\n");
00520 printf ("Keys:\n");
00521 printf ("\n");
00522 printf ("[p]: start/stop playback of the demo.\n");
00523 printf ("[m]: enter/exit monitoring mode (see explanation below).\n");
00524 printf ("[c]: switch between different view frustum culling modes.\n");
00525 printf (" - none: no view frustum culling applied.\n");
00526 printf (" - sphere: view frustum culling using bounding spheres.\n");
00527 printf (" - bounding box: view frustum culling using bounding boxes.\n");
00528 printf (" - mixed: view frustum culling using both bounding spheres\n and bounding boxes.\n");
00529 printf ("[l]: turn level of detail on/off.\n");
00530 printf ("[LEFT]: turn camera to the left during monitoring mode.\n");
00531 printf ("[RIGHT]: turn camera to the right during monitoring mode.\n");
00532 printf ("[UP]: turn camera upwards during monitoring mode.\n");
00533 printf ("[DOWN]: turn camera downwards during monitoring mode.\n");
00534 printf ("[HOME]: move camera forward during monitoring mode.\n");
00535 printf ("[END]: move camera backwards during monitoring mode.\n");
00536 printf ("[DELETE]: move camera to the left during monitoring mode.\n");
00537 printf ("[PGDN]: move camera to the right during monitoring mode.\n");
00538 printf ("[INSERT]: move camera upwards during monitoring mode.\n");
00539 printf ("[PGUP]: move camera downwards during monitoring mode.\n");
00540 printf ("[ESCAPE]: exit if in fullscreen mode.\n");
00541 printf ("\n");
00542 printf ("Monitoring mode:\n");
00543 printf ("\n");
00544 printf ("During monitoring mode, the camera may be moved around freely. The camera\n");
00545 printf ("which captures the scene as well as its viewing frustum are displayed along\n");
00546 printf ("with the bounding volumes of the objects. These volumes are colored\n");
00547 printf ("differently depending on the outcome of the view frustum culling test (red:\n");
00548 printf ("fully outside, green: fully inside, brown: partial). Please note that you can\n");
00549 printf ("always pause/resume playback of the scene at your own free will without leaving\n");
00550 printf ("monitoring mode.\n");
00551 printf ("\n");
00552 printf ("Note:\n");
00553 printf ("\n");
00554 printf ("The keys will only work if the DISPLAY WINDOW is activate. If this CONSOLE\n");
00555 printf ("WINDOW is active, nothing will happen.\n");
00556 printf ("\n");
00557 }