00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #ifdef HAVE_FREEGLUT
00023 # include <GL/freeglut.h>
00024 #else
00025 # include <GL/glut.h>
00026 #endif
00027
00028 #include <stdio.h>
00029 #include <assert.h>
00030 #include <iostream>
00031 #include "buttons.hxx"
00032 #include "events.hxx"
00033 #include "settings.hxx"
00034 #include "screen_manager.hxx"
00035 #include "glut_display.hxx"
00036
00037 GlutDisplay* GlutDisplay::instance_ = 0;
00038
00039 void reshape_func(int w, int h)
00040 {
00041 GlutDisplay::instance()->reshape_func(w, h);
00042 }
00043
00044 void display_func ()
00045 {
00046 GlutDisplay::instance()->display_func();
00047 }
00048
00049 void mouse_func (int button, int button_state, int x, int y)
00050 {
00051 GlutDisplay::instance()->mouse_func(button, button_state, x, y);
00052 }
00053
00054 void idle_func ()
00055 {
00056 GlutDisplay::instance()->idle_func();
00057 }
00058
00059 void keyboard_func (unsigned char key, int x, int y)
00060 {
00061 GlutDisplay::instance()->keyboard_func(key, x, y);
00062 }
00063
00064 void mouse_motion_func (int x, int y)
00065 {
00066 GlutDisplay::instance()->mouse_motion_func(x, y);
00067 }
00068
00069 GlutDisplay::GlutDisplay (int w, int h)
00070 {
00071 instance_ = this;
00072
00073 update_display = 0;
00074 width = w;
00075 height = h;
00076
00077 int argc = 1;
00078 char* argv[] = { "construo", "\0" };
00079
00080 glutInit(&argc, argv);
00081 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
00082 glutInitWindowSize(width, height);
00083
00084 glutSetWindow(glutCreateWindow(argv[0]));
00085
00086 glutDisplayFunc(::display_func);
00087 glutReshapeFunc(::reshape_func);
00088 glutMouseFunc(::mouse_func);
00089
00090 glutMotionFunc (::mouse_motion_func);
00091 glutPassiveMotionFunc (::mouse_motion_func);
00092
00093 glutIdleFunc (::idle_func);
00094 glutKeyboardFunc(::keyboard_func);
00095
00096 is_fullscreen = false;
00097
00098 glClearColor (0.0, 0.0, 0.0, 0.1);
00099 if (settings.alphablending)
00100 {
00101 glShadeModel (GL_SMOOTH);
00102 glEnable(GL_BLEND);
00103 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00104 }
00105
00106 if (settings.antialiasing && settings.alphablending)
00107 {
00108 glEnable(GL_LINE_SMOOTH);
00109 }
00110
00111 glEnable(GL_SCISSOR_TEST);
00112 glScissor(0, 0, settings.screen_width, settings.screen_height);
00113 }
00114
00115 void
00116 GlutDisplay::run()
00117 {
00118 std::cout << "Starting glut mainloop" << std::endl;
00119 glutMainLoop();
00120 std::cout << "Ending glut mainloop" << std::endl;
00121 }
00122
00123 GlutDisplay::~GlutDisplay()
00124 {
00125 }
00126
00127 void
00128 GlutDisplay::draw_lines (std::vector<Line>& lines, Color color, int wide)
00129 {
00130 glLineWidth (wide);
00131
00132 glBegin (GL_LINES);
00133 for (std::vector<Line>::const_iterator i = lines.begin(); i != lines.end(); ++i)
00134 {
00135 glVertex2f (i->x1, i->y1);
00136 glVertex2f (i->x2, i->y2);
00137 }
00138 glEnd ();
00139 }
00140
00141 void
00142 GlutDisplay::draw_line(float x1, float y1, float x2, float y2, Color color, int wide)
00143 {
00144 glLineWidth (wide);
00145 glColor4f (color.r, color.g, color.b, color.a);
00146 glBegin (GL_LINES);
00147 glVertex2f (x1, y1);
00148 glVertex2f (x2, y2);
00149 glEnd ();
00150 }
00151
00152 void
00153 GlutDisplay::draw_rect(float x1, float y1, float x2, float y2, Color color)
00154 {
00155 glLineWidth (2);
00156 glColor4f (color.r, color.g, color.b, color.a);
00157 glBegin (GL_LINE_STRIP);
00158 glVertex2f (x1, y1);
00159 glVertex2f (x2, y1);
00160 glVertex2f (x2, y2);
00161 glVertex2f (x1, y2);
00162 glVertex2f (x1, y1);
00163 glEnd ();
00164 }
00165
00166 void
00167 GlutDisplay::draw_fill_rect(float x1, float y1, float x2, float y2, Color color)
00168 {
00169 glLineWidth (.5f);
00170 glColor4f (color.r, color.g, color.b, color.a);
00171 glBegin (GL_QUADS);
00172 glVertex2f (x1, y1);
00173 glVertex2f (x2, y1);
00174 glVertex2f (x2, y2);
00175 glVertex2f (x1, y2);
00176 glEnd ();
00177 }
00178
00179 void
00180 GlutDisplay::draw_circles(std::vector<Circle>& circles, Color color)
00181 {
00182 for (std::vector<Circle>::iterator i = circles.begin(); i != circles.end(); ++i)
00183 {
00184 draw_circle(i->x, i->y, i->r, color);
00185 }
00186 }
00187
00188 void
00189 GlutDisplay::draw_circle(float x, float y, float r, Color color)
00190 {
00191 glColor4f (color.r, color.g, color.b, color.a);
00192
00193 GLUquadricObj* qobj = gluNewQuadric ();
00194 gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
00195
00196 glPushMatrix();
00197 glTranslatef (x, y, 0);
00198 gluDisk (qobj, 0, r, 8, 1);
00199
00200
00201 glPopMatrix ();
00202 gluDeleteQuadric (qobj);
00203 }
00204
00205 void
00206 GlutDisplay::draw_fill_circle(float x, float y, float r, Color color)
00207 {
00208 glColor4f (color.r, color.g, color.b, color.a);
00209
00210
00211
00212 GLUquadricObj* qobj = gluNewQuadric ();
00213 gluQuadricDrawStyle(qobj, GLU_FILL);
00214
00215 glPushMatrix();
00216 glTranslatef (x, y, 0);
00217 gluDisk (qobj, 0, r, 8, 1);
00218
00219
00220 glPopMatrix ();
00221 gluDeleteQuadric (qobj);
00222 }
00223
00224 void
00225 GlutDisplay::draw_string(float x, float y, const std::string& str, Color color)
00226 {
00227 glLineWidth (1.0f);
00228 glColor4f (color.r, color.g, color.b, color.a);
00229 glPushMatrix();
00230 glTranslatef (x , y, 0);
00231 glScalef (.07f, -.07, 0);
00232
00233 for (std::string::const_iterator i = str.begin (); i != str.end (); ++i)
00234 {
00235 #ifdef HAVE_FREEGLUT
00236 glutBitmapCharacter (GLUT_BITMAP_8_BY_13, *i);
00237 #else
00238 glutStrokeCharacter (GLUT_STROKE_MONO_ROMAN, *i);
00239
00240 #endif
00241 }
00242 glPopMatrix();
00243 }
00244
00245
00246 void
00247 GlutDisplay::draw_string_centered(float x, float y, const std::string& str, Color color)
00248 {
00249 draw_string(x - (7.5 * str.length())/2,
00250 y, str, color);
00251 }
00252
00253 bool
00254 GlutDisplay::get_key (int key)
00255 {
00256 return false;
00257 }
00258
00259 int
00260 GlutDisplay::get_mouse_x ()
00261 {
00262 return mouse_x;
00263 }
00264
00265 int
00266 GlutDisplay::get_mouse_y ()
00267 {
00268 return mouse_y;
00269 }
00270
00271 void
00272 GlutDisplay::clear ()
00273 {
00274 glClear(GL_COLOR_BUFFER_BIT);
00275 }
00276
00277 void
00278 GlutDisplay::flip ()
00279 {
00280 glutSwapBuffers();
00281 }
00282
00283 void
00284 GlutDisplay::flip (int x1, int y1, int x2, int y2)
00285 {
00286 assert (false);
00287 }
00288
00289
00290 void
00291 GlutDisplay::reshape_func(int w, int h)
00292 {
00293 glViewport (0,0, w, h);
00294 glLoadIdentity();
00295 gluOrtho2D (0, w, h, 0);
00296 }
00297
00298 void
00299 GlutDisplay::display_func ()
00300 {
00301 ScreenManager::instance()->run_once();
00302 }
00303
00304 void
00305 GlutDisplay::mouse_func (int button, int button_state, int x, int y)
00306 {
00307 mouse_x = x;
00308 mouse_y = y;
00309
00310 Event event;
00311 event.type = BUTTON_EVENT;
00312
00313
00314
00315 if (button_state == 0)
00316 event.button.pressed = true;
00317 else
00318 event.button.pressed = false;
00319
00320 switch (button)
00321 {
00322 case 0:
00323 event.button.id = BUTTON_PRIMARY;
00324 break;
00325 case 1:
00326 event.button.id = BUTTON_TERTIARY;
00327 break;
00328 case 2:
00329 event.button.id = BUTTON_SECONDARY;
00330 break;
00331 case 3:
00332 event.button.id = BUTTON_ZOOM_IN;
00333 break;
00334 case 4:
00335 event.button.id = BUTTON_ZOOM_OUT;
00336 break;
00337 default:
00338 std::cout << "GlutDisplay: Unhandle mouse button press: " << button << " " << button_state << std::endl;
00339 return;
00340 }
00341 events.push (event);
00342 }
00343
00344 void
00345 GlutDisplay::idle_func ()
00346 {
00347
00348
00349
00350
00351
00352 if (!ScreenManager::instance ()->is_finished())
00353 {
00354 ScreenManager::instance ()->run_once();
00355 }
00356 else
00357 {
00358
00359 exit(EXIT_SUCCESS);
00360 }
00361 }
00362
00363 void
00364 GlutDisplay::keyboard_func (unsigned char key, int x, int y)
00365 {
00366
00367
00368 Event event;
00369 event.type = BUTTON_EVENT;
00370 event.button.pressed = true;
00371
00372 switch (key)
00373 {
00374 case 127:
00375 event.button.id = BUTTON_DELETE;
00376 break;
00377 case 32:
00378 event.button.id = BUTTON_RUN;
00379 break;
00380 case 9:
00381 event.button.id = BUTTON_TOGGLESLOWMO;
00382 break;
00383 case 27:
00384 case 'q':
00385 event.button.id = BUTTON_ESCAPE;
00386 break;
00387 case 'f':
00388 event.button.id = BUTTON_FIX;
00389 break;
00390 case 'd':
00391 event.button.id = BUTTON_DUPLICATE;
00392 break;
00393
00394 case 'v':
00395 event.button.id = BUTTON_SETVELOCITY;
00396 break;
00397
00398 case 'c':
00399 event.button.id = BUTTON_CLEAR;
00400 break;
00401
00402 case 'a':
00403 event.button.id = BUTTON_ACTIONCAM;
00404 break;
00405
00406 case 'o':
00407 event.button.id = BUTTON_HIDEDOTS;
00408 break;
00409
00410 case '!':
00411 event.button.id = BUTTON_QUICKLOAD1;
00412 break;
00413
00414 case '@':
00415 event.button.id = BUTTON_QUICKLOAD2;
00416 break;
00417
00418 case '#':
00419 event.button.id = BUTTON_QUICKLOAD3;
00420 break;
00421
00422 case '$':
00423 event.button.id = BUTTON_QUICKLOAD4;
00424 break;
00425
00426 case '%':
00427 event.button.id = BUTTON_QUICKLOAD5;
00428 break;
00429
00430 case '^':
00431 event.button.id = BUTTON_QUICKLOAD6;
00432 break;
00433
00434 case '&':
00435 event.button.id = BUTTON_QUICKLOAD7;
00436 break;
00437
00438 case '*':
00439 event.button.id = BUTTON_QUICKLOAD8;
00440 break;
00441
00442 case '(':
00443 event.button.id = BUTTON_QUICKLOAD9;
00444 break;
00445
00446 case ')':
00447 event.button.id = BUTTON_QUICKLOAD0;
00448 break;
00449
00450 case '0':
00451 event.button.id = BUTTON_QUICKSAVE0;
00452 break;
00453
00454 case '1':
00455 event.button.id = BUTTON_QUICKSAVE1;
00456 break;
00457
00458 case '2':
00459 event.button.id = BUTTON_QUICKSAVE2;
00460 break;
00461
00462 case '3':
00463 event.button.id = BUTTON_QUICKSAVE3;
00464 break;
00465
00466 case '4':
00467 event.button.id = BUTTON_QUICKSAVE4;
00468 break;
00469
00470 case '5':
00471 event.button.id = BUTTON_QUICKSAVE5;
00472 break;
00473
00474 case '6':
00475 event.button.id = BUTTON_QUICKSAVE6;
00476 break;
00477
00478 case '7':
00479 event.button.id = BUTTON_QUICKSAVE7;
00480 break;
00481
00482 case '8':
00483 event.button.id = BUTTON_QUICKSAVE8;
00484 break;
00485
00486 case '9':
00487 event.button.id = BUTTON_QUICKSAVE9;
00488 break;
00489
00490 case 'u':
00491 event.button.id = BUTTON_UNDO;
00492 break;
00493 case 'r':
00494 event.button.id = BUTTON_REDO;
00495 break;
00496 case '+':
00497 case '=':
00498 event.button.id = BUTTON_ZOOM_IN;
00499 break;
00500 case '-':
00501 event.button.id = BUTTON_ZOOM_OUT;
00502 break;
00503 default:
00504 std::cout << "GlutDisplay: Unhandled keypress: '" << key << "'[" << int(key) << "] x/y: "
00505 << x << ", " << y << std::endl;
00506 return;
00507 }
00508
00509 events.push(event);
00510 }
00511
00512 void
00513 GlutDisplay::mouse_motion_func (int x, int y)
00514 {
00515
00516 mouse_x = x;
00517 mouse_y = y;
00518 }
00519
00520 void
00521 GlutDisplay::set_fullscreen (bool fullscreen)
00522 {
00523 if (fullscreen)
00524 {
00525 char mode[64];
00526 snprintf (mode, 64, "%dx%d:%d@%d", width, height, 16, 80);
00527 std::cout << "GlutDisplay: switching to: " << mode << std::endl;
00528 glutGameModeString(mode);
00529 glutEnterGameMode();
00530 is_fullscreen = true;
00531 }
00532 else
00533 {
00534 is_fullscreen = false;
00535 }
00536 }
00537
00538 void
00539 GlutDisplay::set_clip_rect (int x1, int y1, int x2, int y2)
00540 {
00541
00542
00543
00544 }
00545
00546