Developer Documentation
GlutViewer.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43  * *
44  * $Revision$ *
45  * $Author$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 
51 
52 //=============================================================================
53 //
54 // CLASS GlutViewer - IMPLEMENTATION
55 //
56 //=============================================================================
57 
58 //== INCLUDES =================================================================
59 
60 
61 #include "GlutViewer.hh"
62 #include <cstdio>
63 
64 
65 //== NAMESPACES ===============================================================
66 
67 
68 namespace ACG {
69 
70 
71 //== IMPLEMENTATION ==========================================================
72 
73 
74 std::map<int, GlutViewer*> GlutViewer::windows__;
75 
76 
77 //-----------------------------------------------------------------------------
78 
79 
80 GlutViewer::GlutViewer(const char* _title, int _width, int _height) :
81  width_(_width),
82  height_(_height),
83  fullscreen_(false),
84  bak_left_(0),
85  bak_top_(0),
86  bak_width_(0),
87  bak_height_(0)
88 {
89  // create window
90  glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_ALPHA);
91  glutInitWindowSize(_width, _height);
92  glViewport(0, 0, _width, _height);
93  windowID_ = glutCreateWindow(_title);
94  windows__[windowID_] = this;
95 
96 
97  // register callbacks
98  glutDisplayFunc(display__);
99  glutKeyboardFunc(keyboard__);
100  glutSpecialFunc(special__);
101  glutMouseFunc(mouse__);
102  glutMotionFunc(motion__);
103  glutPassiveMotionFunc(passivemotion__);
104  glutReshapeFunc(reshape__);
105  glutVisibilityFunc(visibility__);
106 
107 
108  // init GL
109  init();
110 }
111 
112 
113 //-----------------------------------------------------------------------------
114 
115 
116 GlutViewer::
117 ~GlutViewer()
118 {
119  glutDestroyWindow(windowID_);
120 }
121 
122 
123 //-----------------------------------------------------------------------------
124 
125 
126 void
127 GlutViewer::init()
128 {
129  // init GL state
130  glstate_.initialize();
131 
132 
133  // OpenGL state
134  ACG::GLState::enable(GL_DEPTH_TEST);
135  ACG::GLState::enable(GL_LIGHTING);
136  ACG::GLState::disable(GL_DITHER);
137  ACG::GLState::shadeModel(GL_FLAT);
138  glFrontFace(GL_CCW);
139 
140 
141  // light sources
142  glLoadIdentity();
143  GLfloat pos[4], col[4];
144  col[0] = col[1] = col[2] = 0.6f;
145  pos[3] = 0.0f;
146  col[3] = 1.0f;
147 
148 #define SET_LIGHT(i,x,y,z) { \
149  pos[0]=x; pos[1]=y; pos[2]=z; \
150  glLightfv(GL_LIGHT##i, GL_POSITION, pos); \
151  glLightfv(GL_LIGHT##i, GL_DIFFUSE, col); \
152  glLightfv(GL_LIGHT##i, GL_SPECULAR, col); \
153  ACG::GLState::enable(GL_LIGHT##i); \
154 }
155 
156  SET_LIGHT(0, 0.0f, 0.0f, 1.0f);
157  SET_LIGHT(1, -1.0f, 1.0f, 0.7f);
158  SET_LIGHT(2, 1.0f, 1.0f, 0.7f);
159 
160 
161 
162  // projection
163  near_ = 0.1f;
164  far_ = 100.0f;
165  fovy_ = 45.0f;
166  update_projection();
167  glstate_.viewport(0, 0, width_, height_);
168  glstate_.translate(0,0,-3);
169 }
170 
171 
172 //-----------------------------------------------------------------------------
173 
174 
175 void
176 GlutViewer::update_projection()
177 {
178  glstate_.reset_projection();
179  glstate_.perspective(fovy_,
180  (GLfloat) width_ / (GLfloat) height_,
181  near_, far_);
182 }
183 
184 
185 //-----------------------------------------------------------------------------
186 
187 
188 GlutViewer* GlutViewer::current_window() {
189  return windows__[glutGetWindow()];
190 }
191 
192 void GlutViewer::display__(void) {
193  current_window()->display();
194 }
195 
196 void GlutViewer::idle__(void) {
197  current_window()->idle();
198 }
199 
200 void GlutViewer::keyboard__(unsigned char key, int x, int y) {
201  current_window()->keyboard((int)key, x, y);
202 }
203 
204 void GlutViewer::motion__(int x, int y) {
205  current_window()->motion(x, y);
206 }
207 
208 void GlutViewer::mouse__(int button, int state, int x, int y) {
209  current_window()->mouse(button, state, x, y);
210 }
211 
212 void GlutViewer::passivemotion__(int x, int y) {
213  current_window()->passivemotion(x, y);
214 }
215 
216 void GlutViewer::reshape__(int w, int h) {
217  current_window()->reshape(w, h);
218 }
219 
220 void GlutViewer::special__(int key, int x, int y) {
221  current_window()->keyboard(key, x, y);
222 }
223 
224 void GlutViewer::visibility__(int visible) {
225  current_window()->visibility(visible);
226 }
227 
228 
229 //-----------------------------------------------------------------------------
230 
231 
232 void GlutViewer::idle(void) {
233 }
234 
235 void GlutViewer::keyboard(int key, int /* x */ , int /* y */ )
236 {
237  switch (key) {
238  case 27: {
239  exit(0);
240  }
241 
242  case GLUT_KEY_F12: {
243  if (!fullscreen_) {
244  bak_left_ = glutGet(GLUT_WINDOW_X);
245  bak_top_ = glutGet(GLUT_WINDOW_Y);
246  bak_width_ = glutGet(GLUT_WINDOW_WIDTH);
247  bak_height_ = glutGet(GLUT_WINDOW_HEIGHT);
248  glutFullScreen();
249  fullscreen_ = true;
250  } else {
251  glutReshapeWindow(bak_width_, bak_height_);
252  glutPositionWindow(bak_left_, bak_top_);
253  fullscreen_ = false;
254  }
255  break;
256  }
257  }
258 }
259 
260 void GlutViewer::motion(int /* x */ , int /* y */ ) {
261 }
262 
263 void GlutViewer::mouse(int /* button */ , int /* state */ , int /* x */ , int /* y */ ) {
264 }
265 
266 void GlutViewer::passivemotion(int /* x */ , int /* y */ ) {
267 }
268 
269 void GlutViewer::visibility(int /* visible */ ) {
270 }
271 
272 void GlutViewer::reshape(int w, int h)
273 {
274  width_=w; height_=h;
275  glstate_.viewport(0, 0, width_, height_);
276 
277  glstate_.reset_projection();
278  glstate_.perspective(fovy_,
279  (GLfloat) width_ / (GLfloat) height_,
280  near_, far_);
281 
282  glutPostRedisplay();
283 }
284 
285 void GlutViewer::display(void)
286 {
287  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
288  draw();
289  glutSwapBuffers();
290 }
291 
292 
293 //=============================================================================
294 } // namespace ACG
295 //=============================================================================
static void enable(GLenum _cap)
replaces glEnable, but supports locking
Definition: GLState.cc:1490
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Definition: GLState.cc:446
void viewport(int _left, int _bottom, int _width, int _height, int _glwidth=0, int _glheight=0)
set viewport (lower left corner, width, height, glcontext width, height)
Definition: GLState.cc:468
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:531
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
static void disable(GLenum _cap)
replaces glDisable, but supports locking
Definition: GLState.cc:1504
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:332
void initialize()
initialize all state variables (called by constructor)
Definition: GLState.cc:162
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1700