1 // $Id: glut_display.cxx,v 1.25 2003/07/28 22:46:48 grumbel Exp $
3 // Construo - A wire-frame construction gamee
4 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 # include <GL/freeglut.h>
31 #include "buttons.hxx"
33 #include "settings.hxx"
34 #include "construo_main.hxx"
35 #include "screen_manager.hxx"
36 #include "glut_display.hxx"
38 GlutDisplay
* GlutDisplay::instance_
= 0;
40 void reshape_func(int w
, int h
)
42 GlutDisplay::instance()->reshape_func(w
, h
);
47 GlutDisplay::instance()->display_func();
50 void mouse_func (int button
, int button_state
, int x
, int y
)
52 GlutDisplay::instance()->mouse_func(button
, button_state
, x
, y
);
57 GlutDisplay::instance()->idle_func();
60 void keyboard_func (unsigned char key
, int x
, int y
)
62 GlutDisplay::instance()->keyboard_func(key
, x
, y
);
65 void special_func (int key
, int x
, int y
)
67 GlutDisplay::instance()->special_func(key
, x
, y
);
70 void mouse_motion_func (int x
, int y
)
72 GlutDisplay::instance()->mouse_motion_func(x
, y
);
75 GlutDisplay::GlutDisplay (int w
, int h
, int fullscreen
)
84 char* argv
[] = { "construo", "\0" };
86 glutInit(&argc
, argv
); // Only pass empty dummies
87 glutInitDisplayMode(GLUT_DOUBLE
| GLUT_RGBA
);
88 glutInitWindowSize(width
, height
);
89 //glutInitWindowPosition(100, 100); don't care
90 glutSetWindow(glutCreateWindow(construo_main
->get_title()));
92 glutDisplayFunc(::display_func
);
93 glutReshapeFunc(::reshape_func
);
94 glutMouseFunc(::mouse_func
);
96 glutMotionFunc (::mouse_motion_func
);
97 glutPassiveMotionFunc (::mouse_motion_func
);
99 glutIdleFunc (::idle_func
);
100 glutKeyboardFunc(::keyboard_func
);
101 glutSpecialFunc(::special_func
);
103 glClearColor (0.0, 0.0, 0.0, 0.1);
104 if (settings
.alphablending
)
106 glShadeModel (GL_SMOOTH
);
108 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
111 if (settings
.antialiasing
&& settings
.alphablending
)
113 glEnable(GL_LINE_SMOOTH
);
116 //glEnable(GL_SCISSOR_TEST);
117 //glScissor(0, 0, settings.screen_width, settings.screen_height);
118 glutSetCursor(GLUT_CURSOR_FULL_CROSSHAIR
);
132 std::cout
<< "Starting glut mainloop" << std::endl
;
134 std::cout
<< "Ending glut mainloop" << std::endl
;
137 GlutDisplay::~GlutDisplay()
142 GlutDisplay::draw_lines (std::vector
<Line
>& lines
, Color color
, int wide
)
144 if (settings
.thick_lines
)
148 for (std::vector
<Line
>::const_iterator i
= lines
.begin(); i
!= lines
.end(); ++i
)
150 glVertex2f (i
->x1
, i
->y1
);
151 glVertex2f (i
->x2
, i
->y2
);
157 GlutDisplay::draw_line(float x1
, float y1
, float x2
, float y2
, Color color
, int wide
)
159 if (settings
.thick_lines
)
162 glColor4f (color
.r
, color
.g
, color
.b
, color
.a
);
170 GlutDisplay::draw_rect(float x1
, float y1
, float x2
, float y2
, Color color
)
172 if (settings
.thick_lines
)
175 glColor4f (color
.r
, color
.g
, color
.b
, color
.a
);
176 glBegin (GL_LINE_STRIP
);
186 GlutDisplay::draw_fill_rect(float x1
, float y1
, float x2
, float y2
, Color color
)
188 if (settings
.thick_lines
)
191 glColor4f (color
.r
, color
.g
, color
.b
, color
.a
);
201 GlutDisplay::draw_circles(std::vector
<Circle
>& circles
, Color color
)
203 for (std::vector
<Circle
>::iterator i
= circles
.begin(); i
!= circles
.end(); ++i
)
205 draw_circle(i
->x
, i
->y
, i
->r
, color
);
210 GlutDisplay::draw_circle(float x
, float y
, float r
, Color color
)
212 glColor4f (color
.r
, color
.g
, color
.b
, color
.a
);
214 GLUquadricObj
* qobj
= gluNewQuadric ();
215 gluQuadricDrawStyle(qobj
, GLU_SILHOUETTE
);
216 //gluQuadricNormals (qobj, GLU_FLAT);
218 glTranslatef (x
, y
, 0);
219 gluDisk (qobj
, 0, r
, 8, 1);
220 /*draw_rect (x - r, y - r, x + r, y + r,
223 gluDeleteQuadric (qobj
);
227 GlutDisplay::draw_fill_circle(float x
, float y
, float r
, Color color
)
229 glColor4f (color
.r
, color
.g
, color
.b
, color
.a
);
230 //draw_fill_rect (x - r, y - r, x + r, y + r,
233 GLUquadricObj
* qobj
= gluNewQuadric ();
234 gluQuadricDrawStyle(qobj
, GLU_FILL
);
235 //gluQuadricNormals (qobj, GLU_FLAT);
237 glTranslatef (x
, y
, 0);
238 gluDisk (qobj
, 0, r
, 8, 1);
239 /*draw_rect (x - r, y - r, x + r, y + r,
242 gluDeleteQuadric (qobj
);
246 GlutDisplay::draw_string(float x
, float y
, const std::string
& str
, Color color
)
248 if (settings
.thick_lines
)
251 glColor4f (color
.r
, color
.g
, color
.b
, color
.a
);
253 glTranslatef (x
, y
, 0);
254 glScalef (.07f
, -.07, 0);
256 for (std::string::const_iterator i
= str
.begin (); i
!= str
.end (); ++i
)
259 glutBitmapCharacter (GLUT_BITMAP_8_BY_13
, *i
);
261 glutStrokeCharacter (GLUT_STROKE_MONO_ROMAN
, *i
);
262 //glutStrokeWidth (GLUT_STROKE_MONO_ROMAN, *i);
270 GlutDisplay::draw_string_centered(float x
, float y
, const std::string
& str
, Color color
)
272 draw_string(x
- (7.5 * str
.length())/2,
277 GlutDisplay::get_key (int key
)
283 GlutDisplay::get_mouse_x ()
289 GlutDisplay::get_mouse_y ()
295 GlutDisplay::clear ()
297 glClear(GL_COLOR_BUFFER_BIT
);
307 GlutDisplay::flip (int x1
, int y1
, int x2
, int y2
)
314 GlutDisplay::reshape_func(int w
, int h
)
316 std::cout
<< "Reshape: " << w
<< " " << h
<< std::endl
;
317 glViewport (0,0, w
, h
);
318 glMatrixMode(GL_PROJECTION
);
320 gluOrtho2D (0, w
, h
, 0);
321 glMatrixMode(GL_MODELVIEW
);
327 GlutDisplay::display_func ()
329 ScreenManager::instance()->run_once();
333 GlutDisplay::mouse_func (int button
, int button_state
, int x
, int y
)
339 event
.type
= BUTTON_EVENT
;
341 //std::cout << "mouse button press: " << button << " " << button_state << " " << x << " " << y << std::endl;
343 if (button_state
== 0)
344 event
.button
.pressed
= true;
346 event
.button
.pressed
= false;
351 event
.button
.id
= BUTTON_PRIMARY
;
354 event
.button
.id
= BUTTON_TERTIARY
;
357 event
.button
.id
= BUTTON_SECONDARY
;
360 event
.button
.id
= BUTTON_ZOOM_IN
;
363 event
.button
.id
= BUTTON_ZOOM_OUT
;
366 std::cout
<< "GlutDisplay: Unhandle mouse button press: " << button
<< " " << button_state
<< std::endl
;
373 GlutDisplay::idle_func ()
375 /* if (Controller::instance()->is_running() || update_display > 0)
377 //system_context->sleep (0); // limit CPU usage via brute force
380 if (!ScreenManager::instance ()->is_finished())
382 ScreenManager::instance ()->run_once();
386 construo_main
->exit();
391 GlutDisplay::special_func (int key
, int x
, int y
)
405 GlutDisplay::keyboard_func (unsigned char key
, int x
, int y
)
407 //std::cout << "GlutDisplay: keypress: " << key << " (" << int(key) << ") " << x << " " << y << std::endl;
410 event
.type
= BUTTON_EVENT
;
411 event
.button
.pressed
= true;
416 event
.button
.id
= BUTTON_DELETE
;
419 event
.button
.id
= BUTTON_RUN
;
422 event
.button
.id
= BUTTON_TOGGLESLOWMO
;
426 event
.button
.id
= BUTTON_ESCAPE
;
429 event
.button
.id
= BUTTON_FLIP
;
432 event
.button
.id
= BUTTON_FIX
;
435 event
.button
.id
= BUTTON_DUPLICATE
;
439 event
.button
.id
= BUTTON_SETVELOCITY
;
443 event
.button
.id
= BUTTON_CLEAR
;
447 event
.button
.id
= BUTTON_JOIN
;
451 event
.button
.id
= BUTTON_SCALE
;
455 event
.button
.id
= BUTTON_ACTIONCAM
;
459 event
.button
.id
= BUTTON_HIDEDOTS
;
463 event
.button
.id
= BUTTON_QUICKLOAD1
;
467 event
.button
.id
= BUTTON_QUICKLOAD2
;
471 event
.button
.id
= BUTTON_QUICKLOAD3
;
475 event
.button
.id
= BUTTON_QUICKLOAD4
;
479 event
.button
.id
= BUTTON_QUICKLOAD5
;
483 event
.button
.id
= BUTTON_QUICKLOAD6
;
487 event
.button
.id
= BUTTON_QUICKLOAD7
;
491 event
.button
.id
= BUTTON_QUICKLOAD8
;
495 event
.button
.id
= BUTTON_QUICKLOAD9
;
499 event
.button
.id
= BUTTON_QUICKLOAD0
;
503 event
.button
.id
= BUTTON_QUICKSAVE0
;
507 event
.button
.id
= BUTTON_QUICKSAVE1
;
511 event
.button
.id
= BUTTON_QUICKSAVE2
;
515 event
.button
.id
= BUTTON_QUICKSAVE3
;
519 event
.button
.id
= BUTTON_QUICKSAVE4
;
523 event
.button
.id
= BUTTON_QUICKSAVE5
;
527 event
.button
.id
= BUTTON_QUICKSAVE6
;
531 event
.button
.id
= BUTTON_QUICKSAVE7
;
535 event
.button
.id
= BUTTON_QUICKSAVE8
;
539 event
.button
.id
= BUTTON_QUICKSAVE9
;
543 event
.button
.id
= BUTTON_GRID
;
547 event
.button
.id
= BUTTON_UNDO
;
550 event
.button
.id
= BUTTON_REDO
;
553 case '=': // so that people don't have to press shift
554 event
.button
.id
= BUTTON_ZOOM_IN
;
557 event
.button
.id
= BUTTON_ZOOM_OUT
;
561 std::cout
<< "GlutDisplay: Unhandled keypress: '" << key
<< "'[" << int(key
) << "] x/y: "
562 << x
<< ", " << y
<< std::endl
;
571 GlutDisplay::mouse_motion_func (int x
, int y
)
573 //std::cout << "Motion: " << x << " " << y << std::endl;
579 GlutDisplay::leave_fullscreen()
581 std::cout
<< "GlutDisplay: leaving fullscreen: restoring to: pos: "
582 << window_x_pos
<< ", " << window_y_pos
<< " - WxH: "
583 << window_width
<< ", " << window_height
<< std::endl
;
585 glutReshapeWindow(window_width
, window_height
);
586 glutPositionWindow(window_x_pos
, window_y_pos
);
588 is_fullscreen
= false;
592 GlutDisplay::enter_fullscreen()
596 snprintf (mode
, 64, "%dx%d:%d@%d", width
, height
, 16, 80);
597 std::cout
<< "GlutDisplay: switching to: " << mode
<< std::endl
;
598 glutGameModeString(mode
);
600 is_fullscreen
= true;
602 std::cout
<< "GlutDisplay: Entering fullscreen" << std::endl
;
604 window_x_pos
= glutGet((GLenum
)GLUT_WINDOW_X
);
605 window_y_pos
= glutGet((GLenum
)GLUT_WINDOW_Y
);
606 window_width
= glutGet((GLenum
)GLUT_WINDOW_WIDTH
);
607 window_height
= glutGet((GLenum
)GLUT_WINDOW_HEIGHT
);
609 std::cout
<< "Saving window: " << window_x_pos
<< ", " << window_y_pos
<< " - WxH: "
610 << window_width
<< ", " << window_height
<< std::endl
;
614 is_fullscreen
= true;
619 GlutDisplay::set_clip_rect (int x1
, int y1
, int x2
, int y2
)
621 //std::cout << "Setting cliprect: " << x1<< " " <<y1<< " " <<x2-x1+1<< " " <<y2-y1+1<<std::endl;
622 // FIXME: doesn't really work for some reason
623 //std::cout << "Clip: " << x1 << ", " << y1 << " - " << x2-x1+1 << "x" << y2-y1+1 << std::endl;
624 //glScissor(x1, y1, x2-x1+1, y2-y1+1);
628 GlutDisplay::push_quick_draw()
630 if (settings
.antialiasing
&& settings
.alphablending
)
632 glDisable(GL_LINE_SMOOTH
);
637 GlutDisplay::pop_quick_draw()
639 if (settings
.antialiasing
&& settings
.alphablending
)
641 glEnable(GL_LINE_SMOOTH
);
646 GlutDisplay::set_cursor_real(CursorType cursor
)
651 glutSetCursor(GLUT_CURSOR_CROSSHAIR
);
654 glutSetCursor(GLUT_CURSOR_INFO
);
657 glutSetCursor(GLUT_CURSOR_HELP
);
659 case CURSOR_COLLIDER
:
660 glutSetCursor(GLUT_CURSOR_CROSSHAIR
);
663 glutSetCursor(GLUT_CURSOR_INHERIT
);
666 glutSetCursor(GLUT_CURSOR_CYCLE
);
669 std::cout
<< "GlutDisplay: Unhandled cursor type: " << cursor
<< std::endl
;