mirror of https://github.com/qt/qt3d.git
Revert "Allow for when a Scene3D item switches screens"
This reverts commit 648b7459e8.
Reason for revert: Introduces QTBUG-82275
Change-Id: I5514ad58707c086eaaab3203773614c939e461e8
Reviewed-by: Mike Krus <mike.krus@kdab.com>
This commit is contained in:
parent
ecca6d21fb
commit
c6fecd32f8
|
|
@ -13,6 +13,7 @@ HEADERS += \
|
|||
qtquickscene3dplugin.h \
|
||||
scene3dlogging_p.h \
|
||||
scene3ditem_p.h \
|
||||
scene3dcleaner_p.h \
|
||||
scene3drenderer_p.h \
|
||||
scene3dsgnode_p.h \
|
||||
scene3dsgmaterialshader_p.h \
|
||||
|
|
@ -23,6 +24,7 @@ SOURCES += \
|
|||
qtquickscene3dplugin.cpp \
|
||||
scene3ditem.cpp \
|
||||
scene3dlogging.cpp \
|
||||
scene3dcleaner.cpp \
|
||||
scene3drenderer.cpp \
|
||||
scene3dsgnode.cpp \
|
||||
scene3dsgmaterialshader.cpp \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "scene3dcleaner_p.h"
|
||||
|
||||
#include <Qt3DCore/qaspectengine.h>
|
||||
#include <QtCore/qthread.h>
|
||||
|
||||
#include <scene3dlogging_p.h>
|
||||
#include <scene3drenderer_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace Qt3DRender {
|
||||
|
||||
Scene3DCleaner::Scene3DCleaner(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_renderer(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Scene3DCleaner::~Scene3DCleaner()
|
||||
{
|
||||
qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread();
|
||||
}
|
||||
|
||||
void Scene3DCleaner::cleanup()
|
||||
{
|
||||
Q_ASSERT(m_renderer);
|
||||
delete m_renderer->m_aspectEngine; // also deletes m_renderer->m_renderAspect
|
||||
m_renderer->m_aspectEngine = nullptr;
|
||||
m_renderer->m_renderAspect = nullptr;
|
||||
m_renderer->deleteLater();
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
} // namespace Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QT3DRENDER_SCENE3DCLEANER_P_H
|
||||
#define QT3DRENDER_SCENE3DCLEANER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace Qt3DRender {
|
||||
|
||||
class Scene3DRenderer;
|
||||
|
||||
class Scene3DCleaner : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Scene3DCleaner(QObject *parent = 0);
|
||||
~Scene3DCleaner();
|
||||
|
||||
void setRenderer(Scene3DRenderer *renderer) { m_renderer = renderer; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
Scene3DRenderer *m_renderer;
|
||||
};
|
||||
|
||||
} // namespace Qt3DRender
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT3DRENDER_SCENE3DCLEANER_H
|
||||
|
|
@ -68,6 +68,7 @@
|
|||
#include <Qt3DRender/private/qrendersurfaceselector_p.h>
|
||||
#include <Qt3DRender/private/qrenderaspect_p.h>
|
||||
#include <Qt3DRender/private/rendersettings_p.h>
|
||||
#include <scene3dcleaner_p.h>
|
||||
#include <scene3dlogging_p.h>
|
||||
#include <scene3drenderer_p.h>
|
||||
#include <scene3dsgnode_p.h>
|
||||
|
|
@ -149,8 +150,8 @@ Scene3DItem::Scene3DItem(QQuickItem *parent)
|
|||
, m_viewHolderFG(nullptr)
|
||||
, m_aspectEngine(new Qt3DCore::QAspectEngine())
|
||||
, m_renderAspect(nullptr)
|
||||
, m_aspectToDelete(nullptr)
|
||||
, m_renderer(nullptr)
|
||||
, m_rendererCleaner(new Scene3DCleaner())
|
||||
, m_multisample(true)
|
||||
, m_dirty(true)
|
||||
, m_dirtyViews(false)
|
||||
|
|
@ -178,8 +179,6 @@ Scene3DItem::~Scene3DItem()
|
|||
// When the window is closed, it first destroys all of its children. At
|
||||
// this point, Scene3DItem is destroyed but the Renderer, AspectEngine and
|
||||
// Scene3DSGNode still exist and will perform their cleanup on their own.
|
||||
m_aspectEngine->deleteLater();
|
||||
m_renderer->deleteLater();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -205,11 +204,18 @@ QStringList Scene3DItem::aspects() const
|
|||
*/
|
||||
Qt3DCore::QEntity *Scene3DItem::entity() const
|
||||
{
|
||||
return m_entity.data();
|
||||
return m_entity;
|
||||
}
|
||||
|
||||
void Scene3DItem::applyAspects()
|
||||
void Scene3DItem::setAspects(const QStringList &aspects)
|
||||
{
|
||||
if (!m_aspects.isEmpty()) {
|
||||
qCWarning(Scene3D) << "Aspects already set on the Scene3D, ignoring";
|
||||
return;
|
||||
}
|
||||
|
||||
m_aspects = aspects;
|
||||
|
||||
// Aspects are owned by the aspect engine
|
||||
for (const QString &aspect : qAsConst(m_aspects)) {
|
||||
if (aspect == QLatin1String("render")) // This one is hardwired anyway
|
||||
|
|
@ -240,26 +246,16 @@ void Scene3DItem::applyAspects()
|
|||
}
|
||||
m_aspectEngine->registerAspect(aspect);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene3DItem::setAspects(const QStringList &aspects)
|
||||
{
|
||||
if (!m_aspects.isEmpty()) {
|
||||
qWarning() << "Aspects already set on the Scene3D, ignoring";
|
||||
return;
|
||||
}
|
||||
|
||||
m_aspects = aspects;
|
||||
|
||||
emit aspectsChanged();
|
||||
}
|
||||
|
||||
void Scene3DItem::setEntity(Qt3DCore::QEntity *entity)
|
||||
{
|
||||
if (entity == m_entity.data())
|
||||
if (entity == m_entity)
|
||||
return;
|
||||
|
||||
m_entity.reset(entity);
|
||||
m_entity = entity;
|
||||
emit entityChanged();
|
||||
}
|
||||
|
||||
|
|
@ -402,21 +398,14 @@ void Scene3DItem::removeView(Scene3DView *view)
|
|||
|
||||
void Scene3DItem::applyRootEntityChange()
|
||||
{
|
||||
if (m_aspectEngine->rootEntity() != m_entity.data()) {
|
||||
m_aspectEngine->setRootEntity(m_entity);
|
||||
|
||||
/* If we changed window, the old aspect engine must be deleted only after we have set
|
||||
the root entity for the new one so that it doesn't delete the root node. */
|
||||
if (m_aspectToDelete) {
|
||||
delete m_aspectToDelete;
|
||||
m_aspectToDelete = nullptr;
|
||||
}
|
||||
if (m_aspectEngine->rootEntity() != m_entity) {
|
||||
m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(m_entity));
|
||||
|
||||
// Set the render surface
|
||||
if (!m_entity)
|
||||
return;
|
||||
|
||||
setWindowSurface(entity());
|
||||
setWindowSurface(m_entity);
|
||||
|
||||
if (m_cameraAspectRatioMode == AutomaticAspectRatio) {
|
||||
// Set aspect ratio of first camera to match the window
|
||||
|
|
@ -492,8 +481,6 @@ void Scene3DItem::onBeforeSync()
|
|||
// if the Scene3D item is not visible
|
||||
if (!isVisible() && dontRenderWhenHidden)
|
||||
return;
|
||||
if (m_renderer->m_resetRequested)
|
||||
return;
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == thread());
|
||||
|
||||
|
|
@ -509,7 +496,7 @@ void Scene3DItem::onBeforeSync()
|
|||
// Make renderer aware of any Scene3DView we are dealing with
|
||||
if (m_dirtyViews) {
|
||||
// Scene3DViews checks
|
||||
if (entity() != m_viewHolderEntity) {
|
||||
if (m_entity != m_viewHolderEntity) {
|
||||
qCWarning(Scene3D) << "Scene3DView is not supported if the Scene3D entity property has been set";
|
||||
}
|
||||
if (!usesFBO) {
|
||||
|
|
@ -557,48 +544,30 @@ void Scene3DItem::requestUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
void Scene3DItem::updateWindowSurface()
|
||||
{
|
||||
if (!m_entity || !m_dummySurface)
|
||||
return;
|
||||
Qt3DRender::QRenderSurfaceSelector *surfaceSelector =
|
||||
Qt3DRender::QRenderSurfaceSelectorPrivate::find(entity());
|
||||
if (surfaceSelector) {
|
||||
if (QWindow *rw = QQuickRenderControl::renderWindowFor(this->window())) {
|
||||
m_dummySurface->deleteLater();
|
||||
createDummySurface(rw, surfaceSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene3DItem::setWindowSurface(QObject *rootObject)
|
||||
{
|
||||
Qt3DRender::QRenderSurfaceSelector *surfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(rootObject);
|
||||
|
||||
// Set the item's window surface if it appears
|
||||
// the surface wasn't set on the surfaceSelector
|
||||
if (surfaceSelector && !surfaceSelector->surface()) {
|
||||
// We may not have a real, exposed QQuickWindow when the Quick rendering
|
||||
// is redirected via QQuickRenderControl (f.ex. QQuickWidget).
|
||||
if (QWindow *rw = QQuickRenderControl::renderWindowFor(this->window())) {
|
||||
createDummySurface(rw, surfaceSelector);
|
||||
// rw is the top-level window that is backed by a native window. Do
|
||||
// not use that though since we must not clash with e.g. the widget
|
||||
// backingstore compositor in the gui thread.
|
||||
m_dummySurface = new QOffscreenSurface;
|
||||
m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living
|
||||
m_dummySurface->setFormat(rw->format());
|
||||
m_dummySurface->setScreen(rw->screen());
|
||||
m_dummySurface->create();
|
||||
surfaceSelector->setSurface(m_dummySurface);
|
||||
} else {
|
||||
surfaceSelector->setSurface(this->window());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene3DItem::createDummySurface(QWindow *rw, Qt3DRender::QRenderSurfaceSelector *surfaceSelector)
|
||||
{
|
||||
// rw is the top-level window that is backed by a native window. Do
|
||||
// not use that though since we must not clash with e.g. the widget
|
||||
// backingstore compositor in the gui thread.
|
||||
m_dummySurface = new QOffscreenSurface;
|
||||
m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living
|
||||
m_dummySurface->setFormat(rw->format());
|
||||
m_dummySurface->setScreen(rw->screen());
|
||||
m_dummySurface->create();
|
||||
surfaceSelector->setSurface(m_dummySurface);
|
||||
}
|
||||
/*!
|
||||
\qmlmethod void Scene3D::setItemAreaAndDevicePixelRatio(size area, real devicePixelRatio)
|
||||
|
||||
|
|
@ -606,8 +575,7 @@ void Scene3DItem::createDummySurface(QWindow *rw, Qt3DRender::QRenderSurfaceSele
|
|||
*/
|
||||
void Scene3DItem::setItemAreaAndDevicePixelRatio(QSize area, qreal devicePixelRatio)
|
||||
{
|
||||
Qt3DRender::QRenderSurfaceSelector *surfaceSelector
|
||||
= Qt3DRender::QRenderSurfaceSelectorPrivate::find(entity());
|
||||
Qt3DRender::QRenderSurfaceSelector *surfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(m_entity);
|
||||
if (surfaceSelector) {
|
||||
surfaceSelector->setExternalRenderTargetSize(area);
|
||||
surfaceSelector->setSurfacePixelRatio(devicePixelRatio);
|
||||
|
|
@ -697,16 +665,6 @@ void Scene3DItem::setMultisample(bool enable)
|
|||
|
||||
QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *)
|
||||
{
|
||||
// m_resetRequested is set to true by Scene3DRenderer::shutdown()
|
||||
if (m_renderer && m_renderer->m_resetRequested) {
|
||||
QObject::disconnect(m_windowConnection);
|
||||
m_renderAspect = nullptr;
|
||||
m_aspectToDelete = m_aspectEngine;
|
||||
m_aspectEngine = new Qt3DCore::QAspectEngine();
|
||||
m_aspectEngine->setRunMode(Qt3DCore::QAspectEngine::Manual);
|
||||
applyAspects();
|
||||
m_renderer->m_resetRequested = false;
|
||||
}
|
||||
// If the render aspect wasn't created yet, do so now
|
||||
if (m_renderAspect == nullptr) {
|
||||
m_renderAspect = new QRenderAspect(QRenderAspect::Synchronous);
|
||||
|
|
@ -717,24 +675,16 @@ QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode
|
|||
|
||||
// Before Synchronizing is in the SG Thread, we want beforeSync to be triggered
|
||||
// in the context of the main thread
|
||||
m_windowConnection = QObject::connect(window(), &QQuickWindow::afterAnimating,
|
||||
this, &Scene3DItem::onBeforeSync, Qt::DirectConnection);
|
||||
QObject::connect(window(), &QQuickWindow::afterAnimating,
|
||||
this, &Scene3DItem::onBeforeSync, Qt::DirectConnection);
|
||||
auto renderAspectPriv = static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect));
|
||||
QObject::connect(renderAspectPriv->m_aspectManager->changeArbiter(), &Qt3DCore::QChangeArbiter::receivedChange,
|
||||
this, [this] { m_dirty = true; }, Qt::DirectConnection);
|
||||
}
|
||||
|
||||
if (m_renderer == nullptr) {
|
||||
m_renderer = new Scene3DRenderer();
|
||||
m_renderer->init(this, m_aspectEngine, m_renderAspect);
|
||||
} else if (m_renderer->renderAspect() != m_renderAspect) {
|
||||
// If the renderer's renderAspect is not equal to the aspect used
|
||||
// by the item, then it means that we have created a new one due to
|
||||
// the fact that shutdown() was called on the renderer previously.
|
||||
// This is a typical situation when the window the item is in has
|
||||
// moved from one screen to another.
|
||||
updateWindowSurface();
|
||||
m_renderer->init(this, m_aspectEngine, m_renderAspect);
|
||||
m_renderer = new Scene3DRenderer(this, m_aspectEngine, m_renderAspect);
|
||||
m_renderer->setCleanerHelper(m_rendererCleaner);
|
||||
}
|
||||
const bool usesFBO = m_compositingMode == FBO;
|
||||
const bool hasScene3DViews = !m_views.empty();
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ class Scene3DRenderer;
|
|||
class Scene3DCleaner;
|
||||
class Scene3DView;
|
||||
class QFrameGraphNode;
|
||||
class QRenderSurfaceSelector;
|
||||
|
||||
class Scene3DItem : public QQuickItem
|
||||
{
|
||||
|
|
@ -139,20 +138,16 @@ private:
|
|||
void updateCameraAspectRatio();
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
bool needsRender();
|
||||
void updateWindowSurface();
|
||||
void createDummySurface(QWindow *window, QRenderSurfaceSelector *surfaceSelector);
|
||||
void applyAspects();
|
||||
|
||||
QStringList m_aspects;
|
||||
// Store as shared pointer so that aspect engine doesn't delete it.
|
||||
QSharedPointer<Qt3DCore::QEntity> m_entity;
|
||||
Qt3DCore::QEntity *m_entity;
|
||||
Qt3DCore::QEntity *m_viewHolderEntity;
|
||||
Qt3DRender::QFrameGraphNode *m_viewHolderFG;
|
||||
|
||||
Qt3DCore::QAspectEngine *m_aspectEngine;
|
||||
Qt3DCore::QAspectEngine *m_aspectToDelete;
|
||||
QRenderAspect *m_renderAspect;
|
||||
Scene3DRenderer *m_renderer;
|
||||
Scene3DCleaner *m_rendererCleaner;
|
||||
|
||||
bool m_multisample;
|
||||
bool m_dirty;
|
||||
|
|
@ -165,7 +160,6 @@ private:
|
|||
CompositingMode m_compositingMode;
|
||||
QOffscreenSurface *m_dummySurface;
|
||||
QVector<Scene3DView *> m_views;
|
||||
QMetaObject::Connection m_windowConnection;
|
||||
};
|
||||
|
||||
} // Qt3DRender
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include <Qt3DCore/private/qchangearbiter_p.h>
|
||||
#include <Qt3DCore/private/qservicelocator_p.h>
|
||||
|
||||
#include <scene3dcleaner_p.h>
|
||||
#include <scene3ditem_p.h>
|
||||
#include <scene3dlogging_p.h>
|
||||
#include <scene3dsgnode_p.h>
|
||||
|
|
@ -143,15 +144,16 @@ private:
|
|||
signal of the window is not called. Therefore the cleanup method is invoked
|
||||
to properly destroy the aspect engine.
|
||||
*/
|
||||
Scene3DRenderer::Scene3DRenderer()
|
||||
Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *aspectEngine, QRenderAspect *renderAspect)
|
||||
: QObject()
|
||||
, m_item(nullptr)
|
||||
, m_aspectEngine(nullptr)
|
||||
, m_renderAspect(nullptr)
|
||||
, m_item(item)
|
||||
, m_aspectEngine(aspectEngine)
|
||||
, m_renderAspect(renderAspect)
|
||||
, m_multisampledFBO(nullptr)
|
||||
, m_finalFBO(nullptr)
|
||||
, m_texture(nullptr)
|
||||
, m_node(nullptr)
|
||||
, m_cleaner(nullptr)
|
||||
, m_window(nullptr)
|
||||
, m_multisample(false) // this value is not used, will be synced from the Scene3DItem instead
|
||||
, m_lastMultisample(false)
|
||||
|
|
@ -163,17 +165,6 @@ Scene3DRenderer::Scene3DRenderer()
|
|||
, m_allowRendering(0)
|
||||
, m_compositingMode(Scene3DItem::FBO)
|
||||
{
|
||||
}
|
||||
|
||||
void Scene3DRenderer::init(Scene3DItem *item, Qt3DCore::QAspectEngine *aspectEngine,
|
||||
QRenderAspect *renderAspect)
|
||||
{
|
||||
m_item = item;
|
||||
m_window = m_item->window();
|
||||
m_aspectEngine = aspectEngine;
|
||||
m_renderAspect = renderAspect;
|
||||
m_needsShutdown = true;
|
||||
|
||||
Q_CHECK_PTR(m_item);
|
||||
Q_CHECK_PTR(m_item->window());
|
||||
|
||||
|
|
@ -224,14 +215,21 @@ void Scene3DRenderer::scheduleRootEntityChange()
|
|||
QMetaObject::invokeMethod(m_item, "applyRootEntityChange", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void Scene3DRenderer::setCleanerHelper(Scene3DCleaner *cleaner)
|
||||
{
|
||||
m_cleaner = cleaner;
|
||||
if (m_cleaner) {
|
||||
// Window closed case
|
||||
QObject::connect(m_item->window(), &QQuickWindow::destroyed, m_cleaner, &Scene3DCleaner::cleanup);
|
||||
m_cleaner->setRenderer(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Executed in the QtQuick render thread (which may even be the gui/main with QQuickWidget / RenderControl).
|
||||
void Scene3DRenderer::shutdown()
|
||||
{
|
||||
qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread();
|
||||
|
||||
// In case the same item is rendered on another window reset it
|
||||
m_resetRequested = true;
|
||||
|
||||
// Set to null so that subsequent calls to render
|
||||
// would return early
|
||||
m_item = nullptr;
|
||||
|
|
@ -245,14 +243,8 @@ void Scene3DRenderer::shutdown()
|
|||
|
||||
// Shutdown the Renderer Aspect while the OpenGL context
|
||||
// is still valid
|
||||
if (m_renderAspect) {
|
||||
if (m_renderAspect)
|
||||
static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderShutdown();
|
||||
m_aspectEngine->unregisterAspect(m_renderAspect); // deletes render aspect
|
||||
m_renderAspect = nullptr;
|
||||
}
|
||||
m_aspectEngine = nullptr;
|
||||
m_finalFBO.reset();
|
||||
m_multisampledFBO.reset();
|
||||
}
|
||||
|
||||
// QtQuick render thread (which may also be the gui/main thread with QQuickWidget / RenderControl)
|
||||
|
|
@ -262,6 +254,7 @@ void Scene3DRenderer::onSceneGraphInvalidated()
|
|||
if (m_needsShutdown) {
|
||||
m_needsShutdown = false;
|
||||
shutdown();
|
||||
QMetaObject::invokeMethod(m_cleaner, "cleanup");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,6 +265,7 @@ void Scene3DRenderer::onWindowChanged(QQuickWindow *w)
|
|||
if (m_needsShutdown) {
|
||||
m_needsShutdown = false;
|
||||
shutdown();
|
||||
QMetaObject::invokeMethod(m_cleaner, "cleanup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,9 @@ class Scene3DRenderer : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Scene3DRenderer();
|
||||
Scene3DRenderer(Scene3DItem *item,
|
||||
Qt3DCore::QAspectEngine *aspectEngine,
|
||||
QRenderAspect *renderAspect);
|
||||
~Scene3DRenderer();
|
||||
|
||||
void setSGNode(Scene3DSGNode *node);
|
||||
|
|
@ -87,12 +89,7 @@ public:
|
|||
void setCompositingMode(Scene3DItem::CompositingMode mode);
|
||||
void setSkipFrame(bool skip);
|
||||
void setScene3DViews(const QVector<Scene3DView *> views);
|
||||
void init(Scene3DItem *item, Qt3DCore::QAspectEngine *aspectEngine, QRenderAspect *renderAspect);
|
||||
|
||||
QRenderAspect *renderAspect() const
|
||||
{
|
||||
return m_renderAspect;
|
||||
}
|
||||
public Q_SLOTS:
|
||||
void render();
|
||||
void shutdown();
|
||||
|
|
@ -106,12 +103,13 @@ private:
|
|||
void scheduleRootEntityChange();
|
||||
|
||||
Scene3DItem *m_item; // Will be released by the QQuickWindow/QML Engine
|
||||
Qt3DCore::QAspectEngine *m_aspectEngine; // Will be released by the Scene3DItem
|
||||
Qt3DCore::QAspectEngine *m_aspectEngine; // Will be released by the Scene3DRendererCleaner
|
||||
QRenderAspect *m_renderAspect; // Will be released by the aspectEngine
|
||||
QScopedPointer<QOpenGLFramebufferObject> m_multisampledFBO;
|
||||
QScopedPointer<QOpenGLFramebufferObject> m_finalFBO;
|
||||
QScopedPointer<QSGTexture> m_texture;
|
||||
Scene3DSGNode *m_node; // Will be released by the QtQuick SceneGraph
|
||||
Scene3DCleaner *m_cleaner;
|
||||
QQuickWindow *m_window;
|
||||
QMutex m_windowMutex;
|
||||
QSize m_lastSize;
|
||||
|
|
@ -125,9 +123,8 @@ private:
|
|||
QSemaphore m_allowRendering;
|
||||
Scene3DItem::CompositingMode m_compositingMode;
|
||||
QVector<Scene3DView *> m_views;
|
||||
bool m_resetRequested = false;
|
||||
|
||||
friend class Scene3DItem;
|
||||
friend class Scene3DCleaner;
|
||||
};
|
||||
|
||||
} // namespace Qt3DRender
|
||||
|
|
|
|||
|
|
@ -88,8 +88,3 @@ qtHaveModule(widgets): {
|
|||
rendercapture-cpp \
|
||||
texture-updates-cpp
|
||||
}
|
||||
|
||||
qtHaveModule(quickwidgets): {
|
||||
SUBDIRS += quickwidget-switch
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,125 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QDesktopWidget>
|
||||
#include <QScreen>
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <QMdiArea>
|
||||
#include <QMdiSubWindow>
|
||||
#include <QQuickWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
void configureMainWindow(QMainWindow *w, QMdiArea *mdiArea, QPushButton *button)
|
||||
{
|
||||
auto widget = new QWidget;
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->addWidget(mdiArea);
|
||||
layout->addWidget(button);
|
||||
widget->setLayout(layout);
|
||||
w->setCentralWidget(widget);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QMainWindow w1;
|
||||
w1.winId();
|
||||
w1.windowHandle()->setScreen(QGuiApplication::screens().at(0));
|
||||
auto mdiArea1 = new QMdiArea;
|
||||
auto button1 = new QPushButton("Switch to other window");
|
||||
configureMainWindow(&w1, mdiArea1, button1);
|
||||
w1.setGeometry(0, 0, 800, 800);
|
||||
w1.show();
|
||||
|
||||
QMainWindow w2;
|
||||
w2.winId();
|
||||
w2.windowHandle()->setScreen(QGuiApplication::screens().at(1));
|
||||
auto mdiArea2 = new QMdiArea;
|
||||
auto button2 = new QPushButton("Switch to other window");
|
||||
configureMainWindow(&w2, mdiArea2, button2);
|
||||
w2.setGeometry(0, 0, 800, 800);
|
||||
w2.show();
|
||||
|
||||
QMdiSubWindow* subWindow = new QMdiSubWindow();
|
||||
|
||||
QQuickWidget *quickWidget = new QQuickWidget();
|
||||
quickWidget->resize(QSize(400, 400));
|
||||
quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
quickWidget->setSource(QUrl("qrc:/main.qml"));
|
||||
|
||||
subWindow->setWidget(quickWidget);
|
||||
|
||||
QObject::connect(button1, &QPushButton::clicked,
|
||||
[mdiArea1, mdiArea2, subWindow, button1, button2]() {
|
||||
mdiArea2->removeSubWindow(subWindow);
|
||||
mdiArea1->addSubWindow(subWindow);
|
||||
subWindow->show();
|
||||
button1->setEnabled(false);
|
||||
button2->setEnabled(true);
|
||||
});
|
||||
|
||||
QObject::connect(button2, &QPushButton::clicked,
|
||||
[mdiArea1, mdiArea2, subWindow, button1, button2]() {
|
||||
mdiArea1->removeSubWindow(subWindow);
|
||||
mdiArea2->addSubWindow(subWindow);
|
||||
subWindow->show();
|
||||
button1->setEnabled(true);
|
||||
button2->setEnabled(false);
|
||||
});
|
||||
|
||||
mdiArea2->addSubWindow(subWindow);
|
||||
button2->setEnabled(false);
|
||||
subWindow->show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt3D module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.2 as QQ2
|
||||
import Qt3D.Core 2.0
|
||||
import Qt3D.Render 2.0
|
||||
import Qt3D.Input 2.0
|
||||
import Qt3D.Extras 2.0
|
||||
|
||||
import QtQuick.Scene3D 2.0
|
||||
|
||||
QQ2.Item {
|
||||
id: mioitem
|
||||
width: 300
|
||||
height: 300
|
||||
Scene3D {
|
||||
id: scene3d
|
||||
anchors.fill: parent
|
||||
Entity {
|
||||
id: sceneRoot
|
||||
|
||||
Camera {
|
||||
id: camera
|
||||
projectionType: CameraLens.PerspectiveProjection
|
||||
fieldOfView: 45
|
||||
aspectRatio: 16/9
|
||||
nearPlane : 0.1
|
||||
farPlane : 1000.0
|
||||
position: Qt.vector3d( 0.0, 0.0, -40.0 )
|
||||
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
|
||||
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
|
||||
}
|
||||
|
||||
OrbitCameraController {
|
||||
camera: camera
|
||||
}
|
||||
|
||||
components: [
|
||||
RenderSettings {
|
||||
activeFrameGraph: ForwardRenderer {
|
||||
clearColor: Qt.rgba(0, 0.5, 1, 1)
|
||||
camera: camera
|
||||
}
|
||||
},
|
||||
// Event Source will be set by the Qt3DQuickWindow
|
||||
InputSettings { }
|
||||
]
|
||||
|
||||
PhongMaterial {
|
||||
id: material
|
||||
}
|
||||
|
||||
TorusMesh {
|
||||
id: torusMesh
|
||||
radius: 5
|
||||
minorRadius: 1
|
||||
rings: 100
|
||||
slices: 20
|
||||
}
|
||||
|
||||
Transform {
|
||||
id: torusTransform
|
||||
scale3D: Qt.vector3d(1.5, 1, 0.5)
|
||||
rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45)
|
||||
}
|
||||
|
||||
Entity {
|
||||
id: torusEntity
|
||||
components: [ torusMesh, material, torusTransform ]
|
||||
}
|
||||
|
||||
SphereMesh {
|
||||
id: sphereMesh
|
||||
radius: 3
|
||||
}
|
||||
|
||||
Transform {
|
||||
id: sphereTransform
|
||||
property real userAngle: 0.0
|
||||
matrix: {
|
||||
var m = Qt.matrix4x4();
|
||||
m.rotate(userAngle, Qt.vector3d(0, 1, 0));
|
||||
m.translate(Qt.vector3d(20, 0, 0));
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
QQ2.NumberAnimation {
|
||||
target: sphereTransform
|
||||
property: "userAngle"
|
||||
duration: 10000
|
||||
from: 0
|
||||
to: 360
|
||||
|
||||
loops: QQ2.Animation.Infinite
|
||||
running: true
|
||||
}
|
||||
|
||||
Entity {
|
||||
id: sphereEntity
|
||||
components: [ sphereMesh, material, sphereTransform ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
TEMPLATE = app
|
||||
|
||||
QT += 3dextras
|
||||
CONFIG += resources_big
|
||||
|
||||
QT += 3dcore 3drender 3dinput 3dquick 3dlogic qml quick 3dquickextras widgets quickwidgets
|
||||
|
||||
SOURCES += \
|
||||
main.cpp
|
||||
|
||||
RESOURCES += \
|
||||
quickwidget-switch.qrc
|
||||
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
Loading…
Reference in New Issue