OGLplus (0.52.0) a C++ wrapper for OpenGL

glut_glew_example.hpp
1 /*
2  * @file standalone/glut_glew_example.hpp
3  * @brief Implements GLUT/GLEW-based program main function for running examples
4  *
5  * Copyright 2008-2014 Matus Chochlik. Distributed under the Boost
6  * Software License, Version 1.0. (See accompanying file
7  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8  */
9 #ifndef OGLPLUS_STANDALONE_GLUT_GLEW_EXAMPLE_1203161253_HPP
10 #define OGLPLUS_STANDALONE_GLUT_GLEW_EXAMPLE_1203161253_HPP
11 
12 #include <GL/glew.h>
13 
14 #include <oglplus/config/gl.hpp>
15 
16 #if OGLPLUS_USE_FREEGLUT
17 # include <GL/freeglut.h>
18 #else
19 # include <GL/glut.h>
20 #endif
21 
22 #include <cassert>
23 #include <cstdlib>
24 #include <iostream>
25 #include <chrono>
26 
28 #include <oglplus/error/limit.hpp>
29 
30 namespace oglplus {
31 
32 class StandaloneExample
33 {
34 private:
35  std::chrono::time_point<std::chrono::system_clock> _start;
36  std::chrono::time_point<std::chrono::system_clock> _now;
37  double _frame_time, _frame_duration;
38  unsigned long _frame_number;
39 
40  GLuint _width, _height;
41 
42  GLuint _prev_mouse_x, _prev_mouse_y;
43  GLuint _curr_mouse_x, _curr_mouse_y;
44 
45  GLuint _curr_key;
46 public:
47  void HandleUpdate(void)
48  {
49  static const double period =
50  double(std::chrono::system_clock::period::num)/
51  double(std::chrono::system_clock::period::den);
52  auto now = std::chrono::system_clock::now();
53  _frame_duration = (now - _now).count() * period;
54  _now = now;
55  _frame_time = (_now - _start).count() * period;
56  ++_frame_number;
57  }
58 
59  void HandleResize(GLuint width, GLuint height)
60  {
61  _width = width;
62  _height = height;
63  }
64 
65  void HandleMouseMove(GLuint mouse_x, GLuint mouse_y)
66  {
67  _prev_mouse_x = _curr_mouse_x;
68  _prev_mouse_y = _curr_mouse_y;;
69  _curr_mouse_x = mouse_x;
70  _curr_mouse_y = mouse_y;
71  }
72 
73  void HandleKeyPress(GLuint key)
74  {
75  _curr_key = key;
76  }
77 
78 
79  double FrameTime(void) const { return _frame_time; }
80  double FrameDuration(void) const { return _frame_duration; }
81  unsigned long FrameNumber(void) const { return _frame_number; }
82 
83  double CurrentFPS(void) const { return 1.0 / _frame_duration; }
84  double AverageFPS(void) const { return _frame_number / _frame_time; }
85 
86  GLuint Width(void) const { return _width; }
87  GLuint Height(void) const { return _height; }
88  double Aspect(void) const { return double(_width)/double(_height); }
89 
90  GLuint MouseX(void) const { return _curr_mouse_x; }
91  GLuint MouseY(void) const { return _curr_mouse_y; }
92 
93  int MouseDiffX(void) const
94  {
95  return _curr_mouse_x - _prev_mouse_x;
96  }
97 
98  int MouseDiffY(void) const
99  {
100  return _curr_mouse_y - _prev_mouse_y;
101  }
102 
103  double NormMouseX(void) const
104  {
105  return double(2*_curr_mouse_x)/_width - 1.0;
106  }
107 
108  double NormMouseY(void) const
109  {
110  return double(2*_curr_mouse_y)/_height - 1.0;
111  }
112 
113  double NormMouseDiffX(void) const
114  {
115  return double(2*MouseDiffX())/_width;
116  }
117 
118  double NormMouseDiffY(void) const
119  {
120  return double(2*MouseDiffY())/_height;
121  }
122 
123  GLuint Key(void) const { return _curr_key; }
124 
125 private:
126  StandaloneExample(const StandaloneExample&);
127 public:
128 
129  StandaloneExample(void)
130  : _width(800)
131  , _height(800)
132  { }
133 
134  virtual ~StandaloneExample(void)
135  { }
136 
137  void Startup(GLuint width, GLuint height)
138  {
139  HandleResize(width, height);
140  Reshape();
141 
142  HandleMouseMove(_width/2, _height/2);
143  HandleMouseMove(_width/2, _height/2);
144  PassiveMotion();
145 
146  _start = std::chrono::system_clock::now();
147  _frame_number = 0;
148  HandleUpdate();
149  }
150 
151  virtual void Render(void) = 0;
152 
153  virtual void Reshape(void) = 0;
154 
155  virtual void Motion(void)
156  {
157  }
158 
159  virtual void PassiveMotion(void)
160  {
161  }
162 
163  virtual void KeyPress(void)
164  {
165  }
166 };
167 
168 template <typename Example>
169 class SingleExampleTpl
170 {
171 private:
172  static Example*& SingleInstance(void)
173  {
174  static Example* _ptr = nullptr;
175  return _ptr;
176  }
177 public:
178  SingleExampleTpl(int argc, const char** argv)
179  {
180  assert(!SingleInstance());
181  SingleInstance() = new Example(argc, argv);
182  }
183 
184  ~SingleExampleTpl(void)
185  {
186  delete SingleInstance();
187  }
188 
189  void Startup(GLuint width, GLuint height)
190  {
191  assert(SingleInstance());
192  SingleInstance()->Startup(width, height);
193  }
194 
195  static void CloseFunc(void)
196  {
197  assert(SingleInstance());
198  delete SingleInstance();
199  SingleInstance() = nullptr;
200  }
201 
202  static void DisplayFunc(void)
203  {
204  assert(SingleInstance());
205  SingleInstance()->HandleUpdate();
206  SingleInstance()->Render();
207  glutSwapBuffers();
208  }
209 
210  static void ReshapeFunc(int width, int height)
211  {
212  assert(SingleInstance());
213  SingleInstance()->HandleResize(width, height);
214  SingleInstance()->Reshape();
215  }
216 
217  static void MotionFunc(int x, int y)
218  {
219  assert(SingleInstance());
220  SingleInstance()->HandleMouseMove(x, y);
221  SingleInstance()->Motion();
222  }
223 
224  static void PassiveMotionFunc(int x, int y)
225  {
226  assert(SingleInstance());
227  SingleInstance()->HandleMouseMove(x, y);
228  SingleInstance()->PassiveMotion();
229  }
230 
231  static void KeyboardFunc(unsigned char k, int, int)
232  {
233  if(k == 0x1B) // Escape
234  {
235 #if OGLPLUS_USE_FREEGLUT
236  glutLeaveMainLoop();
237 #else
238  exit(0);
239 #endif
240  }
241  else
242  {
243  assert(SingleInstance());
244  SingleInstance()->HandleKeyPress(k);
245  SingleInstance()->KeyPress();
246  }
247  }
248 };
249 
250 class GlutInit
251 {
252 protected:
253  GlutInit(
254  GLuint xpos,
255  GLuint ypos,
256  GLuint width,
257  GLuint height,
258  const char* window_title,
259  int &argc,
260  char* argv[]
261  )
262  {
263  glutInit(&argc, argv);
264 
265  glutInitDisplayMode(
266  GLUT_DOUBLE |
267  GLUT_RGBA |
268  GLUT_DEPTH |
269  GLUT_STENCIL
270  );
271 
272  glutInitWindowPosition(xpos, ypos);
273  glutInitWindowSize(width, height);
274 
275  glutCreateWindow(window_title);
276  }
277 };
278 
279 class GlewInit
280 {
281 protected:
282  GlewInit(void)
283  {
284  if(glewInit() != GLEW_OK)
285  {
286  throw std::runtime_error(
287  "GLEW initialization error"
288  );
289  }
290  glGetError();
291  }
292 };
293 
294 template <typename Example>
295 class GlutGlewExampleApp
296  : public GlutInit
297  , public GlewInit
298 {
299 private:
300  typedef SingleExampleTpl<Example> SingleExample;
301  SingleExample example;
302 
303  GlutGlewExampleApp(const GlutGlewExampleApp&);
304 public:
305  GlutGlewExampleApp(
306  GLuint xpos,
307  GLuint ypos,
308  GLuint width,
309  GLuint height,
310  const char* window_title,
311  int &argc,
312  char* argv[]
313  ): GlutInit(
314  xpos,
315  ypos,
316  width,
317  height,
318  window_title,
319  argc,
320  argv
321  ), GlewInit()
322  , example(argc, const_cast<const char**>(argv))
323  {
324  glutReshapeFunc(&SingleExample::ReshapeFunc);
325 
326  glutMotionFunc(&SingleExample::MotionFunc);
327  glutPassiveMotionFunc(&SingleExample::PassiveMotionFunc);
328 
329  glutKeyboardFunc(&SingleExample::KeyboardFunc);
330 
331  glutDisplayFunc(&SingleExample::DisplayFunc);
332  glutIdleFunc(&SingleExample::DisplayFunc);
333 
334  example.Startup(width, height);
335  }
336 
337  void Run(int /*argc*/, const char** /*argv*/)
338  {
339 #if OGLPLUS_USE_FREEGLUT
340  glutSetOption(
341  GLUT_ACTION_ON_WINDOW_CLOSE,
342  GLUT_ACTION_GLUTMAINLOOP_RETURNS
343  );
344  glutCloseFunc(&SingleExample::CloseFunc);
345 #endif
346  glutMainLoop();
347  }
348 };
349 
350 template <typename Example>
351 int GlutGlewMain(const char* title, int argc, char* argv[])
352 {
353  try
354  {
355  std::cout << "Started" << std::endl;
356  {
357  GLuint width = 800, height = 600;
358  GlutGlewExampleApp<Example> app(
359  100, 100,
360  width, height,
361  title,
362  argc, argv
363  );
364  app.Run(argc, const_cast<const char**>(argv));
365  }
366  std::cout << "Finished" << std::endl;
367  return 0;
368  }
369  catch(oglplus::ProgramBuildError& pbe)
370  {
371  std::cerr
372  << "Program build error (in "
373  << pbe.GLFunc()
374  << ", "
375  << pbe.ObjectTypeName()
376  << ": ("
377  << pbe.ObjectName()
378  << ") '"
379  << pbe.ObjectDesc()
380  << "'): "
381  << pbe.what()
382  << ": "
383  << pbe.Log()
384  << std::endl;
385  }
386  catch(oglplus::LimitError& le)
387  {
388  std::cerr
389  << "Limit error: ("
390  << le.Value()
391  << ") exceeds ("
392  << le.EnumParamName()
393  << " == "
394  << le.Limit()
395  << ") ["
396  << le.SourceFile()
397  << ":"
398  << le.SourceLine()
399  << "] "
400  << std::endl;
401  }
402  catch(oglplus::ObjectError& obe)
403  {
404  std::cerr
405  << "Object error (in "
406  << obe.GLFunc()
407  << ", "
408  << obe.ObjectTypeName()
409  << ": ("
410  << obe.ObjectName()
411  << ") '"
412  << obe.ObjectDesc()
413  << "') ["
414  << obe.SourceFile()
415  << ":"
416  << obe.SourceLine()
417  << "]: "
418  << obe.what()
419  << std::endl;
420  }
421  catch(oglplus::Error& err)
422  {
423  std::cerr
424  << "Error (in "
425  << err.GLFunc()
426  << "') ["
427  << err.SourceFile()
428  << ":"
429  << err.SourceLine()
430  << "]: "
431  << err.what()
432  << std::endl;
433  }
434  catch(std::exception& se)
435  {
436  std::cerr << "Error: " << se.what() << std::endl;
437  }
438  return 1;
439 }
440 
441 } // namespace oglplus
442 
443 #endif
Exception indicating exceeded implementation-defined limits.
Definition: limit.hpp:30
const String & ObjectDesc(void) const
Object textual description.
GLint ObjectName(void) const
Object GL name.
Base class for program compilation or linking errors.
Definition: program.hpp:27
const char * ObjectTypeName(void) const
Returns the class name.
Program errors.
Exception class for general OpenGL errors.
Definition: basic.hpp:43
Exception class for GL object-related errors.
Definition: object.hpp:24
Limited value error.
const char * EnumParamName(void) const
Returns the name of the enumeration parameter related to the error.

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).