glVertex  5.5.2
glvertex_qt_glwindow.h
Go to the documentation of this file.
1 // (c) by Stefan Roettger, licensed under MIT license
2 
5 #ifndef GLVERTEX_QT_GLWINDOW_H
6 #define GLVERTEX_QT_GLWINDOW_H
7 
8 #include "glvertex_qt.h"
9 
10 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
11 
12 #include "glvertex_qt_glwidget.h"
13 
14 class lgl_Qt_GLWindow: public lgl_Qt_GLWidget
15 {
16 public:
17 
19  lgl_Qt_GLWindow(bool core = true)
20  : lgl_Qt_GLWidget(NULL, core)
21  {}
22 
24  virtual ~lgl_Qt_GLWindow()
25  {}
26 
27 };
28 
29 #else
30 
31 #include <QTime>
32 #include <QElapsedTimer>
33 #include <QWindow>
34 #include <QKeyEvent>
35 #include <QOpenGLContext>
36 #include <QOpenGLFunctions>
37 #include <QCoreApplication>
38 
40 class lgl_Qt_GLWindow: public QWindow, protected QOpenGLFunctions
41 {
42 public:
43 
45  lgl_Qt_GLWindow(bool core = true)
46  : QWindow(),
47  core_(core),
48  time_(0),
49  speedup_(1),
50  background_(false),
51  red_(0), green_(0), blue_(0), alpha_(1),
52  animation_(true),
53  override_(false),
54  ztest_(true),
55  culling_(false),
56  blending_(false),
57  atest_(false),
58  wireframe_(false),
59  fullscreen_(false),
60  timerid_(-1),
61  m_context(NULL),
62  m_update_pending(false)
63  {
64  setSurfaceType(QWindow::OpenGLSurface);
65 
66  QSurfaceFormat format;
67  format.setDepthBufferSize(24);
68  format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
69 #if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
70  format.setSwapInterval(1);
71 #endif
72  if (core_)
73  {
74 #if (LGL_OPENGL_VERSION>=30) || defined(LGL_GLES)
75 #if (LGL_OPENGL_VERSION >= 30)
76 #if (LGL_OPENGL_VERSION >= 32) && !defined(__APPLE__)
77  format.setVersion(3, 2);
78 #else
79  format.setVersion(3, 0);
80 #endif
81 #else
82  format.setVersion(2, 0);
83 #endif
84 #ifndef FORCE_COMPATIBILITY_PROFILE
85  format.setProfile(QSurfaceFormat::CoreProfile);
86 #else
87  format.setProfile(QSurfaceFormat::CompatibilityProfile);
88 #endif
89 #endif
90  }
91  setFormat(format);
92 
93 #ifdef QT_DEBUG
94 
95 #if (LGL_OPENGL_VERSION >= 30)
96  std::cerr << "Creating QWindow with"
97  << std::endl
98  << " opengl "
99  << (format.profile()==QSurfaceFormat::CoreProfile? "core" : "compatibility")
100  << " profile"
101  << std::endl
102  << " version "
103  << format.majorVersion() << "." << format.minorVersion()
104  << std::endl
105  << std::endl;
106 #endif
107 
108 #endif
109 
110  setFPS(30);
111  }
112 
115  {
116  finish();
117  }
118 
120  void update()
121  {
122  renderLater();
123  }
124 
126  void setFPS(double rate)
127  {
128  fps_ = rate;
129 
130  if (fps_ > 0)
131  timerid_ = startTimer((int)(1000/fps_));
132  else
133  {
134  if (timerid_ >= 0) killTimer(timerid_);
135  timerid_ = -1;
136  }
137 
138  timer_.start();
139  update();
140  }
141 
143  void setTimeLapse(double speedup)
144  {
145  speedup_ = speedup;
146  }
147 
149  void background(double red, double green, double blue, double alpha=1)
150  {
151  background_ = true;
152  red_ = red;
153  green_ = green;
154  blue_ = blue;
155  alpha_ = alpha;
156  update();
157  }
158 
161  {
162  if (red_+green_+blue_ > 1.5)
163  background(0,0,0);
164  else
165  background(1,1,1);
166  }
167 
169  void animation(bool on)
170  {
171  animation_ = on;
172  if (animation_) timer_.start();
173  update();
174  }
175 
178  {
179  animation(!animation_);
180  }
181 
183  void ztest(bool on)
184  {
185  if (on != ztest_)
186  {
187  override_ = true;
188  ztest_ = on;
189  update();
190  }
191  }
192 
195  {
196  ztest(!ztest_);
197  }
198 
200  void culling(bool on)
201  {
202  if (on != culling_)
203  {
204  override_ = true;
205  culling_ = on;
206  update();
207  }
208  }
209 
212  {
213  culling(!culling_);
214  }
215 
217  void blending(bool on)
218  {
219  if (on != blending_)
220  {
221  override_ = true;
222  blending_ = on;
223  update();
224  }
225  }
226 
229  {
230  blending(!blending_);
231  }
232 
234  void atest(bool on)
235  {
236  if (on != atest_)
237  {
238  override_ = true;
239  atest_ = on;
240  update();
241  }
242  }
243 
246  {
247  atest(!atest_);
248  }
249 
251  void wireframe(bool on)
252  {
253  if (on != wireframe_)
254  {
255  override_ = true;
256  wireframe_ = on;
257  update();
258  }
259  }
260 
263  {
264  wireframe(!wireframe_);
265  }
266 
268  void override(bool on)
269  {
270  override_ = on;
271  if (!override_) background_ = false;
272  update();
273  }
274 
276  void fullscreen(bool on)
277  {
278  if (on != fullscreen_)
279  {
280  fullscreen_ = on;
281  if (fullscreen_) showFullScreen();
282  else showNormal();
283  requestActivate();
284  update();
285  }
286  }
287 
290  {
291  fullscreen(!fullscreen_);
292  }
293 
295  void restart()
296  {
297  time_ = 0;
298  }
299 
300 public slots:
301 
302  void renderNow()
303  {
304  if (!isExposed())
305  return;
306 
307  bool needsInitialize = false;
308 
309  if (!m_context)
310  {
311  m_context = new QOpenGLContext(this);
312  m_context->setFormat(requestedFormat());
313  m_context->create();
314 
315  needsInitialize = true;
316  }
317 
318  m_context->makeCurrent(this);
319 
320  if (needsInitialize)
321  {
322  initialize();
323  initializeOpenGLFunctions();
324  initializeOpenGL();
325  }
326 
327  if (override_)
328  {
329  lglDepthTest(ztest_);
330  lglBackFaceCulling(culling_);
331  lglBlendMode(blending_?LGL_BLEND_ALPHA:LGL_BLEND_NONE);
332  lglAlphaTest(atest_);
333  lglPolygonMode(wireframe_?LGL_LINE:LGL_FILL);
334  }
335 
336  float scale = devicePixelRatio();
337  lglViewport(0, 0, scale*width(), scale*height());
338 
339  if (background_)
340  {
341  lglClearColor(red_, green_, blue_, alpha_);
342  lglClear();
343  }
344 
345  double dt = 0.001*timer_.elapsed();
346  if (!animation_) dt = 0;
347  else dt *= speedup_;
348 
349  timer_.start();
350 
351  prepareOpenGL(dt);
352  renderOpenGL(dt);
353  updateOpenGL(dt);
354  finishOpenGL(time_+=dt);
355 
356  m_context->swapBuffers(this);
357 
358  if (fps_ <= 0)
359  if (animation_)
360  update();
361  }
362 
363  void renderLater()
364  {
365  if (!m_update_pending)
366  {
367  m_update_pending = true;
368  QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
369  }
370  }
371 
372 protected:
373 
374  bool core_; // OpenGL core profile?
375 
376  double time_; // elapsed time
377 
378  double fps_; // animated frames per second
379  double speedup_; // time lapse speedup
380 
381  bool background_;
382  double red_, green_, blue_, alpha_;
383 
384  bool animation_;
385  bool override_;
386  bool ztest_;
387  bool culling_;
388  bool blending_;
389  bool atest_;
390  bool wireframe_;
391  bool fullscreen_;
392 
393  QElapsedTimer timer_;
394  int timerid_;
395 
396  bool event(QEvent *event)
397  {
398  switch (event->type())
399  {
400  case QEvent::UpdateRequest:
401  m_update_pending = false;
402  renderNow();
403  return(true);
404  default:
405  return(QWindow::event(event));
406  }
407  }
408 
409  void exposeEvent(QExposeEvent *)
410  {
411  if (isExposed())
412  renderNow();
413  }
414 
415  void keyPressEvent(QKeyEvent *event)
416  {
417 #ifndef __APPLE__
418  Qt::KeyboardModifier ctrl = Qt::ControlModifier;
419 #else
420  Qt::KeyboardModifier ctrl = Qt::MetaModifier;
421 #endif
422 
423  if (event->modifiers() & ctrl)
424  if (event->key() == Qt::Key_Space)
425  {
426  animation(!animation_);
427  }
428  else if (event->key() == Qt::Key_Z)
429  {
430  ztest(!ztest_);
431  }
432  else if (event->key() == Qt::Key_C)
433  {
434  culling(!culling_);
435  }
436  else if (event->key() == Qt::Key_B)
437  {
438  blending(!blending_);
439  }
440  else if (event->key() == Qt::Key_A)
441  {
442  atest(!atest_);
443  }
444  else if (event->key() == Qt::Key_W)
445  {
446  wireframe(!wireframe_);
447  }
448  else if (event->key() == Qt::Key_0)
449  {
450  background(0,0,0);
451  }
452  else if (event->key() == Qt::Key_1)
453  {
454  background(1,1,1);
455  }
456  else if (event->key() == Qt::Key_2)
457  {
458  background(0.5,0.5,0.5);
459  }
460  else if (event->key() == Qt::Key_O)
461  {
462  override(!override_);
463  }
464  else if (event->key() == Qt::Key_F)
465  {
466  fullscreen(!fullscreen_);
467  }
468  else
469  event->ignore();
470  else
471  event->ignore();
472  }
473 
474  void timerEvent(QTimerEvent *)
475  {
476  if (animation_)
477  update();
478  }
479 
480  virtual void initialize() {lglInitializeOpenGL();}
481  virtual void initializeOpenGL() = 0; //< reimplement for initializing OpenGL state
482  virtual void prepareOpenGL(double dt) {}
483  virtual void renderOpenGL(double dt) = 0; //< reimplement for rendering each frame
484  virtual void updateOpenGL(double dt) {}
485  virtual void finishOpenGL(double t) {}
486  virtual void finish() {}
487 
488 private:
489 
490  QOpenGLContext *m_context;
491  bool m_update_pending;
492 };
493 
494 #endif
495 
496 #endif
lgl_Qt_GLWindow::blending
void blending(bool on)
enable alpha blending
Definition: glvertex_qt_glwindow.h:217
lglBlendMode
void lglBlendMode(lgl_blendmode_enum mode)
change OpenGL state (blending)
Definition: glvertex_api.h:404
lglAlphaTest
void lglAlphaTest(bool on=false, float value=0.0f, bool greater=true, bool equal=false)
change OpenGL state (alpha test)
Definition: glvertex_api.h:416
lglInitializeOpenGL
void lglInitializeOpenGL(float r=0, float g=0, float b=0, float a=1, bool ztest=true, bool culling=false)
initialize OpenGL state (clear color, depth test, back-face culling)
Definition: glvertex_api.h:367
lgl_Qt_GLWindow::~lgl_Qt_GLWindow
virtual ~lgl_Qt_GLWindow()
dtor
Definition: glvertex_qt_glwindow.h:114
lglPolygonMode
void lglPolygonMode(lgl_polygonmode_enum mode)
specify polygon mode (as defined by OpenGL 1.2)
Definition: glvertex_api.h:168
lgl_Qt_GLWindow::animation
void animation(bool on)
enable animation
Definition: glvertex_qt_glwindow.h:169
lgl_Qt_GLWindow::restart
void restart()
restart time
Definition: glvertex_qt_glwindow.h:295
lgl_Qt_GLWindow::setFPS
void setFPS(double rate)
set frame rate
Definition: glvertex_qt_glwindow.h:126
lglViewport
void lglViewport(int ax, int ay, int bx, int by)
specify viewport (as defined by OpenGL 1.2)
Definition: glvertex_api.h:132
lgl_Qt_GLWindow::toggle_ztest
void toggle_ztest()
toggle z-buffer test
Definition: glvertex_qt_glwindow.h:194
lgl_Qt_GLWindow::toggle_culling
void toggle_culling()
toggle back-face culling
Definition: glvertex_qt_glwindow.h:211
lgl_Qt_GLWindow::toggle_blending
void toggle_blending()
toggle alpha blending
Definition: glvertex_qt_glwindow.h:228
lglClear
void lglClear(GLuint bits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
clear color and depth buffer (as defined by OpenGL 1.2)
Definition: glvertex_api.h:144
lgl_Qt_GLWindow::lgl_Qt_GLWindow
lgl_Qt_GLWindow(bool core=true)
default ctor
Definition: glvertex_qt_glwindow.h:45
lglClearColor
void lglClearColor(float w=0, float a=1)
specify clear color (as defined by OpenGL 1.2)
Definition: glvertex_api.h:136
glvertex_qt.h
lglDepthTest
void lglDepthTest(bool on=false)
change OpenGL state (depth test)
Definition: glvertex_api.h:388
lglBackFaceCulling
void lglBackFaceCulling(bool on=true)
change OpenGL state (back-face culling)
Definition: glvertex_api.h:396
lgl_Qt_GLWindow::toggle_atest
void toggle_atest()
toggle alpha testing
Definition: glvertex_qt_glwindow.h:245
lgl_Qt_GLWindow::culling
void culling(bool on)
enable back-face culling
Definition: glvertex_qt_glwindow.h:200
lgl_Qt_GLWindow::fullscreen
void fullscreen(bool on)
enable fullscreen mode
Definition: glvertex_qt_glwindow.h:276
lgl_Qt_GLWindow::atest
void atest(bool on)
enable alpha testing
Definition: glvertex_qt_glwindow.h:234
lgl_Qt_GLWindow::setTimeLapse
void setTimeLapse(double speedup)
set time lapse speedup
Definition: glvertex_qt_glwindow.h:143
lgl_Qt_GLWindow::toggle_animation
void toggle_animation()
toggle animation
Definition: glvertex_qt_glwindow.h:177
lgl_Qt_GLWindow::update
void update()
update
Definition: glvertex_qt_glwindow.h:120
lgl_Qt_GLWindow::toggle_wireframe
void toggle_wireframe()
toggle wireframe mode
Definition: glvertex_qt_glwindow.h:262
lgl_Qt_GLWindow::background
void background(double red, double green, double blue, double alpha=1)
set background color
Definition: glvertex_qt_glwindow.h:149
scale
mat4 scale(const mat4 &m, const vec4 &c)
inline scale
Definition: glslmath.h:2591
lgl_Qt_GLWindow::toggle_fullscreen
void toggle_fullscreen()
toggle fullscreen mode
Definition: glvertex_qt_glwindow.h:289
glvertex_qt_glwidget.h
lgl_Qt_GLWindow::ztest
void ztest(bool on)
enable z-buffer test
Definition: glvertex_qt_glwindow.h:183
lgl_Qt_GLWindow::toggle_background
void toggle_background()
toggle background color
Definition: glvertex_qt_glwindow.h:160
lgl_Qt_GLWindow
Qt OpenGL window base class.
Definition: glvertex_qt_glwindow.h:40
lgl_Qt_GLWindow::wireframe
void wireframe(bool on)
enable wireframe mode
Definition: glvertex_qt_glwindow.h:251
lgl_Qt_GLWidget
Qt OpenGL widget base class.
Definition: glvertex_qt_glwidget.h:27