This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 // $Id: glut_display.cxx,v 1.11 2003/01/12 19:06:08 grumbel Exp $ 00002 // 00003 // Construo - A wire-frame construction gamee 00004 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de> 00005 // 00006 // This program is free software; you can redistribute it and/or 00007 // modify it under the terms of the GNU General Public License 00008 // as published by the Free Software Foundation; either version 2 00009 // of the License, or (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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); // Only pass empty dummies 00081 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 00082 glutInitWindowSize(width, height); 00083 //glutInitWindowPosition(100, 100); don't care 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 //gluQuadricNormals (qobj, GLU_FLAT); 00196 glPushMatrix(); 00197 glTranslatef (x, y, 0); 00198 gluDisk (qobj, 0, r, 8, 1); 00199 /*draw_rect (x - r, y - r, x + r, y + r, 00200 color);*/ 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 //draw_fill_rect (x - r, y - r, x + r, y + r, 00210 // color); 00211 00212 GLUquadricObj* qobj = gluNewQuadric (); 00213 gluQuadricDrawStyle(qobj, GLU_FILL); 00214 //gluQuadricNormals (qobj, GLU_FLAT); 00215 glPushMatrix(); 00216 glTranslatef (x, y, 0); 00217 gluDisk (qobj, 0, r, 8, 1); 00218 /*draw_rect (x - r, y - r, x + r, y + r, 00219 color);*/ 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 //glutStrokeWidth (GLUT_STROKE_MONO_ROMAN, *i); 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 //std::cout << "mouse button press: " << button << " " << button_state << " " << x << " " << y << std::endl; 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 /* if (Controller::instance()->is_running() || update_display > 0) 00348 { 00349 //system_context->sleep (0); // limit CPU usage via brute force 00350 update_display = 0; 00351 }*/ 00352 if (!ScreenManager::instance ()->is_finished()) 00353 { 00354 ScreenManager::instance ()->run_once(); 00355 } 00356 else 00357 { 00358 // FIXME: is there a more gracefull way to end this? 00359 exit(EXIT_SUCCESS); 00360 } 00361 } 00362 00363 void 00364 GlutDisplay::keyboard_func (unsigned char key, int x, int y) 00365 { 00366 //std::cout << "GlutDisplay: keypress: " << key << " (" << int(key) << ") " << x << " " << y << std::endl; 00367 00368 Event event; 00369 event.type = BUTTON_EVENT; 00370 event.button.pressed = true; 00371 00372 switch (key) 00373 { 00374 case 127: // Delete 00375 event.button.id = BUTTON_DELETE; 00376 break; 00377 case 32: // Space 00378 event.button.id = BUTTON_RUN; 00379 break; 00380 case 9: // Tab 00381 event.button.id = BUTTON_TOGGLESLOWMO; 00382 break; 00383 case 27: // Escape 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 '=': // so that people don't have to press shift 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 //std::cout << "Motion: " << x << " " << y << std::endl; 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 //std::cout << "Setting cliprect: " << x1<< " " <<y1<< " " <<x2-x1+1<< " " <<y2-y1+1<<std::endl; 00542 // FIXME: doesn't really work for some reason 00543 //glScissor(x1, y1, x2-x1+1, y2-y1+1); 00544 } 00545 00546 /* EOF */