Clean up the QOpenGLWindow example
1. Use includes without module prefixes, as is the custom in examples. 2. No inline functions to make it more readable. 3. Pause animation on pressing P and document our signal connection a bit more. Change-Id: I68dc3d4c74b639cf3fec17b63b7f49626db58bdb Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
This commit is contained in:
parent
37023a096d
commit
78221fe762
@ -40,13 +40,13 @@
|
||||
|
||||
#include "background_renderer.h"
|
||||
|
||||
#include <QtCore/qmath.h>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QTime>
|
||||
#include <qmath.h>
|
||||
#include <QFileInfo>
|
||||
#include <QTime>
|
||||
|
||||
#include <QtGui/QOpenGLShaderProgram>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QOpenGLFunctions>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -41,14 +41,14 @@
|
||||
#ifndef FRAGMENT_TOY_H
|
||||
#define FRAGMENT_TOY_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QFileSystemWatcher>
|
||||
#include <QtGui/QOpenGLVertexArrayObject>
|
||||
#include <QtGui/QOpenGLBuffer>
|
||||
#include <QtGui/QOpenGLShaderProgram>
|
||||
#include <QtGui/QOpenGLFunctions>
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include <QDateTime>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
class FragmentToy : public QObject, protected QOpenGLFunctions
|
||||
{
|
||||
|
@ -38,12 +38,13 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui/QOpenGLWindow>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QMatrix4x4>
|
||||
#include <QtGui/QStaticText>
|
||||
#include <QOpenGLWindow>
|
||||
#include <QScreen>
|
||||
#include <QPainter>
|
||||
#include <QGuiApplication>
|
||||
#include <QMatrix4x4>
|
||||
#include <QStaticText>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "background_renderer.h"
|
||||
|
||||
@ -65,71 +66,16 @@ class OpenGLWindow : public QOpenGLWindow
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Use NoPartialUpdate. This means that all the rendering goes directly to
|
||||
// the window surface, no additional framebuffer object stands in the
|
||||
// middle. This is fine since we will clear the entire framebuffer on each
|
||||
// paint. Under the hood this means that the behavior is equivalent to the
|
||||
// manual makeCurrent - perform OpenGL calls - swapBuffers loop that is
|
||||
// typical in pure QWindow-based applications.
|
||||
OpenGLWindow()
|
||||
: QOpenGLWindow(QOpenGLWindow::NoPartialUpdate)
|
||||
, m_fragment_toy("background.frag")
|
||||
, m_text_layout("The triangle and this text is rendered with QPainter")
|
||||
{
|
||||
m_view.lookAt(QVector3D(3,1,1),
|
||||
QVector3D(0,0,0),
|
||||
QVector3D(0,1,0));
|
||||
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
||||
|
||||
QLinearGradient gradient(QPointF(-1,-1), QPointF(1,1));
|
||||
gradient.setColorAt(0, Qt::red);
|
||||
gradient.setColorAt(1, Qt::green);
|
||||
|
||||
m_brush = QBrush(gradient);
|
||||
}
|
||||
OpenGLWindow();
|
||||
|
||||
protected:
|
||||
void paintGL() Q_DECL_OVERRIDE
|
||||
{
|
||||
m_fragment_toy.draw(size());
|
||||
|
||||
QPainter p(this);
|
||||
p.setWorldTransform(m_window_normalised_matrix.toTransform());
|
||||
|
||||
QMatrix4x4 mvp = m_projection * m_view * m_model_triangle;
|
||||
p.setTransform(mvp.toTransform(), true);
|
||||
|
||||
p.fillPath(painterPathForTriangle(), m_brush);
|
||||
|
||||
QTransform text_transform = (m_window_painter_matrix * m_view * m_model_text).toTransform();
|
||||
p.setTransform(text_transform, false);
|
||||
p.setPen(QPen(Qt::white));
|
||||
m_text_layout.prepare(text_transform);
|
||||
qreal x = - (m_text_layout.size().width() / 2);
|
||||
qreal y = 0;
|
||||
p.drawStaticText(x, y, m_text_layout);
|
||||
|
||||
m_model_triangle.rotate(-1, 0, 1, 0);
|
||||
m_model_text.rotate(1, 0, 1, 0);
|
||||
}
|
||||
|
||||
void resizeGL(int w, int h) Q_DECL_OVERRIDE
|
||||
{
|
||||
m_window_normalised_matrix.setToIdentity();
|
||||
m_window_normalised_matrix.translate(w / 2.0, h / 2.0);
|
||||
m_window_normalised_matrix.scale(w / 2.0, -h / 2.0);
|
||||
|
||||
m_window_painter_matrix.setToIdentity();
|
||||
m_window_painter_matrix.translate(w / 2.0, h / 2.0);
|
||||
|
||||
m_text_layout.setTextWidth(std::max(w * 0.2, 80.0));
|
||||
|
||||
m_projection.setToIdentity();
|
||||
m_projection.perspective(45.f, qreal(w) / qreal(h), 0.1f, 100.f);
|
||||
|
||||
}
|
||||
void paintGL() Q_DECL_OVERRIDE;
|
||||
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
|
||||
void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void setAnimating(bool enabled);
|
||||
|
||||
QMatrix4x4 m_window_normalised_matrix;
|
||||
QMatrix4x4 m_window_painter_matrix;
|
||||
QMatrix4x4 m_projection;
|
||||
@ -140,9 +86,97 @@ private:
|
||||
|
||||
FragmentToy m_fragment_toy;
|
||||
QStaticText m_text_layout;
|
||||
bool m_animate;
|
||||
};
|
||||
|
||||
int main (int argc, char **argv)
|
||||
// Use NoPartialUpdate. This means that all the rendering goes directly to
|
||||
// the window surface, no additional framebuffer object stands in the
|
||||
// middle. This is fine since we will clear the entire framebuffer on each
|
||||
// paint. Under the hood this means that the behavior is equivalent to the
|
||||
// manual makeCurrent - perform OpenGL calls - swapBuffers loop that is
|
||||
// typical in pure QWindow-based applications.
|
||||
OpenGLWindow::OpenGLWindow()
|
||||
: QOpenGLWindow(QOpenGLWindow::NoPartialUpdate)
|
||||
, m_fragment_toy("background.frag")
|
||||
, m_text_layout("The triangle and this text is rendered with QPainter")
|
||||
, m_animate(true)
|
||||
{
|
||||
m_view.lookAt(QVector3D(3,1,1),
|
||||
QVector3D(0,0,0),
|
||||
QVector3D(0,1,0));
|
||||
|
||||
QLinearGradient gradient(QPointF(-1,-1), QPointF(1,1));
|
||||
gradient.setColorAt(0, Qt::red);
|
||||
gradient.setColorAt(1, Qt::green);
|
||||
|
||||
m_brush = QBrush(gradient);
|
||||
|
||||
setAnimating(m_animate);
|
||||
}
|
||||
|
||||
void OpenGLWindow::paintGL()
|
||||
{
|
||||
m_fragment_toy.draw(size());
|
||||
|
||||
QPainter p(this);
|
||||
p.setWorldTransform(m_window_normalised_matrix.toTransform());
|
||||
|
||||
QMatrix4x4 mvp = m_projection * m_view * m_model_triangle;
|
||||
p.setTransform(mvp.toTransform(), true);
|
||||
|
||||
p.fillPath(painterPathForTriangle(), m_brush);
|
||||
|
||||
QTransform text_transform = (m_window_painter_matrix * m_view * m_model_text).toTransform();
|
||||
p.setTransform(text_transform, false);
|
||||
p.setPen(QPen(Qt::white));
|
||||
m_text_layout.prepare(text_transform);
|
||||
qreal x = - (m_text_layout.size().width() / 2);
|
||||
qreal y = 0;
|
||||
p.drawStaticText(x, y, m_text_layout);
|
||||
|
||||
m_model_triangle.rotate(-1, 0, 1, 0);
|
||||
m_model_text.rotate(1, 0, 1, 0);
|
||||
}
|
||||
|
||||
void OpenGLWindow::resizeGL(int w, int h)
|
||||
{
|
||||
m_window_normalised_matrix.setToIdentity();
|
||||
m_window_normalised_matrix.translate(w / 2.0, h / 2.0);
|
||||
m_window_normalised_matrix.scale(w / 2.0, -h / 2.0);
|
||||
|
||||
m_window_painter_matrix.setToIdentity();
|
||||
m_window_painter_matrix.translate(w / 2.0, h / 2.0);
|
||||
|
||||
m_text_layout.setTextWidth(std::max(w * 0.2, 80.0));
|
||||
|
||||
m_projection.setToIdentity();
|
||||
m_projection.perspective(45.f, qreal(w) / qreal(h), 0.1f, 100.f);
|
||||
}
|
||||
|
||||
void OpenGLWindow::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
if (e->key() == Qt::Key_P) { // pause
|
||||
m_animate = !m_animate;
|
||||
setAnimating(m_animate);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLWindow::setAnimating(bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
// Animate continuously, throttled by the blocking swapBuffers() call the
|
||||
// QOpenGLWindow internally executes after each paint. Once that is done
|
||||
// (frameSwapped signal is emitted), we schedule a new update. This
|
||||
// obviously assumes that the swap interval (see
|
||||
// QSurfaceFormat::setSwapInterval()) is non-zero.
|
||||
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
||||
update();
|
||||
} else {
|
||||
disconnect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user