2011-04-27 10:05:43 +00:00
|
|
|
/****************************************************************************
|
2014-08-02 17:42:15 +00:00
|
|
|
**
|
2016-01-22 12:24:00 +00:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2014-08-02 17:42:15 +00:00
|
|
|
**
|
|
|
|
** This file is part of the examples of the Qt Toolkit.
|
|
|
|
**
|
|
|
|
** $QT_BEGIN_LICENSE:BSD$
|
2016-01-22 12:24:00 +00:00
|
|
|
** 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:
|
2014-08-02 17:42:15 +00:00
|
|
|
**
|
|
|
|
** "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.
|
2015-02-13 11:15:33 +00:00
|
|
|
** * 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.
|
2014-08-02 17:42:15 +00:00
|
|
|
**
|
|
|
|
**
|
|
|
|
** 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$
|
|
|
|
**
|
|
|
|
****************************************************************************/
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
#include "glwidget.h"
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QPaintEngine>
|
2014-08-02 17:42:15 +00:00
|
|
|
#include <QOpenGLShaderProgram>
|
|
|
|
#include <QOpenGLTexture>
|
2017-04-14 04:13:52 +00:00
|
|
|
#include <QRandomGenerator>
|
2014-08-02 17:42:15 +00:00
|
|
|
#include <QCoreApplication>
|
2017-03-22 12:18:52 +00:00
|
|
|
#include <qmath.h>
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-06-20 09:58:34 +00:00
|
|
|
#include "mainwindow.h"
|
2011-04-27 10:05:43 +00:00
|
|
|
#include "bubble.h"
|
|
|
|
|
|
|
|
const int bubbleNum = 8;
|
|
|
|
|
2017-02-20 14:19:49 +00:00
|
|
|
#ifndef GL_SRGB8_ALPHA8
|
|
|
|
#define GL_SRGB8_ALPHA8 0x8C43
|
|
|
|
#endif
|
|
|
|
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
GLWidget::GLWidget(MainWindow *maybeMainWindow, const QColor &background)
|
|
|
|
: m_mainWindow(maybeMainWindow),
|
2014-06-20 09:58:34 +00:00
|
|
|
m_background(background)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
|
|
|
setMinimumSize(300, 250);
|
2017-02-20 14:19:49 +00:00
|
|
|
if (QCoreApplication::arguments().contains(QStringLiteral("--srgb")))
|
|
|
|
setTextureFormat(GL_SRGB8_ALPHA8);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GLWidget::~GLWidget()
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::reset()
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
qDeleteAll(m_bubbles);
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
// Leave everything in a state suitable for a subsequent call to
|
|
|
|
// initialize(). This matters when coming from the context's
|
|
|
|
// aboutToBeDestroyed signal, would not matter when invoked from the
|
|
|
|
// destructor.
|
|
|
|
m_bubbles.clear();
|
2014-08-02 17:42:15 +00:00
|
|
|
|
|
|
|
// And now release all OpenGL resources.
|
|
|
|
makeCurrent();
|
|
|
|
delete m_texture;
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_texture = nullptr;
|
2014-08-02 17:42:15 +00:00
|
|
|
delete m_program1;
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_program1 = nullptr;
|
2014-08-02 17:42:15 +00:00
|
|
|
delete m_program2;
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_program2 = nullptr;
|
2014-08-02 17:42:15 +00:00
|
|
|
delete m_vshader1;
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_vshader1 = nullptr;
|
2014-08-02 17:42:15 +00:00
|
|
|
delete m_fshader1;
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_fshader1 = nullptr;
|
2014-08-02 17:42:15 +00:00
|
|
|
delete m_vshader2;
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_vshader2 = nullptr;
|
2014-08-02 17:42:15 +00:00
|
|
|
delete m_fshader2;
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_fshader2 = nullptr;
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vbo1.destroy();
|
|
|
|
m_vbo2.destroy();
|
|
|
|
doneCurrent();
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
|
|
|
|
// We are done with the current QOpenGLContext, forget it. If there is a
|
|
|
|
// subsequent initialize(), that will then connect to the new context.
|
|
|
|
QObject::disconnect(m_contextWatchConnection);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
void GLWidget::setScaling(int scale)
|
|
|
|
{
|
2014-06-20 09:58:34 +00:00
|
|
|
if (scale > 30)
|
|
|
|
m_fScale = 1 + qreal(scale - 30) / 30 * 0.25;
|
|
|
|
else if (scale < 30)
|
|
|
|
m_fScale = 1 - (qreal(30 - scale) / 30 * 0.25);
|
2013-03-14 23:42:15 +00:00
|
|
|
else
|
2014-08-02 17:42:15 +00:00
|
|
|
m_fScale = 1;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
void GLWidget::setLogo()
|
|
|
|
{
|
|
|
|
m_qtLogo = true;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
void GLWidget::setTexture()
|
|
|
|
{
|
|
|
|
m_qtLogo = false;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
void GLWidget::setShowBubbles(bool bubbles)
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
m_showBubbles = bubbles;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::paintQtLogo()
|
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
m_program1->enableAttributeArray(m_vertexAttr1);
|
|
|
|
m_program1->enableAttributeArray(m_normalAttr1);
|
|
|
|
|
|
|
|
m_vbo1.bind();
|
|
|
|
// The data in the buffer is placed like this:
|
|
|
|
// vertex1.x, vertex1.y, vertex1.z, normal1.x, normal1.y, normal1.z, vertex2.x, ...
|
|
|
|
m_program1->setAttributeBuffer(m_vertexAttr1, GL_FLOAT, 0, 3, 6 * sizeof(GLfloat));
|
|
|
|
m_program1->setAttributeBuffer(m_normalAttr1, GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat));
|
|
|
|
m_vbo1.release();
|
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
|
|
|
|
|
|
|
|
m_program1->disableAttributeArray(m_normalAttr1);
|
|
|
|
m_program1->disableAttributeArray(m_vertexAttr1);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::paintTexturedCube()
|
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
m_texture->bind();
|
|
|
|
|
|
|
|
if (!m_vbo2.isCreated()) {
|
|
|
|
static GLfloat afVertices[] = {
|
|
|
|
-0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
|
|
|
|
0.5, -0.5, 0.5, -0.5,0.5,0.5,0.5,0.5,0.5,
|
|
|
|
-0.5, -0.5, -0.5, 0.5,-0.5,-0.5,-0.5,0.5,-0.5,
|
|
|
|
0.5, 0.5, -0.5, -0.5,0.5,-0.5,0.5,-0.5,-0.5,
|
|
|
|
|
|
|
|
0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
|
|
|
|
0.5, 0.5, 0.5, 0.5,0.5,-0.5,0.5,-0.5,0.5,
|
|
|
|
-0.5, 0.5, -0.5, -0.5,-0.5,0.5,-0.5,-0.5,-0.5,
|
|
|
|
-0.5, -0.5, 0.5, -0.5,0.5,-0.5,-0.5,0.5,0.5,
|
|
|
|
|
|
|
|
0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5,
|
|
|
|
-0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5,
|
|
|
|
-0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
|
|
|
|
0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5
|
|
|
|
};
|
|
|
|
|
|
|
|
static GLfloat afTexCoord[] = {
|
|
|
|
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
|
|
|
|
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
|
|
|
|
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
|
|
|
|
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
|
|
|
|
|
|
|
|
1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
|
|
|
|
0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
|
|
|
|
0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
|
|
|
|
1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
|
|
|
|
|
|
|
|
0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
|
|
|
|
1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
|
|
|
|
1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
|
|
|
|
0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
|
|
|
|
};
|
|
|
|
|
|
|
|
GLfloat afNormals[] = {
|
|
|
|
|
|
|
|
0,0,-1, 0,0,-1, 0,0,-1,
|
|
|
|
0,0,-1, 0,0,-1, 0,0,-1,
|
|
|
|
0,0,1, 0,0,1, 0,0,1,
|
|
|
|
0,0,1, 0,0,1, 0,0,1,
|
|
|
|
|
|
|
|
-1,0,0, -1,0,0, -1,0,0,
|
|
|
|
-1,0,0, -1,0,0, -1,0,0,
|
|
|
|
1,0,0, 1,0,0, 1,0,0,
|
|
|
|
1,0,0, 1,0,0, 1,0,0,
|
|
|
|
|
|
|
|
0,-1,0, 0,-1,0, 0,-1,0,
|
|
|
|
0,-1,0, 0,-1,0, 0,-1,0,
|
|
|
|
0,1,0, 0,1,0, 0,1,0,
|
|
|
|
0,1,0, 0,1,0, 0,1,0
|
|
|
|
};
|
|
|
|
|
|
|
|
m_vbo2.create();
|
|
|
|
m_vbo2.bind();
|
|
|
|
m_vbo2.allocate(36 * 8 * sizeof(GLfloat));
|
|
|
|
m_vbo2.write(0, afVertices, sizeof(afVertices));
|
|
|
|
m_vbo2.write(sizeof(afVertices), afTexCoord, sizeof(afTexCoord));
|
|
|
|
m_vbo2.write(sizeof(afVertices) + sizeof(afTexCoord), afNormals, sizeof(afNormals));
|
|
|
|
m_vbo2.release();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_program2->setUniformValue(m_textureUniform2, 0); // use texture unit 0
|
|
|
|
|
|
|
|
m_program2->enableAttributeArray(m_vertexAttr2);
|
|
|
|
m_program2->enableAttributeArray(m_normalAttr2);
|
|
|
|
m_program2->enableAttributeArray(m_texCoordAttr2);
|
|
|
|
|
|
|
|
m_vbo2.bind();
|
|
|
|
// In the buffer we first have 36 vertices (3 floats for each), then 36 texture
|
|
|
|
// coordinates (2 floats for each), then 36 normals (3 floats for each).
|
|
|
|
m_program2->setAttributeBuffer(m_vertexAttr2, GL_FLOAT, 0, 3);
|
|
|
|
m_program2->setAttributeBuffer(m_texCoordAttr2, GL_FLOAT, 36 * 3 * sizeof(GLfloat), 2);
|
|
|
|
m_program2->setAttributeBuffer(m_normalAttr2, GL_FLOAT, 36 * 5 * sizeof(GLfloat), 3);
|
|
|
|
m_vbo2.release();
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_program2->disableAttributeArray(m_vertexAttr2);
|
|
|
|
m_program2->disableAttributeArray(m_normalAttr2);
|
|
|
|
m_program2->disableAttributeArray(m_texCoordAttr2);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
void GLWidget::initializeGL()
|
2011-04-27 10:05:43 +00:00
|
|
|
{
|
2014-04-24 12:36:57 +00:00
|
|
|
initializeOpenGLFunctions();
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_texture = new QOpenGLTexture(QImage(":/qt.png"));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vshader1 = new QOpenGLShader(QOpenGLShader::Vertex);
|
2011-04-27 10:05:43 +00:00
|
|
|
const char *vsrc1 =
|
|
|
|
"attribute highp vec4 vertex;\n"
|
|
|
|
"attribute mediump vec3 normal;\n"
|
|
|
|
"uniform mediump mat4 matrix;\n"
|
|
|
|
"varying mediump vec4 color;\n"
|
|
|
|
"void main(void)\n"
|
|
|
|
"{\n"
|
|
|
|
" vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
|
|
|
|
" float angle = max(dot(normal, toLight), 0.0);\n"
|
|
|
|
" vec3 col = vec3(0.40, 1.0, 0.0);\n"
|
|
|
|
" color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n"
|
|
|
|
" color = clamp(color, 0.0, 1.0);\n"
|
|
|
|
" gl_Position = matrix * vertex;\n"
|
|
|
|
"}\n";
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vshader1->compileSourceCode(vsrc1);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_fshader1 = new QOpenGLShader(QOpenGLShader::Fragment);
|
2011-04-27 10:05:43 +00:00
|
|
|
const char *fsrc1 =
|
|
|
|
"varying mediump vec4 color;\n"
|
|
|
|
"void main(void)\n"
|
|
|
|
"{\n"
|
|
|
|
" gl_FragColor = color;\n"
|
|
|
|
"}\n";
|
2014-08-02 17:42:15 +00:00
|
|
|
m_fshader1->compileSourceCode(fsrc1);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_program1 = new QOpenGLShaderProgram;
|
|
|
|
m_program1->addShader(m_vshader1);
|
|
|
|
m_program1->addShader(m_fshader1);
|
|
|
|
m_program1->link();
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertexAttr1 = m_program1->attributeLocation("vertex");
|
|
|
|
m_normalAttr1 = m_program1->attributeLocation("normal");
|
|
|
|
m_matrixUniform1 = m_program1->uniformLocation("matrix");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vshader2 = new QOpenGLShader(QOpenGLShader::Vertex);
|
2011-04-27 10:05:43 +00:00
|
|
|
const char *vsrc2 =
|
|
|
|
"attribute highp vec4 vertex;\n"
|
|
|
|
"attribute highp vec4 texCoord;\n"
|
|
|
|
"attribute mediump vec3 normal;\n"
|
|
|
|
"uniform mediump mat4 matrix;\n"
|
|
|
|
"varying highp vec4 texc;\n"
|
|
|
|
"varying mediump float angle;\n"
|
|
|
|
"void main(void)\n"
|
|
|
|
"{\n"
|
|
|
|
" vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
|
|
|
|
" angle = max(dot(normal, toLight), 0.0);\n"
|
|
|
|
" gl_Position = matrix * vertex;\n"
|
|
|
|
" texc = texCoord;\n"
|
|
|
|
"}\n";
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vshader2->compileSourceCode(vsrc2);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_fshader2 = new QOpenGLShader(QOpenGLShader::Fragment);
|
2011-04-27 10:05:43 +00:00
|
|
|
const char *fsrc2 =
|
|
|
|
"varying highp vec4 texc;\n"
|
|
|
|
"uniform sampler2D tex;\n"
|
|
|
|
"varying mediump float angle;\n"
|
|
|
|
"void main(void)\n"
|
|
|
|
"{\n"
|
|
|
|
" highp vec3 color = texture2D(tex, texc.st).rgb;\n"
|
|
|
|
" color = color * 0.2 + color * 0.8 * angle;\n"
|
|
|
|
" gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0);\n"
|
|
|
|
"}\n";
|
2014-08-02 17:42:15 +00:00
|
|
|
m_fshader2->compileSourceCode(fsrc2);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_program2 = new QOpenGLShaderProgram;
|
|
|
|
m_program2->addShader(m_vshader2);
|
|
|
|
m_program2->addShader(m_fshader2);
|
|
|
|
m_program2->link();
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertexAttr2 = m_program2->attributeLocation("vertex");
|
|
|
|
m_normalAttr2 = m_program2->attributeLocation("normal");
|
|
|
|
m_texCoordAttr2 = m_program2->attributeLocation("texCoord");
|
|
|
|
m_matrixUniform2 = m_program2->uniformLocation("matrix");
|
|
|
|
m_textureUniform2 = m_program2->uniformLocation("tex");
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
m_fAngle = 0;
|
|
|
|
m_fScale = 1;
|
2014-08-02 17:42:15 +00:00
|
|
|
|
2011-04-27 10:05:43 +00:00
|
|
|
createGeometry();
|
2014-08-02 17:42:15 +00:00
|
|
|
|
|
|
|
// Use a vertex buffer object. Client-side pointers are old-school and should be avoided.
|
|
|
|
m_vbo1.create();
|
|
|
|
m_vbo1.bind();
|
|
|
|
// For the cube all the data belonging to the texture coordinates and
|
|
|
|
// normals is placed separately, after the vertices. Here, for the Qt logo,
|
|
|
|
// let's do something different and potentially more efficient: create a
|
|
|
|
// properly interleaved data set.
|
|
|
|
const int vertexCount = m_vertices.count();
|
2020-06-22 08:12:38 +00:00
|
|
|
QList<GLfloat> buf;
|
2014-08-02 17:42:15 +00:00
|
|
|
buf.resize(vertexCount * 3 * 2);
|
|
|
|
GLfloat *p = buf.data();
|
|
|
|
for (int i = 0; i < vertexCount; ++i) {
|
|
|
|
*p++ = m_vertices[i].x();
|
|
|
|
*p++ = m_vertices[i].y();
|
|
|
|
*p++ = m_vertices[i].z();
|
|
|
|
*p++ = m_normals[i].x();
|
|
|
|
*p++ = m_normals[i].y();
|
|
|
|
*p++ = m_normals[i].z();
|
|
|
|
}
|
|
|
|
m_vbo1.allocate(buf.constData(), buf.count() * sizeof(GLfloat));
|
|
|
|
m_vbo1.release();
|
|
|
|
|
|
|
|
createBubbles(bubbleNum - m_bubbles.count());
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
|
|
|
|
// A well-behaved QOpenGLWidget releases OpenGL resources not only upon
|
|
|
|
// destruction, but also when the associated OpenGL context disappears. If
|
|
|
|
// the widget continues to exist, the context's destruction will be
|
|
|
|
// followed by a call to initialize(). This is not strictly mandatory in
|
|
|
|
// widgets that never change their parents.
|
|
|
|
m_contextWatchConnection = QObject::connect(context(), &QOpenGLContext::aboutToBeDestroyed, context(), [this] { reset(); });
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::paintGL()
|
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
createBubbles(bubbleNum - m_bubbles.count());
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QPainter painter;
|
|
|
|
painter.begin(this);
|
|
|
|
|
|
|
|
painter.beginNativePainting();
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
glClearColor(m_background.redF(), m_background.greenF(), m_background.blueF(), m_transparent ? 0.0f : 1.0f);
|
2011-04-27 10:05:43 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
|
|
|
glFrontFace(GL_CW);
|
|
|
|
glCullFace(GL_FRONT);
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
QMatrix4x4 modelview;
|
|
|
|
modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f);
|
|
|
|
modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f);
|
|
|
|
modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f);
|
|
|
|
modelview.scale(m_fScale);
|
|
|
|
modelview.translate(0.0f, -0.2f, 0.0f);
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
if (m_qtLogo) {
|
|
|
|
m_program1->bind();
|
|
|
|
m_program1->setUniformValue(m_matrixUniform1, modelview);
|
2011-04-27 10:05:43 +00:00
|
|
|
paintQtLogo();
|
2014-08-02 17:42:15 +00:00
|
|
|
m_program1->release();
|
2011-04-27 10:05:43 +00:00
|
|
|
} else {
|
2014-08-02 17:42:15 +00:00
|
|
|
m_program2->bind();
|
|
|
|
m_program2->setUniformValue(m_matrixUniform2, modelview);
|
2011-04-27 10:05:43 +00:00
|
|
|
paintTexturedCube();
|
2014-08-02 17:42:15 +00:00
|
|
|
m_program2->release();
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
|
|
|
|
painter.endNativePainting();
|
|
|
|
|
2019-01-01 14:18:57 +00:00
|
|
|
if (m_showBubbles) {
|
|
|
|
for (Bubble *bubble : qAsConst(m_bubbles))
|
2011-04-27 10:05:43 +00:00
|
|
|
bubble->drawBubble(&painter);
|
2019-01-01 14:18:57 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
if (const int elapsed = m_time.elapsed()) {
|
2014-02-24 10:26:41 +00:00
|
|
|
QString framesPerSecond;
|
2014-08-02 17:42:15 +00:00
|
|
|
framesPerSecond.setNum(m_frames /(elapsed / 1000.0), 'f', 2);
|
2014-06-20 09:58:34 +00:00
|
|
|
painter.setPen(m_transparent ? Qt::black : Qt::white);
|
|
|
|
painter.drawText(20, 40, framesPerSecond + " paintGL calls / s");
|
2014-02-24 10:26:41 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
painter.end();
|
2013-03-14 23:42:15 +00:00
|
|
|
|
2017-12-13 23:29:30 +00:00
|
|
|
for (Bubble *bubble : qAsConst(m_bubbles))
|
2011-04-27 10:05:43 +00:00
|
|
|
bubble->move(rect());
|
2017-12-13 23:29:30 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
if (!(m_frames % 100)) {
|
|
|
|
m_time.start();
|
|
|
|
m_frames = 0;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
m_fAngle += 1.0f;
|
2014-08-02 17:42:15 +00:00
|
|
|
++m_frames;
|
2014-09-28 16:58:46 +00:00
|
|
|
|
|
|
|
// When requested, follow the ideal way to animate: Rely on
|
|
|
|
// blocking swap and just schedule updates continuously.
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
if (!m_mainWindow || !m_mainWindow->timerEnabled())
|
2014-09-28 16:58:46 +00:00
|
|
|
update();
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::createBubbles(int number)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < number; ++i) {
|
2017-04-14 04:13:52 +00:00
|
|
|
QPointF position(width()*(0.1 + QRandomGenerator::global()->bounded(0.8)),
|
|
|
|
height()*(0.1 + QRandomGenerator::global()->bounded(0.8)));
|
|
|
|
qreal radius = qMin(width(), height())*(0.0175 + QRandomGenerator::global()->bounded(0.0875));
|
|
|
|
QPointF velocity(width()*0.0175*(-0.5 + QRandomGenerator::global()->bounded(1.0)),
|
|
|
|
height()*0.0175*(-0.5 + QRandomGenerator::global()->bounded(1.0)));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_bubbles.append(new Bubble(position, radius, velocity));
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::createGeometry()
|
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertices.clear();
|
|
|
|
m_normals.clear();
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
qreal x1 = +0.06f;
|
|
|
|
qreal y1 = -0.14f;
|
|
|
|
qreal x2 = +0.14f;
|
|
|
|
qreal y2 = -0.06f;
|
|
|
|
qreal x3 = +0.08f;
|
|
|
|
qreal y3 = +0.00f;
|
|
|
|
qreal x4 = +0.30f;
|
|
|
|
qreal y4 = +0.22f;
|
|
|
|
|
|
|
|
quad(x1, y1, x2, y2, y2, x2, y1, x1);
|
|
|
|
quad(x3, y3, x4, y4, y4, x4, y3, x3);
|
|
|
|
|
|
|
|
extrude(x1, y1, x2, y2);
|
|
|
|
extrude(x2, y2, y2, x2);
|
|
|
|
extrude(y2, x2, y1, x1);
|
|
|
|
extrude(y1, x1, x1, y1);
|
|
|
|
extrude(x3, y3, x4, y4);
|
|
|
|
extrude(x4, y4, y4, x4);
|
|
|
|
extrude(y4, x4, y3, x3);
|
|
|
|
|
|
|
|
const int NumSectors = 100;
|
2017-03-22 12:18:52 +00:00
|
|
|
const qreal sectorAngle = 2 * qreal(M_PI) / NumSectors;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < NumSectors; ++i) {
|
2017-03-22 12:18:52 +00:00
|
|
|
qreal angle = i * sectorAngle;
|
|
|
|
qreal x5 = 0.30 * sin(angle);
|
|
|
|
qreal y5 = 0.30 * cos(angle);
|
|
|
|
qreal x6 = 0.20 * sin(angle);
|
|
|
|
qreal y6 = 0.20 * cos(angle);
|
|
|
|
|
|
|
|
angle += sectorAngle;
|
|
|
|
qreal x7 = 0.20 * sin(angle);
|
|
|
|
qreal y7 = 0.20 * cos(angle);
|
|
|
|
qreal x8 = 0.30 * sin(angle);
|
|
|
|
qreal y8 = 0.30 * cos(angle);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
quad(x5, y5, x6, y6, x7, y7, x8, y8);
|
|
|
|
|
|
|
|
extrude(x6, y6, x7, y7);
|
|
|
|
extrude(x8, y8, x5, y5);
|
|
|
|
}
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
for (int i = 0;i < m_vertices.size();i++)
|
|
|
|
m_vertices[i] *= 2.0f;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
|
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertices << QVector3D(x1, y1, -0.05f);
|
|
|
|
m_vertices << QVector3D(x2, y2, -0.05f);
|
|
|
|
m_vertices << QVector3D(x4, y4, -0.05f);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertices << QVector3D(x3, y3, -0.05f);
|
|
|
|
m_vertices << QVector3D(x4, y4, -0.05f);
|
|
|
|
m_vertices << QVector3D(x2, y2, -0.05f);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QVector3D n = QVector3D::normal
|
|
|
|
(QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertices << QVector3D(x4, y4, 0.05f);
|
|
|
|
m_vertices << QVector3D(x2, y2, 0.05f);
|
|
|
|
m_vertices << QVector3D(x1, y1, 0.05f);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertices << QVector3D(x2, y2, 0.05f);
|
|
|
|
m_vertices << QVector3D(x4, y4, 0.05f);
|
|
|
|
m_vertices << QVector3D(x3, y3, 0.05f);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
n = QVector3D::normal
|
|
|
|
(QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
|
|
|
|
{
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertices << QVector3D(x1, y1, +0.05f);
|
|
|
|
m_vertices << QVector3D(x2, y2, +0.05f);
|
|
|
|
m_vertices << QVector3D(x1, y1, -0.05f);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_vertices << QVector3D(x2, y2, -0.05f);
|
|
|
|
m_vertices << QVector3D(x1, y1, -0.05f);
|
|
|
|
m_vertices << QVector3D(x2, y2, +0.05f);
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
QVector3D n = QVector3D::normal
|
|
|
|
(QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
|
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2014-08-02 17:42:15 +00:00
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2014-06-20 09:58:34 +00:00
|
|
|
|
|
|
|
void GLWidget::setTransparent(bool transparent)
|
|
|
|
{
|
|
|
|
setAttribute(Qt::WA_AlwaysStackOnTop, transparent);
|
|
|
|
m_transparent = transparent;
|
|
|
|
// Call update() on the top-level window after toggling AlwayStackOnTop to make sure
|
|
|
|
// the entire backingstore is updated accordingly.
|
|
|
|
window()->update();
|
|
|
|
}
|
|
|
|
|
2015-06-01 09:44:37 +00:00
|
|
|
void GLWidget::resizeGL(int, int)
|
2014-06-20 09:58:34 +00:00
|
|
|
{
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
if (m_mainWindow) {
|
2014-06-20 09:58:34 +00:00
|
|
|
if (!m_btn) {
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
m_btn = new QPushButton("\nAdd widget\n", this);
|
|
|
|
connect(m_btn, &QPushButton::clicked, this, [this] { m_mainWindow->addNew(); });
|
2014-06-20 09:58:34 +00:00
|
|
|
}
|
2015-06-01 09:44:37 +00:00
|
|
|
m_btn->move(20, 80);
|
Compose render-to-texture widgets through QRhi
QPlatformTextureList holds a QRhiTexture instead of GLuint. A
QPlatformBackingStore now optionally can own a QRhi and a
QRhiSwapChain for the associated window. Non-GL rendering must use
this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still
rely on resource sharing between contexts. A widget tells that it
wants QRhi and the desired configuration in a new virtual function in
QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is
evaluated (among a top-level's all children) upon create() before
creating the repaint manager and the QWidgetWindow.
In QOpenGLWidget what do request is obvious: it will request an
OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget)
will be more interesting: it needs to honor the standard Qt Quick
env.vars. and QQuickWindow APIs (or, in whatever way the user
configured the QRhiWidget), and so will set up the config struct
accordingly.
In addition, the rhiconfig and surface type is (re)evaluated when
(re)parenting a widget to a new tlw. If needed, this will now trigger
a destroy - create on the tlw. This should be be safe to do in
setParent. When multiple child widgets report an enabled rhiconfig,
the first one (the first child encountered) wins. So e.g. attempting
to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same
top-level window will fail one of the widgets (it likely won't
render).
RasterGLSurface is no longer used by widgets. Rather, the appropriate
surface type is chosen.
The rhi support in the backingstore is usable without widgets as well.
To make rhiFlush() functional, one needs to call setRhiConfig() after
creating the QBackingStore. (like QWidget does to top-level windows)
Most of the QT_NO_OPENGL ifdefs are eliminated all over the place.
Everything with QRhi is unconditional code at compile time, except the
actual initialization.
Having to plumb the widget tlw's shareContext (or, now, the QRhi)
through QWindowPrivate is no longer needed. The old approach does not
scale: to implement composeAndFlush (now rhiFlush) we need more than
just a QRhi object, and this way we no longer pollute everything
starting from the widget level (QWidget's topextra -> QWidgetWindow ->
QWindowPrivate) just to send data around.
The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split
is all gone. Instead, there is a QBackingStoreDefaultCompositor in
QtGui which is what the default implementations of composeAndFlush and
toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs
should continue working mostly as-is, apart from adapting to the
texture list changes and getting the native OpenGL texture id out of
the QRhiTexture)
As QQuickWidget is way too complicated to just port as-is, an rhi
manual test (rhiwidget) is introduced as a first step, in ordewr to
exercise a simple, custom render-to-texture widget that does something
using a (not necessarily OpenGL-backed) QRhi and acts as fully
functional QWidget (modeled after QOpenGLWidget). This can also form
the foundation of a potential future QRhiWidget.
It is also possible to force the QRhi-based flushing always,
regardless of the presence of render-to-texture widgets. To exercise
this, set the env.var. QT_WIDGETS_RHI=1. This picks a
platform-specific default, and can be overridden with
QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be
extended to query the platform plugin as well to check if the platform
plugin prefers to always do flushes with a 3D API.
QOpenGLWidget should work like before from the user's perspective, while
internally it has to do some things differently to play nice and prevent
regressions with the new rendering architecture. To exercise this
better, the qopenglwidget example gets a new tab-based view (that could
perhaps replace the example's main window later on?). The openglwidget
manual test is made compatible with Qt 6, and gets a counterpart in form
of the dockedopenglwidget manual test, which is a modified version of
the cube example that features dock widgets. This is relevant in
particular because render-to-texture widgets within a QDockWidget has
its own specific quirks, with logic taking this into account, hence
testing is essential.
For existing applications there are two important consequences with
this patch in place:
- Once the rhi-based composition is enabled, it stays active for the
lifetime of the top-level window.
- Dynamically creating and parenting the first render-to-texture
widget to an already created tlw will destroy and recreate the tlw
(and the underlying window). The visible effects of this depend on the
platform. (e.g. the window may disappear and reappear on some,
whereas with other windowing systems it is not noticeable at all -
this is not really different from similar situtions with reparenting
or when moving windows between screens, so should be acceptable in
practice)
- On iOS raster windows are flushed with Metal (and rhi) from now on
(previously this was through OpenGL by making flush() call
composeAndFlush().
Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2021-10-25 13:21:31 +00:00
|
|
|
if (!m_btn2) {
|
|
|
|
m_btn2 = new QPushButton("\nI prefer tabbed widgets\n", this);
|
|
|
|
connect(m_btn2, &QPushButton::clicked, this, [this] { m_mainWindow->showNewWindow(); });
|
|
|
|
}
|
|
|
|
m_btn2->move(20, 160);
|
2014-06-20 09:58:34 +00:00
|
|
|
}
|
|
|
|
}
|