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