glVertex  5.5.2
glvertex_qt_glwidget.h
Go to the documentation of this file.
1 // (c) by Stefan Roettger, licensed under MIT license
2 
5 #ifndef GLVERTEX_QT_GLWIDGET_H
6 #define GLVERTEX_QT_GLWIDGET_H
7 
8 #include "glvertex_qt.h"
9 
10 #include <QTime>
11 #include <QElapsedTimer>
12 #include <QKeyEvent>
13 
14 #if (QT_VERSION>=QT_VERSION_CHECK(5, 9, 0)) && !defined(LGL_GLES)
15 # define LGL_USE_QOPENGLWIDGET
16 #endif
17 
18 #ifndef LGL_USE_QOPENGLWIDGET
19 # include <QGLWidget>
20 # define LGL_QGLWIDGET QGLWidget
21 #else
22 # include <QOpenGLWidget>
23 # define LGL_QGLWIDGET QOpenGLWidget
24 #endif
25 
27 class lgl_Qt_GLWidget: public LGL_QGLWIDGET
28 {
29 public:
30 
32  lgl_Qt_GLWidget(QWidget *parent = NULL,
33  bool core = true)
34  : LGL_QGLWIDGET(parent),
35  core_(core),
36  time_(0),
37  speedup_(1),
38  background_(false),
39  red_(0), green_(0), blue_(0), alpha_(1),
40  animation_(true),
41  override_(false),
42  ztest_(true),
43  culling_(false),
44  blending_(false),
45  atest_(false),
46  wireframe_(false),
47  fullscreen_(false),
48  timerid_(-1)
49  {
50  setFocusPolicy(Qt::ClickFocus);
51 
52 #if (LGL_OPENGL_VERSION>=30) || defined(LGL_GLES)
53 #ifndef LGL_USE_QOPENGLWIDGET
54  QGLFormat format(QGL::DoubleBuffer | QGL::DepthBuffer);
55  format.setSwapInterval(1);
56  if (core_)
57  {
58 #if (LGL_OPENGL_VERSION >= 30)
59 #if (LGL_OPENGL_VERSION >= 32) && !defined(__APPLE__)
60  format.setVersion(3, 2);
61 #else
62  format.setVersion(3, 0);
63 #endif
64 #else
65  format.setVersion(2, 0);
66 #endif
67 #ifndef FORCE_COMPATIBILITY_PROFILE
68  format.setProfile(QGLFormat::CoreProfile);
69 #else
70  format.setProfile(QGLFormat::CompatibilityProfile);
71 #endif
72  }
73  setFormat(format);
74 #else
75  QSurfaceFormat format;
76  format.setDepthBufferSize(24);
77  format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
78 #if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
79  format.setSwapInterval(1);
80 #endif
81  if (core_)
82  {
83 #if (LGL_OPENGL_VERSION >= 30)
84 #if (LGL_OPENGL_VERSION >= 32) && !defined(__APPLE__)
85  format.setVersion(3, 2);
86 #else
87  format.setVersion(3, 0);
88 #endif
89 #else
90  format.setVersion(2, 0);
91 #endif
92 #ifndef FORCE_COMPATIBILITY_PROFILE
93  format.setProfile(QSurfaceFormat::CoreProfile);
94 #else
95  format.setProfile(QSurfaceFormat::CompatibilityProfile);
96 #endif
97  }
98  setFormat(format);
99 #endif
100 #endif
101 
102 #ifdef QT_DEBUG
103 
104 #if (LGL_OPENGL_VERSION >= 30)
105  std::cerr << "Creating QGLWidget with"
106  << std::endl
107  << " opengl "
108 #ifndef LGL_USE_QOPENGLWIDGET
109  << (format.profile()==QGLFormat::CoreProfile? "core" : "compatibility")
110 #else
111  << (format.profile()==QSurfaceFormat::CoreProfile? "core" : "compatibility")
112 #endif
113  << " profile"
114  << std::endl
115  << " version "
116  << format.majorVersion() << "." << format.minorVersion()
117  << std::endl
118  << std::endl;
119 #endif
120 
121 #endif
122 
123  setFPS(30);
124  }
125 
128  {
129  finish();
130  }
131 
133  void setFPS(double rate)
134  {
135  fps_ = rate;
136 
137  if (fps_ > 0)
138  timerid_ = startTimer((int)(1000/fps_));
139  else
140  {
141  if (timerid_ >= 0) killTimer(timerid_);
142  timerid_ = -1;
143  }
144 
145  timer_.start();
146  update();
147  }
148 
150  void setTimeLapse(double speedup)
151  {
152  speedup_ = speedup;
153  }
154 
156  void background(double red, double green, double blue, double alpha=1)
157  {
158  background_ = true;
159  red_ = red;
160  green_ = green;
161  blue_ = blue;
162  alpha_ = alpha;
163  update();
164  }
165 
168  {
169  if (red_+green_+blue_ > 1.5)
170  background(0,0,0);
171  else
172  background(1,1,1);
173  }
174 
176  void animation(bool on)
177  {
178  animation_ = on;
179  if (animation_) timer_.start();
180  update();
181  }
182 
185  {
186  animation(!animation_);
187  }
188 
190  void ztest(bool on)
191  {
192  if (on != ztest_)
193  {
194  override_ = true;
195  ztest_ = on;
196  update();
197  }
198  }
199 
202  {
203  ztest(!ztest_);
204  }
205 
207  void culling(bool on)
208  {
209  if (on != culling_)
210  {
211  override_ = true;
212  culling_ = on;
213  update();
214  }
215  }
216 
219  {
220  culling(!culling_);
221  }
222 
224  void blending(bool on)
225  {
226  if (on != blending_)
227  {
228  override_ = true;
229  blending_ = on;
230  update();
231  }
232  }
233 
236  {
237  blending(!blending_);
238  }
239 
241  void atest(bool on)
242  {
243  if (on != atest_)
244  {
245  override_ = true;
246  atest_ = on;
247  update();
248  }
249  }
250 
253  {
254  atest(!atest_);
255  }
256 
258  void wireframe(bool on)
259  {
260  if (on != wireframe_)
261  {
262  override_ = true;
263  wireframe_ = on;
264  update();
265  }
266  }
267 
270  {
271  wireframe(!wireframe_);
272  }
273 
275  void override(bool on)
276  {
277  override_ = on;
278  if (!override_) background_ = false;
279  update();
280  }
281 
283  void fullscreen(bool on)
284  {
285  if (on != fullscreen_)
286  {
287  fullscreen_ = on;
288  if (fullscreen_) showFullScreen();
289  else showNormal();
290  setFocus();
291  update();
292  }
293  }
294 
297  {
298  fullscreen(!fullscreen_);
299  }
300 
302  void restart()
303  {
304  time_ = 0;
305  }
306 
307 protected:
308 
309  bool core_; // OpenGL core profile?
310 
311  double time_; // elapsed time
312 
313  double fps_; // animated frames per second
314  double speedup_; // time lapse speedup
315 
316  bool background_;
317  double red_, green_, blue_, alpha_;
318 
319  bool animation_;
320  bool override_;
321  bool ztest_;
322  bool culling_;
323  bool blending_;
324  bool atest_;
325  bool wireframe_;
326  bool fullscreen_;
327 
328  QElapsedTimer timer_;
329  int timerid_;
330 
331  void initializeGL()
332  {
333  initialize();
334 
335 #ifndef LGL_USE_QOPENGLWIDGET
336  qglClearColor(Qt::black);
337 #else
338  glClearColor(0,0,0,1);
339 #endif
340 
342  }
343 
344  void resizeGL(int, int)
345  {
346  lglViewport(0, 0, width(), height());
347 
348  if (fullscreen_)
349  setFocus();
350  }
351 
352  void paintGL()
353  {
354  if (override_)
355  {
356  lglDepthTest(ztest_);
357  lglBackFaceCulling(culling_);
358  lglBlendMode(blending_?LGL_BLEND_ALPHA:LGL_BLEND_NONE);
359  lglAlphaTest(atest_);
360  lglPolygonMode(wireframe_?LGL_LINE:LGL_FILL);
361  }
362 
363  if (background_)
364  {
365  lglClearColor(red_, green_, blue_, alpha_);
366  lglClear();
367  }
368 
369  double dt = 0.001*timer_.elapsed();
370  if (!animation_) dt = 0;
371  else dt *= speedup_;
372 
373  timer_.start();
374 
375  prepareOpenGL(dt);
376  renderOpenGL(dt);
377  updateOpenGL(dt);
378  finishOpenGL(time_+=dt);
379 
380  if (fps_ <= 0)
381  if (animation_)
382  update();
383  }
384 
385  void keyPressEvent(QKeyEvent *event)
386  {
387 #ifndef __APPLE__
388  Qt::KeyboardModifier ctrl = Qt::ControlModifier;
389 #else
390  Qt::KeyboardModifier ctrl = Qt::MetaModifier;
391 #endif
392 
393  if (event->modifiers() & ctrl)
394  if (event->key() == Qt::Key_Space)
395  {
396  animation(!animation_);
397  }
398  else if (event->key() == Qt::Key_Z)
399  {
400  ztest(!ztest_);
401  }
402  else if (event->key() == Qt::Key_C)
403  {
404  culling(!culling_);
405  }
406  else if (event->key() == Qt::Key_B)
407  {
408  blending(!blending_);
409  }
410  else if (event->key() == Qt::Key_A)
411  {
412  atest(!atest_);
413  }
414  else if (event->key() == Qt::Key_W)
415  {
416  wireframe(!wireframe_);
417  }
418  else if (event->key() == Qt::Key_0)
419  {
420  background(0,0,0);
421  }
422  else if (event->key() == Qt::Key_1)
423  {
424  background(1,1,1);
425  }
426  else if (event->key() == Qt::Key_2)
427  {
428  background(0.5,0.5,0.5);
429  }
430  else if (event->key() == Qt::Key_O)
431  {
432  override(!override_);
433  }
434  else if (event->key() == Qt::Key_F)
435  {
436  fullscreen(!fullscreen_);
437  }
438  else
439  event->ignore();
440  else
441  event->ignore();
442  }
443 
444  void timerEvent(QTimerEvent *)
445  {
446  if (animation_)
447  update();
448  }
449 
450  virtual void initialize() {lglInitializeOpenGL();}
451 
453  virtual void initializeOpenGL() = 0;
454 
456  virtual void renderOpenGL(double dt) = 0;
457 
459  virtual void prepareOpenGL(double dt) {}
460 
462  virtual void updateOpenGL(double dt) {}
463 
465  virtual void finishOpenGL(double t) {}
466 
467  virtual void finish() {}
468 };
469 
470 #endif
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_GLWidget::animation
void animation(bool on)
enable animation
Definition: glvertex_qt_glwidget.h:176
lgl_Qt_GLWidget::updateOpenGL
virtual void updateOpenGL(double dt)
implement this method to update state after rendering
Definition: glvertex_qt_glwidget.h:462
lglPolygonMode
void lglPolygonMode(lgl_polygonmode_enum mode)
specify polygon mode (as defined by OpenGL 1.2)
Definition: glvertex_api.h:168
lgl_Qt_GLWidget::toggle_blending
void toggle_blending()
toggle alpha blending
Definition: glvertex_qt_glwidget.h:235
lgl_Qt_GLWidget::wireframe
void wireframe(bool on)
enable wireframe mode
Definition: glvertex_qt_glwidget.h:258
lgl_Qt_GLWidget::toggle_fullscreen
void toggle_fullscreen()
toggle fullscreen mode
Definition: glvertex_qt_glwidget.h:296
lgl_Qt_GLWidget::atest
void atest(bool on)
enable alpha testing
Definition: glvertex_qt_glwidget.h:241
lgl_Qt_GLWidget::blending
void blending(bool on)
enable alpha blending
Definition: glvertex_qt_glwidget.h:224
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_GLWidget::toggle_background
void toggle_background()
toggle background color
Definition: glvertex_qt_glwidget.h:167
lgl_Qt_GLWidget::culling
void culling(bool on)
enable back-face culling
Definition: glvertex_qt_glwidget.h:207
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
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
lgl_Qt_GLWidget::restart
void restart()
restart time
Definition: glvertex_qt_glwidget.h:302
lglDepthTest
void lglDepthTest(bool on=false)
change OpenGL state (depth test)
Definition: glvertex_api.h:388
lgl_Qt_GLWidget::background
void background(double red, double green, double blue, double alpha=1)
set background color
Definition: glvertex_qt_glwidget.h:156
lgl_Qt_GLWidget::lgl_Qt_GLWidget
lgl_Qt_GLWidget(QWidget *parent=NULL, bool core=true)
default ctor
Definition: glvertex_qt_glwidget.h:32
lgl_Qt_GLWidget::ztest
void ztest(bool on)
enable z-buffer test
Definition: glvertex_qt_glwidget.h:190
lglBackFaceCulling
void lglBackFaceCulling(bool on=true)
change OpenGL state (back-face culling)
Definition: glvertex_api.h:396
lgl_Qt_GLWidget::toggle_atest
void toggle_atest()
toggle alpha testing
Definition: glvertex_qt_glwidget.h:252
lgl_Qt_GLWidget::setTimeLapse
void setTimeLapse(double speedup)
set time lapse speedup
Definition: glvertex_qt_glwidget.h:150
lgl_Qt_GLWidget::toggle_ztest
void toggle_ztest()
toggle z-buffer test
Definition: glvertex_qt_glwidget.h:201
lgl_Qt_GLWidget::fullscreen
void fullscreen(bool on)
enable fullscreen mode
Definition: glvertex_qt_glwidget.h:283
lgl_Qt_GLWidget::toggle_animation
void toggle_animation()
toggle animation
Definition: glvertex_qt_glwidget.h:184
lgl_Qt_GLWidget::initializeOpenGL
virtual void initializeOpenGL()=0
implement this method to initialize OpenGL state
lgl_Qt_GLWidget::toggle_culling
void toggle_culling()
toggle back-face culling
Definition: glvertex_qt_glwidget.h:218
lgl_Qt_GLWidget::~lgl_Qt_GLWidget
virtual ~lgl_Qt_GLWidget()
dtor
Definition: glvertex_qt_glwidget.h:127
lgl_Qt_GLWidget::toggle_wireframe
void toggle_wireframe()
toggle wireframe mode
Definition: glvertex_qt_glwidget.h:269
lgl_Qt_GLWidget::prepareOpenGL
virtual void prepareOpenGL(double dt)
implement this method to prepare state before rendering
Definition: glvertex_qt_glwidget.h:459
lgl_Qt_GLWidget::setFPS
void setFPS(double rate)
set frame rate
Definition: glvertex_qt_glwidget.h:133
lgl_Qt_GLWidget::renderOpenGL
virtual void renderOpenGL(double dt)=0
implement this method to render a frame
lgl_Qt_GLWidget::finishOpenGL
virtual void finishOpenGL(double t)
implement this method to finish OpenGL state
Definition: glvertex_qt_glwidget.h:465
lgl_Qt_GLWidget
Qt OpenGL widget base class.
Definition: glvertex_qt_glwidget.h:27