summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/widgets/painting/affine/affine.pro4
-rw-r--r--examples/widgets/painting/affine/xform.cpp8
-rw-r--r--examples/widgets/painting/composition/composition.cpp129
-rw-r--r--examples/widgets/painting/composition/composition.h18
-rw-r--r--examples/widgets/painting/composition/composition.pro4
-rw-r--r--examples/widgets/painting/composition/main.cpp7
-rw-r--r--examples/widgets/painting/deform/deform.pro4
-rw-r--r--examples/widgets/painting/deform/pathdeform.cpp24
-rw-r--r--examples/widgets/painting/gradients/gradients.cpp8
-rw-r--r--examples/widgets/painting/gradients/gradients.pro4
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.cpp16
-rw-r--r--examples/widgets/painting/pathstroke/pathstroke.pro4
-rw-r--r--examples/widgets/painting/shared/arthurwidgets.cpp80
-rw-r--r--examples/widgets/painting/shared/arthurwidgets.h46
-rw-r--r--examples/widgets/painting/shared/fbopaintdevice.cpp113
-rw-r--r--examples/widgets/painting/shared/fbopaintdevice.h91
-rw-r--r--examples/widgets/painting/shared/hoverpoints.cpp19
-rw-r--r--examples/widgets/painting/shared/shared.pri6
18 files changed, 346 insertions, 239 deletions
diff --git a/examples/widgets/painting/affine/affine.pro b/examples/widgets/painting/affine/affine.pro
index 0ad869183c..0af18b82ca 100644
--- a/examples/widgets/painting/affine/affine.pro
+++ b/examples/widgets/painting/affine/affine.pro
@@ -1,10 +1,6 @@
SOURCES += main.cpp xform.cpp
HEADERS += xform.h
-qtHaveModule(opengl) {
- DEFINES += QT_OPENGL_SUPPORT
- QT += opengl
-}
QT += widgets
SHARED_FOLDER = ../shared
diff --git a/examples/widgets/painting/affine/xform.cpp b/examples/widgets/painting/affine/xform.cpp
index 20f6eb3c6d..dc01acf453 100644
--- a/examples/widgets/painting/affine/xform.cpp
+++ b/examples/widgets/painting/affine/xform.cpp
@@ -830,13 +830,11 @@ XFormWidget::XFormWidget(QWidget *parent)
QPushButton *showSourceButton = new QPushButton(mainGroup);
showSourceButton->setText(tr("Show Source"));
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(true);
enableOpenGLButton->setChecked(view->usesOpenGL());
- if (!QGLFormat::hasOpenGL())
- enableOpenGLButton->hide();
#endif
QPushButton *whatsThisButton = new QPushButton(mainGroup);
whatsThisButton->setText(tr("What's This?"));
@@ -871,7 +869,7 @@ XFormWidget::XFormWidget(QWidget *parent)
mainGroupLayout->addWidget(resetButton);
mainGroupLayout->addWidget(animateButton);
mainGroupLayout->addWidget(showSourceButton);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton);
#endif
mainGroupLayout->addWidget(whatsThisButton);
@@ -897,7 +895,7 @@ XFormWidget::XFormWidget(QWidget *parent)
connect(view, &XFormView::descriptionEnabledChanged, view->hoverPoints(), &HoverPoints::setDisabled);
connect(view, &XFormView::descriptionEnabledChanged, whatsThisButton, &QPushButton::setChecked);
connect(showSourceButton, &QPushButton::clicked, view, &XFormView::showSource);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
connect(enableOpenGLButton, &QPushButton::clicked, view, &XFormView::enableOpenGL);
#endif
view->loadSourceFile(":res/affine/xform.cpp");
diff --git a/examples/widgets/painting/composition/composition.cpp b/examples/widgets/painting/composition/composition.cpp
index 0b57d3c7d3..3bc31b1fce 100644
--- a/examples/widgets/painting/composition/composition.cpp
+++ b/examples/widgets/painting/composition/composition.cpp
@@ -57,6 +57,11 @@
#include <QMouseEvent>
#include <qmath.h>
+#if QT_CONFIG(opengl)
+#include <QOpenGLFunctions>
+#include <QOpenGLWindow>
+#endif
+
const int animationInterval = 15; // update every 16 ms = ~60FPS
CompositionWidget::CompositionWidget(QWidget *parent)
@@ -136,14 +141,11 @@ CompositionWidget::CompositionWidget(QWidget *parent)
QPushButton *showSourceButton = new QPushButton(mainGroup);
showSourceButton->setText(tr("Show Source"));
-#if defined(USE_OPENGL) && !defined(QT_OPENGL_ES)
+#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(true);
enableOpenGLButton->setChecked(view->usesOpenGL());
-
- if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers())
- enableOpenGLButton->hide();
#endif
QPushButton *whatsThisButton = new QPushButton(mainGroup);
whatsThisButton->setText(tr("What's This?"));
@@ -166,7 +168,7 @@ CompositionWidget::CompositionWidget(QWidget *parent)
mainGroupLayout->addWidget(animateButton);
mainGroupLayout->addWidget(whatsThisButton);
mainGroupLayout->addWidget(showSourceButton);
-#if defined(USE_OPENGL) && !defined(QT_OPENGL_ES)
+#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton);
#endif
@@ -210,7 +212,7 @@ CompositionWidget::CompositionWidget(QWidget *parent)
connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool)));
connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool)));
connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource()));
-#if defined(USE_OPENGL) && !defined(QT_OPENGL_ES)
+#if QT_CONFIG(opengl)
connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool)));
#endif
connect(animateButton, SIGNAL(toggled(bool)), view, SLOT(setAnimationEnabled(bool)));
@@ -258,8 +260,7 @@ CompositionRenderer::CompositionRenderer(QWidget *parent)
m_circle_pos = QPoint(200, 100);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-#ifdef USE_OPENGL
- m_pbuffer = 0;
+#if QT_CONFIG(opengl)
m_pbuffer_size = 1024;
#endif
}
@@ -350,8 +351,11 @@ void CompositionRenderer::drawSource(QPainter &p)
void CompositionRenderer::paint(QPainter *painter)
{
-#if defined(USE_OPENGL) && !defined(QT_OPENGL_ES)
- if (usesOpenGL()) {
+#if QT_CONFIG(opengl)
+ if (usesOpenGL() && glWindow()->isValid()) {
+
+ if (!m_blitter.isCreated())
+ m_blitter.create();
int new_pbuf_size = m_pbuffer_size;
if (size().width() > m_pbuffer_size || size().height() > m_pbuffer_size)
@@ -360,95 +364,46 @@ void CompositionRenderer::paint(QPainter *painter)
if (size().width() < m_pbuffer_size/2 && size().height() < m_pbuffer_size/2)
new_pbuf_size /= 2;
- if (!m_pbuffer || new_pbuf_size != m_pbuffer_size) {
- if (m_pbuffer) {
- m_pbuffer->deleteTexture(m_base_tex);
- m_pbuffer->deleteTexture(m_compositing_tex);
- delete m_pbuffer;
- }
-
- m_pbuffer = new QGLPixelBuffer(QSize(new_pbuf_size, new_pbuf_size), QGLFormat::defaultFormat(), glWidget());
- m_pbuffer->makeCurrent();
- m_base_tex = m_pbuffer->generateDynamicTexture();
- m_compositing_tex = m_pbuffer->generateDynamicTexture();
+ if (!m_fbo || new_pbuf_size != m_pbuffer_size) {
+ m_fbo.reset(new QFboPaintDevice(QSize(new_pbuf_size, new_pbuf_size), false, false));
m_pbuffer_size = new_pbuf_size;
}
if (size() != m_previous_size) {
m_previous_size = size();
- QPainter p(m_pbuffer);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
+ QPainter p(m_fbo.data());
drawBase(p);
p.end();
- m_pbuffer->updateDynamicTexture(m_base_tex);
+ m_base_tex = m_fbo->takeTexture();
}
- qreal x_fraction = width()/float(m_pbuffer->width());
- qreal y_fraction = height()/float(m_pbuffer->height());
-
+ painter->beginNativePainting();
{
- QPainter p(m_pbuffer);
- p.setCompositionMode(QPainter::CompositionMode_Source);
- p.fillRect(QRect(0, 0, m_pbuffer->width(), m_pbuffer->height()), Qt::transparent);
-
- p.save(); // Needed when using the GL1 engine
- p.beginNativePainting(); // Needed when using the GL2 engine
-
- glBindTexture(GL_TEXTURE_2D, m_base_tex);
- glEnable(GL_TEXTURE_2D);
- glColor4f(1.,1.,1.,1.);
-
- glBegin(GL_QUADS);
- {
- glTexCoord2f(0, 1.0);
- glVertex2f(0, 0);
-
- glTexCoord2f(x_fraction, 1.0);
- glVertex2f(width(), 0);
-
- glTexCoord2f(x_fraction, 1.0-y_fraction);
- glVertex2f(width(), height());
-
- glTexCoord2f(0, 1.0-y_fraction);
- glVertex2f(0, height());
- }
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
-
- p.endNativePainting(); // Needed when using the GL2 engine
- p.restore(); // Needed when using the GL1 engine
-
+ QPainter p(m_fbo.data());
+ p.beginNativePainting();
+ m_blitter.bind();
+ const QRect targetRect(QPoint(0, 0), m_fbo->size());
+ const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, QRect(QPoint(0, 0), m_fbo->size()));
+ m_blitter.blit(m_base_tex, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ m_blitter.release();
+ p.endNativePainting();
drawSource(p);
p.end();
- m_pbuffer->updateDynamicTexture(m_compositing_tex);
- }
-
- painter->beginNativePainting(); // Needed when using the GL2 engine
- glWidget()->makeCurrent(); // Needed when using the GL1 engine
- glBindTexture(GL_TEXTURE_2D, m_compositing_tex);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glColor4f(1.,1.,1.,1.);
- glBegin(GL_QUADS);
- {
- glTexCoord2f(0, 1.0);
- glVertex2f(0, 0);
-
- glTexCoord2f(x_fraction, 1.0);
- glVertex2f(width(), 0);
-
- glTexCoord2f(x_fraction, 1.0-y_fraction);
- glVertex2f(width(), height());
-
- glTexCoord2f(0, 1.0-y_fraction);
- glVertex2f(0, height());
+ m_compositing_tex = m_fbo->takeTexture();
}
- glEnd();
- glDisable(GL_TEXTURE_2D);
- painter->endNativePainting(); // Needed when using the GL2 engine
+ painter->endNativePainting();
+
+ painter->beginNativePainting();
+ auto *funcs = QOpenGLContext::currentContext()->functions();
+ funcs->glEnable(GL_BLEND);
+ funcs->glBlendEquation(GL_FUNC_ADD);
+ funcs->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ m_blitter.bind();
+ const QRect targetRect(QPoint(0, 0), m_fbo->size());
+ const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, QRect(QPoint(0, 0), size()));
+ m_blitter.blit(m_compositing_tex, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ m_blitter.release();
+ painter->endNativePainting();
} else
#endif
{
@@ -520,7 +475,7 @@ void CompositionRenderer::setCirclePos(const QPointF &pos)
const QRect oldRect = rectangle_around(m_circle_pos).toAlignedRect();
m_circle_pos = pos;
const QRect newRect = rectangle_around(m_circle_pos).toAlignedRect();
-#if defined(USE_OPENGL) && !defined(QT_OPENGL_ES)
+#if QT_CONFIG(opengl)
if (usesOpenGL()) {
update();
return;
diff --git a/examples/widgets/painting/composition/composition.h b/examples/widgets/painting/composition/composition.h
index 49853f503b..19150e2024 100644
--- a/examples/widgets/painting/composition/composition.h
+++ b/examples/widgets/painting/composition/composition.h
@@ -53,6 +53,11 @@
#include "arthurwidgets.h"
+#if QT_CONFIG(opengl)
+#include "fbopaintdevice.h"
+#include <QOpenGLTextureBlitter>
+#endif
+
#include <QPainter>
#include <QEvent>
@@ -61,10 +66,6 @@ class QPushButton;
class QRadioButton;
QT_END_NAMESPACE
-#ifdef QT_OPENGL_SUPPORT
-#include <QtOpenGL>
-#endif
-
class CompositionWidget : public QWidget
{
Q_OBJECT
@@ -186,12 +187,13 @@ private:
bool m_animation_enabled;
int m_animationTimer;
-#ifdef QT_OPENGL_SUPPORT
- QGLPixelBuffer *m_pbuffer;
- GLuint m_base_tex;
- GLuint m_compositing_tex;
+#if QT_CONFIG(opengl)
+ QScopedPointer<QFboPaintDevice> m_fbo;
int m_pbuffer_size; // width==height==size of pbuffer
+ uint m_base_tex;
+ uint m_compositing_tex;
QSize m_previous_size;
+ QOpenGLTextureBlitter m_blitter;
#endif
};
diff --git a/examples/widgets/painting/composition/composition.pro b/examples/widgets/painting/composition/composition.pro
index 5fdbe4a5a2..15d8c6e67b 100644
--- a/examples/widgets/painting/composition/composition.pro
+++ b/examples/widgets/painting/composition/composition.pro
@@ -6,10 +6,6 @@ SHARED_FOLDER = ../shared
include($$SHARED_FOLDER/shared.pri)
RESOURCES += composition.qrc
-qtHaveModule(opengl):!qtConfig(dynamicgl) {
- DEFINES += USE_OPENGL
- QT += opengl
-}
QT += widgets
# install
diff --git a/examples/widgets/painting/composition/main.cpp b/examples/widgets/painting/composition/main.cpp
index 1a5dfd3e5e..1f4ead7165 100644
--- a/examples/widgets/painting/composition/main.cpp
+++ b/examples/widgets/painting/composition/main.cpp
@@ -51,17 +51,12 @@
#include "composition.h"
#include <QApplication>
-#ifdef QT_OPENGL_SUPPORT
-#include <QtOpenGL>
-#endif
int main(int argc, char *argv[])
{
- // Q_INIT_RESOURCE(deform);
-
QApplication app(argc, argv);
- CompositionWidget compWidget(0);
+ CompositionWidget compWidget(nullptr);
QStyle *arthurStyle = new ArthurStyle();
compWidget.setStyle(arthurStyle);
diff --git a/examples/widgets/painting/deform/deform.pro b/examples/widgets/painting/deform/deform.pro
index 6409aaed96..498ec57686 100644
--- a/examples/widgets/painting/deform/deform.pro
+++ b/examples/widgets/painting/deform/deform.pro
@@ -7,10 +7,6 @@ include($$SHARED_FOLDER/shared.pri)
RESOURCES += deform.qrc
-qtHaveModule(opengl) {
- DEFINES += QT_OPENGL_SUPPORT
- QT += opengl
-}
QT += widgets
# install
diff --git a/examples/widgets/painting/deform/pathdeform.cpp b/examples/widgets/painting/deform/pathdeform.cpp
index 805804716f..7c3fe45277 100644
--- a/examples/widgets/painting/deform/pathdeform.cpp
+++ b/examples/widgets/painting/deform/pathdeform.cpp
@@ -109,13 +109,11 @@ void PathDeformControls::layoutForDesktop()
QPushButton *showSourceButton = new QPushButton(mainGroup);
showSourceButton->setText(tr("Show Source"));
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(true);
enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
- if (!QGLFormat::hasOpenGL())
- enableOpenGLButton->hide();
#endif
QPushButton *whatsThisButton = new QPushButton(mainGroup);
@@ -132,7 +130,7 @@ void PathDeformControls::layoutForDesktop()
mainGroupLayout->addWidget(textGroup);
mainGroupLayout->addWidget(animateButton);
mainGroupLayout->addStretch(1);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton);
#endif
mainGroupLayout->addWidget(showSourceButton);
@@ -158,7 +156,7 @@ void PathDeformControls::layoutForDesktop()
connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int)));
connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int)));
connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool)));
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
#endif
@@ -201,13 +199,11 @@ void PathDeformControls::layoutForSmallScreen()
QPushButton *animateButton = new QPushButton(tr("Animated"), mainGroup);
animateButton->setCheckable(true);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(mainGroup);
enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
- if (!QGLFormat::hasOpenGL())
- enableOpenGLButton->hide();
#endif
QPushButton *quitButton = new QPushButton(tr("Quit"), mainGroup);
@@ -223,7 +219,7 @@ void PathDeformControls::layoutForSmallScreen()
mainGroupLayout->addWidget(fontSizeLabel, 2, 0, Qt::AlignRight);
mainGroupLayout->addWidget(fontSizeSlider, 2, 1);
mainGroupLayout->addWidget(animateButton, 3,0, 1,2);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton, 4,0, 1,2);
#endif
@@ -239,7 +235,7 @@ void PathDeformControls::layoutForSmallScreen()
connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int)));
connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int)));
connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool)));
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
#endif
@@ -463,7 +459,7 @@ void PathDeformRenderer::timerEvent(QTimerEvent *e)
m_pos.setY(height() - m_radius);
}
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
if (usesOpenGL()) {
update();
} else
@@ -527,7 +523,7 @@ void PathDeformRenderer::mouseMoveEvent(QMouseEvent *e)
m_direction = (m_direction + dir) / 2;
}
m_pos = e->pos() + m_offset;
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
if (usesOpenGL()) {
update();
} else
@@ -620,7 +616,7 @@ void PathDeformRenderer::setRadius(int radius)
m_radius = radius;
generateLensPixmap();
if (!m_animated || m_radius < max) {
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
if (usesOpenGL()){
update();
return;
@@ -634,7 +630,7 @@ void PathDeformRenderer::setIntensity(int intensity)
{
m_intensity = intensity;
if (!m_animated) {
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
if (usesOpenGL()) {
update();
return;
diff --git a/examples/widgets/painting/gradients/gradients.cpp b/examples/widgets/painting/gradients/gradients.cpp
index 6d9f514a8d..004f6710cd 100644
--- a/examples/widgets/painting/gradients/gradients.cpp
+++ b/examples/widgets/painting/gradients/gradients.cpp
@@ -317,13 +317,11 @@ GradientWidget::GradientWidget(QWidget *parent)
QPushButton *showSourceButton = new QPushButton(mainGroup);
showSourceButton->setText(tr("Show Source"));
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(true);
enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
- if (!QGLFormat::hasOpenGL())
- enableOpenGLButton->hide();
#endif
QPushButton *whatsThisButton = new QPushButton(mainGroup);
whatsThisButton->setText(tr("What's This?"));
@@ -343,7 +341,7 @@ GradientWidget::GradientWidget(QWidget *parent)
mainGroupLayout->addWidget(defaultsGroup);
mainGroupLayout->addStretch(1);
mainGroupLayout->addWidget(showSourceButton);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton);
#endif
mainGroupLayout->addWidget(whatsThisButton);
@@ -406,7 +404,7 @@ GradientWidget::GradientWidget(QWidget *parent)
connect(showSourceButton, &QPushButton::clicked,
m_renderer, &GradientRenderer::showSource);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
connect(enableOpenGLButton, QOverload<bool>::of(&QPushButton::clicked),
m_renderer, &ArthurFrame::enableOpenGL);
#endif
diff --git a/examples/widgets/painting/gradients/gradients.pro b/examples/widgets/painting/gradients/gradients.pro
index 73f3974c62..14eccb6500 100644
--- a/examples/widgets/painting/gradients/gradients.pro
+++ b/examples/widgets/painting/gradients/gradients.pro
@@ -6,10 +6,6 @@ SHARED_FOLDER = ../shared
include($$SHARED_FOLDER/shared.pri)
RESOURCES += gradients.qrc
-qtHaveModule(opengl) {
- DEFINES += QT_OPENGL_SUPPORT
- QT += opengl
-}
QT += widgets
# install
diff --git a/examples/widgets/painting/pathstroke/pathstroke.cpp b/examples/widgets/painting/pathstroke/pathstroke.cpp
index 5a7b8fd9fe..b04998afac 100644
--- a/examples/widgets/painting/pathstroke/pathstroke.cpp
+++ b/examples/widgets/painting/pathstroke/pathstroke.cpp
@@ -211,13 +211,11 @@ void PathStrokeControls::layoutForDesktop()
QPushButton *showSourceButton = new QPushButton(mainGroup);
showSourceButton->setText(tr("Show Source"));
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(mainGroup);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(true);
enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
- if (!QGLFormat::hasOpenGL())
- enableOpenGLButton->hide();
#endif
QPushButton *whatsThisButton = new QPushButton(mainGroup);
whatsThisButton->setText(tr("What's This?"));
@@ -242,7 +240,7 @@ void PathStrokeControls::layoutForDesktop()
mainGroupLayout->addWidget(animated);
mainGroupLayout->addStretch(1);
mainGroupLayout->addWidget(showSourceButton);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
mainGroupLayout->addWidget(enableOpenGLButton);
#endif
mainGroupLayout->addWidget(whatsThisButton);
@@ -254,7 +252,7 @@ void PathStrokeControls::layoutForDesktop()
connect(penWidth, SIGNAL(valueChanged(int)), m_renderer, SLOT(setPenWidth(int)));
connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource()));
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
#endif
connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool)));
@@ -290,13 +288,11 @@ void PathStrokeControls::layoutForSmallScreens()
penWidth->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
penWidth->setRange(0, 500);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
QPushButton *enableOpenGLButton = new QPushButton(this);
enableOpenGLButton->setText(tr("Use OpenGL"));
enableOpenGLButton->setCheckable(true);
enableOpenGLButton->setChecked(m_renderer->usesOpenGL());
- if (!QGLFormat::hasOpenGL())
- enableOpenGLButton->hide();
#endif
// Layouts:
@@ -307,7 +303,7 @@ void PathStrokeControls::layoutForSmallScreens()
QVBoxLayout *leftLayout = new QVBoxLayout(0);
leftLayout->addWidget(m_capGroup);
leftLayout->addWidget(m_joinGroup);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
leftLayout->addWidget(enableOpenGLButton);
#endif
leftLayout->addLayout(penWidthLayout);
@@ -330,7 +326,7 @@ void PathStrokeControls::layoutForSmallScreens()
mainLayout->addWidget(quitBtn, 2, 1, Qt::AlignHCenter | Qt::AlignTop);
mainLayout->addWidget(okBtn, 2, 2, Qt::AlignHCenter | Qt::AlignTop);
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool)));
#endif
diff --git a/examples/widgets/painting/pathstroke/pathstroke.pro b/examples/widgets/painting/pathstroke/pathstroke.pro
index 8ab3cb9244..3e71b2db56 100644
--- a/examples/widgets/painting/pathstroke/pathstroke.pro
+++ b/examples/widgets/painting/pathstroke/pathstroke.pro
@@ -7,10 +7,6 @@ include($$SHARED_FOLDER/shared.pri)
RESOURCES += pathstroke.qrc
-qtHaveModule(opengl) {
- DEFINES += QT_OPENGL_SUPPORT
- QT += opengl
-}
QT += widgets
# install
diff --git a/examples/widgets/painting/shared/arthurwidgets.cpp b/examples/widgets/painting/shared/arthurwidgets.cpp
index 965660a3a3..442fb69ac1 100644
--- a/examples/widgets/painting/shared/arthurwidgets.cpp
+++ b/examples/widgets/painting/shared/arthurwidgets.cpp
@@ -60,6 +60,10 @@
#include <QTextBrowser>
#include <QBoxLayout>
#include <QRegularExpression>
+#include <QOffscreenSurface>
+#include <QOpenGLContext>
+#include <QOpenGLPaintDevice>
+#include <QOpenGLWindow>
extern QPixmap cached(const QString &img);
@@ -67,17 +71,12 @@ ArthurFrame::ArthurFrame(QWidget *parent)
: QWidget(parent)
, m_prefer_image(false)
{
-#ifdef QT_OPENGL_SUPPORT
- glw = 0;
+#if QT_CONFIG(opengl)
+ m_glWindow = nullptr;
+ m_glWidget = nullptr;
m_use_opengl = false;
- QGLFormat f = QGLFormat::defaultFormat();
- f.setSampleBuffers(true);
- f.setStencil(true);
- f.setAlpha(true);
- f.setAlphaBufferSize(8);
- QGLFormat::setDefaultFormat(f);
#endif
- m_document = 0;
+ m_document = nullptr;
m_show_doc = false;
m_tile = QPixmap(128, 128);
@@ -94,37 +93,55 @@ ArthurFrame::ArthurFrame(QWidget *parent)
}
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
void ArthurFrame::enableOpenGL(bool use_opengl)
{
if (m_use_opengl == use_opengl)
return;
- if (!glw && use_opengl) {
- glw = new GLWidget(this);
- glw->setAutoFillBackground(false);
- glw->disableAutoBufferSwap();
+ m_use_opengl = use_opengl;
+
+ if (!m_glWindow && use_opengl) {
+ createGlWindow();
QApplication::postEvent(this, new QResizeEvent(size(), size()));
}
- m_use_opengl = use_opengl;
if (use_opengl) {
- glw->show();
+ m_glWidget->show();
} else {
- if (glw)
- glw->hide();
+ if (m_glWidget)
+ m_glWidget->hide();
}
update();
}
+
+void ArthurFrame::createGlWindow()
+{
+ Q_ASSERT(m_use_opengl);
+
+ m_glWindow = new QOpenGLWindow();
+ QSurfaceFormat f = QSurfaceFormat::defaultFormat();
+ f.setSamples(4);
+ f.setAlphaBufferSize(8);
+ f.setStencilBufferSize(8);
+ m_glWindow->setFormat(f);
+ m_glWindow->setFlags(Qt::WindowTransparentForInput);
+ m_glWindow->resize(width() - 1, height() - 1);
+ m_glWindow->create();
+ m_glWidget = QWidget::createWindowContainer(m_glWindow, this);
+}
#endif
+
void ArthurFrame::paintEvent(QPaintEvent *e)
{
static QImage *static_image = 0;
+
QPainter painter;
+
if (preferImage()
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
&& !m_use_opengl
#endif
) {
@@ -142,10 +159,12 @@ void ArthurFrame::paintEvent(QPaintEvent *e)
painter.fillRect(0, height() - o, o, o, bg);
painter.fillRect(width() - o, height() - o, o, o, bg);
} else {
-#ifdef QT_OPENGL_SUPPORT
- if (m_use_opengl) {
- painter.begin(glw);
- painter.fillRect(QRectF(0, 0, glw->width(), glw->height()), palette().color(backgroundRole()));
+#if QT_CONFIG(opengl)
+ if (m_use_opengl && m_glWindow->isValid()) {
+ m_glWindow->makeCurrent();
+
+ painter.begin(m_glWindow);
+ painter.fillRect(QRectF(0, 0, m_glWindow->width(), m_glWindow->height()), palette().color(backgroundRole()));
} else {
painter.begin(this);
}
@@ -196,7 +215,7 @@ void ArthurFrame::paintEvent(QPaintEvent *e)
painter.drawPath(clipPath);
if (preferImage()
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
&& !m_use_opengl
#endif
) {
@@ -204,18 +223,17 @@ void ArthurFrame::paintEvent(QPaintEvent *e)
painter.begin(this);
painter.drawImage(e->rect(), *static_image, e->rect());
}
-
-#ifdef QT_OPENGL_SUPPORT
- if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
- glw->swapBuffers();
+#if QT_CONFIG(opengl)
+ if (m_use_opengl)
+ m_glWindow->update();
#endif
}
void ArthurFrame::resizeEvent(QResizeEvent *e)
{
-#ifdef QT_OPENGL_SUPPORT
- if (glw)
- glw->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
+#if QT_CONFIG(opengl)
+ if (m_glWidget)
+ m_glWidget->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
#endif
QWidget::resizeEvent(e);
}
diff --git a/examples/widgets/painting/shared/arthurwidgets.h b/examples/widgets/painting/shared/arthurwidgets.h
index d6e1e44b3a..73e1310c0e 100644
--- a/examples/widgets/painting/shared/arthurwidgets.h
+++ b/examples/widgets/painting/shared/arthurwidgets.h
@@ -56,42 +56,13 @@
#include <QPushButton>
#include <QGroupBox>
-#if defined(QT_OPENGL_SUPPORT)
-#include <QGLWidget>
-#include <QEvent>
-class GLWidget : public QGLWidget
-{
-public:
- GLWidget(QWidget *parent)
- : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
- {
- setAttribute(Qt::WA_AcceptTouchEvents);
- }
- void disableAutoBufferSwap() { setAutoBufferSwap(false); }
- void paintEvent(QPaintEvent *) override { parentWidget()->update(); }
-protected:
- bool event(QEvent *event) override
- {
- switch (event->type()) {
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- event->ignore();
- return false;
- break;
- default:
- break;
- }
- return QGLWidget::event(event);
- }
-};
-#endif
-
+QT_FORWARD_DECLARE_CLASS(QOpenGLWindow)
QT_FORWARD_DECLARE_CLASS(QTextDocument)
QT_FORWARD_DECLARE_CLASS(QTextEdit)
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
class ArthurFrame : public QWidget
+
{
Q_OBJECT
public:
@@ -107,9 +78,8 @@ public:
void loadSourceFile(const QString &fileName);
bool preferImage() const { return m_prefer_image; }
-
-#if defined(QT_OPENGL_SUPPORT)
- QGLWidget *glWidget() const { return glw; }
+#if QT_CONFIG(opengl)
+ QOpenGLWindow *glWindow() const { return m_glWindow; }
#endif
public slots:
@@ -117,7 +87,7 @@ public slots:
void setDescriptionEnabled(bool enabled);
void showSource();
-#if defined(QT_OPENGL_SUPPORT)
+#if QT_CONFIG(opengl)
void enableOpenGL(bool use_opengl);
bool usesOpenGL() { return m_use_opengl; }
#endif
@@ -129,8 +99,10 @@ protected:
void paintEvent(QPaintEvent *) override;
void resizeEvent(QResizeEvent *) override;
-#if defined(QT_OPENGL_SUPPORT)
- GLWidget *glw;
+#if QT_CONFIG(opengl)
+ virtual void createGlWindow();
+ QOpenGLWindow *m_glWindow;
+ QWidget *m_glWidget;
bool m_use_opengl;
#endif
QPixmap m_tile;
diff --git a/examples/widgets/painting/shared/fbopaintdevice.cpp b/examples/widgets/painting/shared/fbopaintdevice.cpp
new file mode 100644
index 0000000000..8207090cc8
--- /dev/null
+++ b/examples/widgets/painting/shared/fbopaintdevice.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "fbopaintdevice.h"
+
+#include <QOffscreenSurface>
+#include <QOpenGLFunctions>
+
+QFboPaintDevice::QFboPaintDevice(const QSize& size, bool flipped, bool clearOnInit,
+ QOpenGLFramebufferObject::Attachment attachment)
+ : QOpenGLPaintDevice(size)
+{
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(attachment);
+ format.setSamples(4);
+ m_framebufferObject = new QOpenGLFramebufferObject(size, format);
+ QOffscreenSurface *surface = new QOffscreenSurface();
+ surface->create();
+ m_surface = surface;
+ setPaintFlipped(flipped);
+ if (clearOnInit) {
+ m_framebufferObject->bind();
+
+ context()->functions()->glClearColor(0, 0, 0, 0);
+ context()->functions()->glClear(GL_COLOR_BUFFER_BIT);
+ }
+}
+
+QFboPaintDevice::~QFboPaintDevice()
+{
+ delete m_framebufferObject;
+ delete m_surface;
+}
+
+void QFboPaintDevice::ensureActiveTarget()
+{
+ if (QOpenGLContext::currentContext() != context())
+ context()->makeCurrent(m_surface);
+
+ m_framebufferObject->bind();
+}
+
+GLuint QFboPaintDevice::takeTexture()
+{
+ // We have multisamples so we can't just forward takeTexture().
+ QOpenGLFramebufferObject resolvedFbo(m_framebufferObject->size(), m_framebufferObject->attachment());
+ QOpenGLFramebufferObject::blitFramebuffer(&resolvedFbo, m_framebufferObject);
+ return resolvedFbo.takeTexture();
+}
+
+QImage QFboPaintDevice::toImage() const
+{
+ QOpenGLContext* currentContext = QOpenGLContext::currentContext();
+ QSurface* currentSurface = currentContext ? currentContext->surface() : 0;
+
+ context()->makeCurrent(m_surface);
+
+ QImage image = m_framebufferObject->toImage(!paintFlipped());
+
+ if (currentContext)
+ currentContext->makeCurrent(currentSurface);
+ else
+ context()->doneCurrent();
+
+ return image;
+}
diff --git a/examples/widgets/painting/shared/fbopaintdevice.h b/examples/widgets/painting/shared/fbopaintdevice.h
new file mode 100644
index 0000000000..78451af895
--- /dev/null
+++ b/examples/widgets/painting/shared/fbopaintdevice.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFBOPAINTDEVICE_H
+#define QFBOPAINTDEVICE_H
+
+#ifndef QT_NO_OPENGL
+
+#include <QImage>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLPaintDevice>
+#include <QSurface>
+
+class QFboPaintDevice : public QOpenGLPaintDevice {
+public:
+ QFboPaintDevice(const QSize&, bool flipped = false, bool clearOnInit = true,
+ QOpenGLFramebufferObject::Attachment = QOpenGLFramebufferObject::CombinedDepthStencil);
+ ~QFboPaintDevice();
+
+ // QOpenGLPaintDevice:
+ void ensureActiveTarget() override;
+
+ bool isValid() const { return m_framebufferObject->isValid(); }
+ GLuint handle() const { return m_framebufferObject->handle(); }
+ GLuint takeTexture();
+ QImage toImage() const;
+
+ bool bind() { return m_framebufferObject->bind(); }
+ bool release() { return m_framebufferObject->release(); }
+ QSize size() const { return m_framebufferObject->size(); }
+
+ QOpenGLFramebufferObject* framebufferObject() { return m_framebufferObject; }
+ const QOpenGLFramebufferObject* framebufferObject() const { return m_framebufferObject; }
+
+ static bool isSupported() { return QOpenGLFramebufferObject::hasOpenGLFramebufferObjects(); }
+
+private:
+ QOpenGLFramebufferObject *m_framebufferObject;
+ QSurface* m_surface;
+};
+
+#endif // QT_NO_OPENGL
+
+#endif // QFBOPAINTDEVICE_H
diff --git a/examples/widgets/painting/shared/hoverpoints.cpp b/examples/widgets/painting/shared/hoverpoints.cpp
index c735c83f6a..7cd8cc0b29 100644
--- a/examples/widgets/painting/shared/hoverpoints.cpp
+++ b/examples/widgets/painting/shared/hoverpoints.cpp
@@ -48,10 +48,6 @@
**
****************************************************************************/
-#ifdef QT_OPENGL_SUPPORT
-#include <QGLWidget>
-#endif
-
#include "arthurwidgets.h"
#include "hoverpoints.h"
@@ -269,11 +265,6 @@ bool HoverPoints::eventFilter(QObject *object, QEvent *event)
QApplication::sendEvent(object, event);
m_widget = that_widget;
paintPoints();
-#ifdef QT_OPENGL_SUPPORT
- ArthurFrame *af = qobject_cast<ArthurFrame *>(that_widget);
- if (af && af->usesOpenGL())
- af->glWidget()->swapBuffers();
-#endif
return true;
}
default:
@@ -288,12 +279,14 @@ bool HoverPoints::eventFilter(QObject *object, QEvent *event)
void HoverPoints::paintPoints()
{
QPainter p;
-#ifdef QT_OPENGL_SUPPORT
+#if QT_CONFIG(opengl)
ArthurFrame *af = qobject_cast<ArthurFrame *>(m_widget);
- if (af && af->usesOpenGL())
- p.begin(af->glWidget());
- else
+ if (af && af->usesOpenGL() && af->glWindow()->isValid()) {
+ af->glWindow()->makeCurrent();
+ p.begin(af->glWindow());
+ } else {
p.begin(m_widget);
+ }
#else
p.begin(m_widget);
#endif
diff --git a/examples/widgets/painting/shared/shared.pri b/examples/widgets/painting/shared/shared.pri
index 362cc6819c..cb08b00348 100644
--- a/examples/widgets/painting/shared/shared.pri
+++ b/examples/widgets/painting/shared/shared.pri
@@ -1,8 +1,8 @@
INCLUDEPATH += $$PWD
-qtHaveModule(opengl)|qtConfig(opengles2) {
- DEFINES += QT_OPENGL_SUPPORT
- QT += opengl widgets
+qtConfig(opengl) {
+ SOURCES += $$PWD/fbopaintdevice.cpp
+ HEADERS += $$PWD/fbopaintdevice.h
}
SOURCES += \