From 0ead3b7142e47b89059af689de4ede47075375be Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 11 Jul 2018 15:12:56 +0200 Subject: Move arthurwidget based examples to new QOpenGL classes Several of the examples were not even working besides using deprecated classes. Change-Id: I352e0629d490593edcc5868d2ec5a8ff222eaeab Reviewed-by: Laszlo Agocs --- examples/widgets/painting/shared/arthurwidgets.cpp | 80 +++++++++------ examples/widgets/painting/shared/arthurwidgets.h | 46 ++------- .../widgets/painting/shared/fbopaintdevice.cpp | 113 +++++++++++++++++++++ examples/widgets/painting/shared/fbopaintdevice.h | 91 +++++++++++++++++ examples/widgets/painting/shared/hoverpoints.cpp | 19 ++-- examples/widgets/painting/shared/shared.pri | 6 +- 6 files changed, 271 insertions(+), 84 deletions(-) create mode 100644 examples/widgets/painting/shared/fbopaintdevice.cpp create mode 100644 examples/widgets/painting/shared/fbopaintdevice.h (limited to 'examples/widgets/painting/shared') 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 #include #include +#include +#include +#include +#include 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 #include -#if defined(QT_OPENGL_SUPPORT) -#include -#include -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 +#include + +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 +#include +#include +#include + +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 -#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(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(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 += \ -- cgit v1.2.3