summaryrefslogtreecommitdiffstats
path: root/src/render
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2016-08-14 09:23:05 +0100
committerSean Harmer <sean.harmer@kdab.com>2016-08-14 09:41:21 +0100
commit9a18925b63d47a20d7b74cfd508d7ae71f2d4d7c (patch)
tree4d0d0538b9475a9104d56ee3d07f4bab7b0e00b4 /src/render
parent9a1c0c96246126d2377bd56ed702f47214e3ee0a (diff)
parent71eee85093ba807f5bc2add472b359841faa062d (diff)
Merge branch '5.7' into dev
Diffstat (limited to 'src/render')
-rw-r--r--src/render/backend/entity.cpp1
-rw-r--r--src/render/backend/handle_types_p.h2
-rw-r--r--src/render/backend/managers_p.h2
-rw-r--r--src/render/backend/renderer.cpp33
-rw-r--r--src/render/backend/renderer_p.h1
-rw-r--r--src/render/backend/renderview.cpp63
-rw-r--r--src/render/backend/renderview_p.h4
-rw-r--r--src/render/framegraph/qrendersurfaceselector.cpp26
-rw-r--r--src/render/framegraph/qrendersurfaceselector_p.h8
-rw-r--r--src/render/framegraph/sortpolicy.cpp1
-rw-r--r--src/render/framegraph/sortpolicy_p.h2
-rw-r--r--src/render/frontend/qboundingvolumedebug.cpp182
-rw-r--r--src/render/frontend/qlayer.cpp76
-rw-r--r--src/render/frontend/qrenderaspect.cpp6
-rw-r--r--src/render/frontend/render-frontend.pri2
-rw-r--r--src/render/geometry/qattribute.cpp19
-rw-r--r--src/render/geometry/qbuffer.cpp13
-rw-r--r--src/render/graphicshelpers/graphicscontext.cpp9
-rw-r--r--src/render/graphicshelpers/graphicshelperes2.cpp36
-rw-r--r--src/render/graphicshelpers/graphicshelperes2_p.h4
-rw-r--r--src/render/graphicshelpers/graphicshelperes3.cpp173
-rw-r--r--src/render/graphicshelpers/graphicshelperes3_p.h (renamed from src/render/frontend/qboundingvolumedebug_p.h)57
-rw-r--r--src/render/graphicshelpers/graphicshelpers.pri2
-rw-r--r--src/render/io/qsceneloader.cpp54
-rw-r--r--src/render/jobs/filterlayerentityjob.cpp11
-rw-r--r--src/render/jobs/frustumcullingjob_p.h2
-rw-r--r--src/render/jobs/loadscenejob.cpp28
-rw-r--r--src/render/jobs/pickboundingvolumejob.cpp20
-rw-r--r--src/render/jobs/renderviewinitializerjob_p.h1
-rw-r--r--src/render/materialsystem/qgraphicsapifilter.cpp42
-rw-r--r--src/render/materialsystem/qgraphicsapifilter.h8
-rw-r--r--src/render/picking/qobjectpicker.cpp2
-rw-r--r--src/render/renderstates/renderstatenode.cpp2
-rw-r--r--src/render/renderstates/renderstateset.cpp24
-rw-r--r--src/render/renderstates/renderstateset_p.h2
-rw-r--r--src/render/renderstates/statevariant.cpp2
-rw-r--r--src/render/texture/qtexture.cpp1
-rw-r--r--src/render/texture/qtextureimage.cpp1
38 files changed, 569 insertions, 353 deletions
diff --git a/src/render/backend/entity.cpp b/src/render/backend/entity.cpp
index 7091d493f..095a5a62d 100644
--- a/src/render/backend/entity.cpp
+++ b/src/render/backend/entity.cpp
@@ -50,7 +50,6 @@
#include <Qt3DRender/qgeometryrenderer.h>
#include <Qt3DRender/qobjectpicker.h>
#include <Qt3DRender/qcomputecommand.h>
-#include <Qt3DRender/private/qboundingvolumedebug_p.h>
#include <Qt3DRender/private/geometryrenderermanager_p.h>
#include <Qt3DRender/qcameralens.h>
diff --git a/src/render/backend/handle_types_p.h b/src/render/backend/handle_types_p.h
index d22ef1d90..e68f0f1c5 100644
--- a/src/render/backend/handle_types_p.h
+++ b/src/render/backend/handle_types_p.h
@@ -114,7 +114,7 @@ typedef Qt3DCore::QHandle<Parameter, 16> HParameter;
typedef Qt3DCore::QHandle<ShaderData, 16> HShaderData;
typedef Qt3DCore::QHandle<TextureImage, 16> HTextureImage;
typedef Qt3DCore::QHandle<Buffer, 16> HBuffer;
-typedef Qt3DCore::QHandle<Attribute, 16> HAttribute;
+typedef Qt3DCore::QHandle<Attribute, 20> HAttribute;
typedef Qt3DCore::QHandle<Geometry, 16> HGeometry;
typedef Qt3DCore::QHandle<GeometryRenderer, 16> HGeometryRenderer;
typedef Qt3DCore::QHandle<ObjectPicker, 16> HObjectPicker;
diff --git a/src/render/backend/managers_p.h b/src/render/backend/managers_p.h
index f2c26fd00..8d922c0d1 100644
--- a/src/render/backend/managers_p.h
+++ b/src/render/backend/managers_p.h
@@ -310,7 +310,7 @@ class TextureImageManager : public Qt3DCore::QResourceManager<
class AttributeManager : public Qt3DCore::QResourceManager<
Attribute,
Qt3DCore::QNodeId,
- 16,
+ 20,
Qt3DCore::ArrayAllocatingPolicy,
Qt3DCore::ObjectLevelLockingPolicy>
{
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index 58cc4c483..c91eff86e 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -290,6 +290,12 @@ void Renderer::shutdown()
{
qCDebug(Backend) << Q_FUNC_INFO << "Requesting renderer shutdown";
m_running.store(0);
+
+ // We delete any renderqueue that we may not have had time to render
+ // before the surface was destroyed
+ qDeleteAll(m_renderQueue->nextFrameQueue());
+ m_renderQueue->reset();
+
if (!m_renderThread) {
releaseGraphicsResources();
} else {
@@ -760,12 +766,19 @@ void Renderer::updateGLResources()
}
}
- const QVector<HShader> activeShaderHandles = m_nodesManager->shaderManager()->activeHandles();
- for (HShader handle: activeShaderHandles) {
- Shader *shader = m_nodesManager->shaderManager()->data(handle);
- if (!shader->isLoaded()) {
- // Compile shader
- m_graphicsContext->loadShader(shader);
+ const QVector<HTechnique> activeTechniques = m_nodesManager->techniqueManager()->activeHandles();
+ for (HTechnique techniqueHandle : activeTechniques) {
+ Technique *technique = m_nodesManager->techniqueManager()->data(techniqueHandle);
+ // If api of the renderer matches the one from the technique
+ if (*contextInfo() == *technique->graphicsApiFilter()) {
+ const auto passIds = technique->renderPasses();
+ for (const QNodeId passId : passIds) {
+ RenderPass *renderPass = m_nodesManager->renderPassManager()->lookupResource(passId);
+ HShader shaderHandle = m_nodesManager->shaderManager()->lookupHandle(renderPass->shaderProgram());
+ Shader *shader = m_nodesManager->shaderManager()->data(shaderHandle);
+ if (shader != nullptr && !shader->isLoaded())
+ m_graphicsContext->loadShader(shader);
+ }
}
}
@@ -798,6 +811,7 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
QSurface *surface = nullptr;
QSurface *previousSurface = renderViews.first()->surface();
QSurface *lastUsedSurface = nullptr;
+
for (int i = 0; i < renderViewsCount; ++i) {
// Initialize GraphicsContext for drawing
// If the RenderView has a RenderStateSet defined
@@ -842,13 +856,14 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
lastBoundFBOId = m_graphicsContext->boundFrameBufferObject();
}
- // Set RenderView render state
// Note: the RenderStateSet is allocated once per RV if needed
// and it contains a list of StateVariant value types
RenderStateSet *renderViewStateSet = renderView->stateSet();
- if (renderViewStateSet)
+
+ // Set the RV state if not null,
+ if (renderViewStateSet != nullptr)
m_graphicsContext->setCurrentStateSet(renderViewStateSet);
- else if (surfaceHasChanged || i == 0) // Reset state to the default state on initial render view or on surface change
+ else
m_graphicsContext->setCurrentStateSet(m_defaultRenderStateSet);
// Set RenderTarget ...
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index ddbc4cffc..3e6ef6ffc 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -82,7 +82,6 @@
#include <QAtomicInt>
#include <QScopedPointer>
#include <QSemaphore>
-#include <QThreadStorage>
QT_BEGIN_NAMESPACE
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 8d40f2882..9226f8fac 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -114,12 +114,14 @@ RenderView::StandardUniformsPFuncsHash RenderView::initializeStandardUniformSett
setters.insert(StringToInt::lookupId(QLatin1String("viewMatrix")), &RenderView::viewMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("projectionMatrix")), &RenderView::projectionMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("modelView")), &RenderView::modelViewMatrix);
+ setters.insert(StringToInt::lookupId(QLatin1String("viewProjectionMatrix")), &RenderView::viewProjectionMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("modelViewProjection")), &RenderView::modelViewProjectionMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("mvp")), &RenderView::modelViewProjectionMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("inverseModelMatrix")), &RenderView::inverseModelMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("inverseViewMatrix")), &RenderView::inverseViewMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("inverseProjectionMatrix")), &RenderView::inverseProjectionMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("inverseModelView")), &RenderView::inverseModelViewMatrix);
+ setters.insert(StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix")), &RenderView::inverseViewProjectionMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("inverseModelViewProjection")), &RenderView::inverseModelViewProjectionMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("modelNormalMatrix")), &RenderView::modelNormalMatrix);
setters.insert(StringToInt::lookupId(QLatin1String("modelViewNormal")), &RenderView::modelViewNormalMatrix);
@@ -151,6 +153,12 @@ QUniformValue RenderView::modelViewMatrix(const QMatrix4x4 &model) const
return QUniformValue(QVariant::fromValue(m_data.m_viewMatrix * model));
}
+QUniformValue RenderView::viewProjectionMatrix(const QMatrix4x4 &model) const
+{
+ Q_UNUSED(model);
+ return QUniformValue(QVariant::fromValue(m_data.m_renderCameraLens->projection() * m_data.m_viewMatrix));
+}
+
QUniformValue RenderView::modelViewProjectionMatrix(const QMatrix4x4 &model) const
{
return QUniformValue(QVariant::fromValue(m_data.m_viewProjectionMatrix * model));
@@ -179,6 +187,13 @@ QUniformValue RenderView::inverseModelViewMatrix(const QMatrix4x4 &model) const
return QUniformValue(QVariant::fromValue((m_data.m_viewMatrix * model).inverted()));
}
+QUniformValue RenderView::inverseViewProjectionMatrix(const QMatrix4x4 &model) const
+{
+ Q_UNUSED(model);
+ const auto viewProjectionMatrix = m_data.m_renderCameraLens->projection() * m_data.m_viewMatrix;
+ return QUniformValue(QVariant::fromValue(viewProjectionMatrix.inverted()));
+}
+
QUniformValue RenderView::inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const
{
return QUniformValue(QVariant::fromValue((m_data.m_viewProjectionMatrix * model).inverted(0)));
@@ -383,6 +398,13 @@ void RenderView::addClearBuffers(const ClearBuffers *cb) {
// If we are there, we know that entity had a GeometryRenderer + Material
QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entity *> &entities) const
{
+ // Note: since many threads can be building render commands
+ // we need to ensure that the UniformBlockValueBuilder they are using
+ // is only accessed from the same thread
+ UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
+ builder->shaderDataManager = m_manager->shaderDataManager();
+ m_localData.setLocalData(builder);
+
QVector<RenderCommand *> commands;
commands.reserve(entities.size());
@@ -429,6 +451,8 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
std::sort(lightSources.begin(), lightSources.end(), LightSourceCompare(node));
ParameterInfoList globalParameters = passData.parameterInfo;
+ // setShaderAndUniforms can initialize a localData
+ // make sure this is cleared before we leave this function
setShaderAndUniforms(command, pass, globalParameters, *(node->worldTransform()), lightSources.mid(0, std::max(lightSources.size(), MAX_LIGHTS)));
buildSortingKey(command);
@@ -436,11 +460,22 @@ QVector<RenderCommand *> RenderView::buildDrawRenderCommands(const QVector<Entit
}
}
}
+
+ // We reset the local data once we are done with it
+ m_localData.setLocalData(nullptr);
+
return commands;
}
QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<Entity *> &entities) const
{
+ // Note: since many threads can be building render commands
+ // we need to ensure that the UniformBlockValueBuilder they are using
+ // is only accessed from the same thread
+ UniformBlockValueBuilder *builder = new UniformBlockValueBuilder();
+ builder->shaderDataManager = m_manager->shaderDataManager();
+ m_localData.setLocalData(builder);
+
// If the RenderView contains only a ComputeDispatch then it cares about
// A ComputeDispatch is also implicitely a NoDraw operation
// enabled flag
@@ -477,6 +512,10 @@ QVector<RenderCommand *> RenderView::buildComputeRenderCommands(const QVector<En
}
}
}
+
+ // We reset the local data once we are done with it
+ m_localData.setLocalData(nullptr);
+
return commands;
}
@@ -612,28 +651,22 @@ void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack, Shader *shader, ShaderData *shaderData, const QString &structName) const
{
- // Note: since many threads can be building render commands
- // we need to ensure that the UniformBlockValueBuilder they are using
- // is only accessed from the same thread
- if (!m_localData.hasLocalData()) {
- m_localData.setLocalData(UniformBlockValueBuilder());
- m_localData.localData().shaderDataManager = m_manager->shaderDataManager();
- }
-
- UniformBlockValueBuilder &builder = m_localData.localData();
- builder.activeUniformNamesToValue.clear();
+ UniformBlockValueBuilder *builder = m_localData.localData();
+ builder->activeUniformNamesToValue.clear();
// updates transformed properties;
+ // Fix me: this will lead to races when having multiple cameras
shaderData->updateViewTransform(m_data.m_viewMatrix);
+
// Force to update the whole block
- builder.updatedPropertiesOnly = false;
+ builder->updatedPropertiesOnly = false;
// Retrieve names and description of each active uniforms in the uniform block
- builder.uniforms = shader->activeUniformsForUniformBlock(-1);
+ builder->uniforms = shader->activeUniformsForUniformBlock(-1);
// Build name-value map for the block
- builder.buildActiveUniformNameValueMapStructHelper(shaderData, structName);
+ builder->buildActiveUniformNameValueMapStructHelper(shaderData, structName);
// Set uniform values for each entrie of the block name-value map
- QHash<int, QVariant>::const_iterator activeValuesIt = builder.activeUniformNamesToValue.constBegin();
- const QHash<int, QVariant>::const_iterator activeValuesEnd = builder.activeUniformNamesToValue.constEnd();
+ QHash<int, QVariant>::const_iterator activeValuesIt = builder->activeUniformNamesToValue.constBegin();
+ const QHash<int, QVariant>::const_iterator activeValuesEnd = builder->activeUniformNamesToValue.constEnd();
while (activeValuesIt != activeValuesEnd) {
setUniformValue(uniformPack, activeValuesIt.key(), activeValuesIt.value());
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index 0b01744e9..7be9903f6 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -242,7 +242,7 @@ private:
void setShaderAndUniforms(RenderCommand *command, RenderPass *pass, ParameterInfoList &parameters, const QMatrix4x4 &worldTransform,
const QVector<LightSource> &activeLightSources) const;
- mutable QThreadStorage<UniformBlockValueBuilder> m_localData;
+ mutable QThreadStorage<UniformBlockValueBuilder*> m_localData;
Renderer *m_renderer;
NodeManagers *m_manager;
@@ -282,11 +282,13 @@ private:
QUniformValue viewMatrix(const QMatrix4x4&) const;
QUniformValue projectionMatrix(const QMatrix4x4 &) const;
QUniformValue modelViewMatrix(const QMatrix4x4 &model) const;
+ QUniformValue viewProjectionMatrix(const QMatrix4x4 &model) const;
QUniformValue modelViewProjectionMatrix(const QMatrix4x4 &model) const;
QUniformValue inverseModelMatrix(const QMatrix4x4 &model) const;
QUniformValue inverseViewMatrix(const QMatrix4x4 &) const;
QUniformValue inverseProjectionMatrix(const QMatrix4x4 &) const;
QUniformValue inverseModelViewMatrix(const QMatrix4x4 &model) const;
+ QUniformValue inverseViewProjectionMatrix(const QMatrix4x4 &model) const;
QUniformValue inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const;
QUniformValue modelNormalMatrix(const QMatrix4x4 &model) const;
QUniformValue modelViewNormalMatrix(const QMatrix4x4 &model) const;
diff --git a/src/render/framegraph/qrendersurfaceselector.cpp b/src/render/framegraph/qrendersurfaceselector.cpp
index 349ceb827..e76963e72 100644
--- a/src/render/framegraph/qrendersurfaceselector.cpp
+++ b/src/render/framegraph/qrendersurfaceselector.cpp
@@ -43,7 +43,9 @@
#include <QtGui/QWindow>
#include <QtGui/QScreen>
#include <QtGui/QOffscreenSurface>
+#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
+#include <Qt3DRender/qrendersettings.h>
QT_BEGIN_NAMESPACE
@@ -104,6 +106,30 @@ QRenderSurfaceSelectorPrivate::~QRenderSurfaceSelectorPrivate()
QObject::disconnect(m_screenConn);
}
+QRenderSurfaceSelector *QRenderSurfaceSelectorPrivate::find(QObject *rootObject)
+{
+ auto rendererSettings = rootObject->findChild<Qt3DRender::QRenderSettings *>();
+ if (!rendererSettings) {
+ qWarning() << "No renderer settings component found";
+ return nullptr;
+ }
+
+ auto frameGraphRoot = rendererSettings->activeFrameGraph();
+ if (!frameGraphRoot) {
+ qWarning() << "No active frame graph found";
+ return nullptr;
+ }
+
+ auto surfaceSelector = qobject_cast<Qt3DRender::QRenderSurfaceSelector *>(frameGraphRoot);
+ if (!surfaceSelector)
+ surfaceSelector = frameGraphRoot->findChild<Qt3DRender::QRenderSurfaceSelector *>();
+
+ if (!surfaceSelector)
+ qWarning() << "No render surface selector found in frame graph";
+
+ return surfaceSelector;
+}
+
void QRenderSurfaceSelectorPrivate::setExternalRenderTargetSize(const QSize &size)
{
m_externalRenderTargetSize = size;
diff --git a/src/render/framegraph/qrendersurfaceselector_p.h b/src/render/framegraph/qrendersurfaceselector_p.h
index d21bf744c..899387b98 100644
--- a/src/render/framegraph/qrendersurfaceselector_p.h
+++ b/src/render/framegraph/qrendersurfaceselector_p.h
@@ -53,6 +53,7 @@
#include <Qt3DRender/private/qframegraphnode_p.h>
#include <Qt3DRender/private/platformsurfacefilter_p.h>
+#include <Qt3DRender/private/qt3drender_global_p.h>
#include <QtGui/qsurface.h>
#include <QtGui/qwindow.h>
#include <QtCore/qpointer.h>
@@ -61,12 +62,17 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
-class QRenderSurfaceSelectorPrivate : public Qt3DRender::QFrameGraphNodePrivate
+class QRenderSurfaceSelector;
+
+class QT3DRENDERSHARED_PRIVATE_EXPORT QRenderSurfaceSelectorPrivate : public Qt3DRender::QFrameGraphNodePrivate
{
public:
QRenderSurfaceSelectorPrivate();
~QRenderSurfaceSelectorPrivate();
+ // TODO: Qt 5.8, make it public
+ static QRenderSurfaceSelector *find(QObject *rootObject);
+
void setExternalRenderTargetSize(const QSize &size);
QSize externalRenderTargetSize() const { return m_externalRenderTargetSize; }
diff --git a/src/render/framegraph/sortpolicy.cpp b/src/render/framegraph/sortpolicy.cpp
index 628fa75e4..9631ebeab 100644
--- a/src/render/framegraph/sortpolicy.cpp
+++ b/src/render/framegraph/sortpolicy.cpp
@@ -74,6 +74,7 @@ QVector<QSortPolicy::SortType> SortPolicy::sortTypes() const
void SortPolicy::initializeFromPeer(const QNodeCreatedChangeBasePtr &change)
{
+ FrameGraphNode::initializeFromPeer(change);
const auto typedChange = qSharedPointerCast<Qt3DCore::QNodeCreatedChange<QSortPolicyData>>(change);
const QSortPolicyData &data = typedChange->data;
m_sortTypes = data.sortTypes;
diff --git a/src/render/framegraph/sortpolicy_p.h b/src/render/framegraph/sortpolicy_p.h
index 32d2888c3..868c1430d 100644
--- a/src/render/framegraph/sortpolicy_p.h
+++ b/src/render/framegraph/sortpolicy_p.h
@@ -60,7 +60,7 @@ namespace Qt3DRender {
namespace Render {
-class SortPolicy : public FrameGraphNode
+class Q_AUTOTEST_EXPORT SortPolicy : public FrameGraphNode
{
public:
SortPolicy();
diff --git a/src/render/frontend/qboundingvolumedebug.cpp b/src/render/frontend/qboundingvolumedebug.cpp
deleted file mode 100644
index 4ee6816d6..000000000
--- a/src/render/frontend/qboundingvolumedebug.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 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$
-**
-****************************************************************************/
-
-#if 0
-
-#include "qboundingvolumedebug_p.h"
-#include <Qt3DCore/qentity.h>
-#include <Qt3DCore/private/qcomponent_p.h>
-#include <Qt3DCore/qpropertyupdatedchange.h>
-#include <Qt3DRender/qspheremesh.h>
-#include <Qt3DCore/qtransform.h>
-#include <Qt3DRender/qphongalphamaterial.h>
-#include <Qt3DRender/qlayer.h>
-#include <QThread>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DRender {
-
-class QBoundingVolumeDebugPrivate : public Qt3DCore::QComponentPrivate
-{
-public:
- QBoundingVolumeDebugPrivate()
- : QComponentPrivate()
- , m_recursive(false)
- , m_debugSubtree(nullptr)
- , m_sphereMesh(nullptr)
- , m_transform(nullptr)
- , m_material(nullptr)
- , m_layer(nullptr)
- , m_bvRadius(0.0f)
- {
- m_shareable = false;
- }
-
- Q_DECLARE_PUBLIC(QBoundingVolumeDebug)
-
- bool m_recursive;
- Qt3DCore::QEntity *m_debugSubtree;
- Qt3DRender::QSphereMesh *m_sphereMesh;
- Qt3DCore::QTransform *m_transform;
- Qt3DRender::QMaterial *m_material;
- Qt3DRender::QLayer *m_layer;
-
- float m_bvRadius;
- QVector3D m_bvCenter;
-
- Qt3DCore::QEntity *findRootEntity(Qt3DCore::QEntity *e);
- void updateSubtree();
-};
-
-QBoundingVolumeDebug::QBoundingVolumeDebug(Qt3DCore::QNode *parent)
- : QComponent(*new QBoundingVolumeDebugPrivate(), parent)
-{
-}
-
-QBoundingVolumeDebug::~QBoundingVolumeDebug()
-{
- QComponent::cleanup();
-}
-
-void QBoundingVolumeDebug::setRecursive(bool recursive)
-{
- Q_D(QBoundingVolumeDebug);
- if (d->m_recursive != recursive) {
- d->m_recursive = recursive;
- emit recursiveChanged(recursive);
- }
-}
-
-bool QBoundingVolumeDebug::recursive() const
-{
- Q_D(const QBoundingVolumeDebug);
- return d->m_recursive;
-}
-
-void QBoundingVolumeDebug::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
-{
- Q_D(QBoundingVolumeDebug);
- Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change);
- if (e->type() == Qt3DCore::PropertyUpdated) {
- if (e->propertyName() == QByteArrayLiteral("center")) {
- d->m_bvCenter = e->value().value<QVector3D>();
- d->updateSubtree();
- } else if (e->propertyName() == QByteArrayLiteral("radius")) {
- d->m_bvRadius = e->value().toFloat();
- d->updateSubtree();
- }
- }
-}
-
-// Executed in the frontend thread
-Qt3DCore::QEntity *QBoundingVolumeDebugPrivate::findRootEntity(Qt3DCore::QEntity *e)
-{
- Qt3DCore::QEntity *tmp = nullptr;
- Qt3DCore::QEntity *parentEntity = nullptr;
- while (e && (tmp = e->parentEntity()) != nullptr) {
- parentEntity = tmp;
- e = parentEntity;
- }
- return parentEntity;
-}
-
-void QBoundingVolumeDebugPrivate::updateSubtree()
-{
- Q_Q(QBoundingVolumeDebug);
- if (m_debugSubtree == nullptr) {
- m_debugSubtree = new Qt3DCore::QEntity();
- m_sphereMesh = new Qt3DRender::QSphereMesh();
- m_transform = new Qt3DCore::QTransform();
- m_material = new Qt3DRender::QPhongAlphaMaterial();
- m_layer = new Qt3DRender::QLayer();
-
- static_cast<QPhongAlphaMaterial *>(m_material)->setAlpha(0.3f);
- static_cast<QPhongAlphaMaterial *>(m_material)->setDiffuse(QColor::fromRgb(255, 153, 0));
-
- m_layer->setNames(QStringList() << QStringLiteral("debug"));
-
- m_debugSubtree->addComponent(m_sphereMesh);
- m_debugSubtree->addComponent(m_transform);
- m_debugSubtree->addComponent(m_material);
- m_debugSubtree->addComponent(m_layer);
-
- m_transform->setTranslation(m_bvCenter);
- m_transform->setScale(m_bvRadius * 2.0f);
- m_sphereMesh->setRadius(0.5f);
- m_sphereMesh->setRings(100);
- m_sphereMesh->setSlices(100);
-
- // Insert into scene
- if (q->entities().size() > 0) {
- Qt3DCore::QEntity *rootEntity = findRootEntity(q->entities().constFirst());
- m_debugSubtree->setParent(rootEntity ? rootEntity : q->entities().constFirst());
- }
- } else {
- // Just update the mesh
- m_transform->setTranslation(m_bvCenter);
- m_transform->setScale(m_bvRadius * 2.0f);
- }
-}
-
-} // Qt3DRender
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/render/frontend/qlayer.cpp b/src/render/frontend/qlayer.cpp
index e9f23a015..cd7d92caf 100644
--- a/src/render/frontend/qlayer.cpp
+++ b/src/render/frontend/qlayer.cpp
@@ -53,7 +53,38 @@ QLayerPrivate::QLayerPrivate()
\class Qt3DRender::QLayer
\inmodule Qt3DRender
\since 5.5
- \brief The QLayer class provides ...
+ \brief The QLayer class provides a way of filtering which entities will be rendered.
+
+ Qt3DRender::QLayer works in conjunction with the Qt3DRender::QLayerFilter in the FrameGraph.
+ \sa Qt3DRender::QLayerFilter
+
+ Qt3DRender::QLayer doesn't define any new properties but is supposed to only be referenced.
+
+ \code
+ #include <Qt3DCore/QEntity>
+ #include <Qt3DRender/QGeometryRenderer>
+ #include <Qt3DRender/QLayer>
+ #include <Qt3DRender/QLayerFilter>
+ #include <Qt3DRender/QViewport>
+
+ // Scene
+ Qt3DCore::QEntity *rootEntity = new Qt3DCore::Qt3DCore::QEntity;
+
+ Qt3DCore::QEntity *renderableEntity = new Qt3DCore::Qt3DCore::QEntity(rootEntity);
+ Qt3DRender::QGeometryRenderer *geometryRenderer = new Qt3DCore::QGeometryRenderer(renderableEntity);
+ Qt3DRender::QLayer *layer1 = new Qt3DCore::QLayer(renderableEntity);
+ renderableEntity->addComponent(geometryRenderer);
+ renderableEntity->addComponent(layer1);
+
+ ...
+
+ // FrameGraph
+ Qt3DRender::QViewport *viewport = new Qt3DRender::QViewport;
+ Qt3DRender::QLayerFilter *layerFilter = new Qt3DRender::QLayerFilter(viewport);
+ layerFilter->addLayer(layer1);
+
+ ...
+ \endcode
*/
/*!
@@ -62,7 +93,48 @@ QLayerPrivate::QLayerPrivate()
\inherits Component3D
\inqmlmodule Qt3D.Render
\since 5.5
- \brief For ...
+ \sa LayerFilter
+ \brief Layer provides a way of filtering which entities will be rendered.
+
+ Layer works in conjunction with the LayerFilter in the FrameGraph.
+
+ Layer doesn't define any new properties but is supposed to only be referenced.
+
+ \code
+ import Qt3D.Core 2.0
+ import Qt3D.Render 2.0
+
+ Entity {
+ id: root
+
+ components: RenderSettings {
+ // FrameGraph
+ Viewport {
+ ClearBuffers {
+ buffers: ClearBuffers.ColorDepthBuffer
+ CameraSelector {
+ camera: mainCamera
+ LayerFilter {
+ layers: [layer1]
+ }
+ }
+ }
+ }
+ }
+
+ // Scene
+ Camera { id: mainCamera }
+
+ Layer { id: layer1 }
+
+ GeometryRenderer { id: mesh }
+
+ Entity {
+ id: renderableEntity
+ components: [ mesh, layer1 ]
+ }
+ }
+ \endcode
*/
/*! \fn Qt3DRender::QLayer::QLayer(Qt3DCore::QNode *parent)
diff --git a/src/render/frontend/qrenderaspect.cpp b/src/render/frontend/qrenderaspect.cpp
index 03a939a13..5a8195b64 100644
--- a/src/render/frontend/qrenderaspect.cpp
+++ b/src/render/frontend/qrenderaspect.cpp
@@ -77,7 +77,6 @@
#include <Qt3DRender/qrendersurfaceselector.h>
#include <Qt3DRender/qrendersettings.h>
-#include <Qt3DRender/private/qboundingvolumedebug_p.h>
#include <Qt3DRender/private/cameraselectornode_p.h>
#include <Qt3DRender/private/layerfilternode_p.h>
#include <Qt3DRender/private/filterkey_p.h>
@@ -173,6 +172,9 @@ void QRenderAspectPrivate::registerBackendTypes()
{
Q_Q(QRenderAspect);
+ qRegisterMetaType<Qt3DRender::QBuffer*>();
+ qRegisterMetaType<Qt3DRender::QEffect*>();
+
q->registerBackendType<Qt3DCore::QEntity>(QSharedPointer<Render::RenderEntityFunctor>::create(m_renderer, m_nodeManagers));
q->registerBackendType<Qt3DCore::QTransform>(QSharedPointer<Render::NodeFunctor<Render::Transform, Render::TransformManager> >::create(m_renderer, m_nodeManagers->transformManager()));
@@ -222,7 +224,6 @@ void QRenderAspectPrivate::registerBackendTypes()
q->registerBackendType<QViewport>(QSharedPointer<Render::FrameGraphNodeFunctor<Render::ViewportNode, QViewport> >::create(m_renderer, m_nodeManagers->frameGraphManager()));
// Picking
- // q->registerBackendType<QBoundingVolumeDebug>(QSharedPointer<Render::NodeFunctor<Render::BoundingVolumeDebug, Render::BoundingVolumeDebugManager> >::create(m_renderer, m_nodeManagers->boundingVolumeDebugManager()));
q->registerBackendType<QObjectPicker>(QSharedPointer<Render::NodeFunctor<Render::ObjectPicker, Render::ObjectPickerManager> >::create(m_renderer, m_nodeManagers->objectPickerManager()));
}
@@ -278,7 +279,6 @@ void QRenderAspectPrivate::unregisterBackendTypes()
unregisterBackendType<QViewport>();
// Picking
- // unregisterBackendType<QBoundingVolumeDebug>();
unregisterBackendType<QObjectPicker>();
}
diff --git a/src/render/frontend/render-frontend.pri b/src/render/frontend/render-frontend.pri
index 5f5246518..829e3d756 100644
--- a/src/render/frontend/render-frontend.pri
+++ b/src/render/frontend/render-frontend.pri
@@ -10,7 +10,6 @@ HEADERS += \
$$PWD/qrendertarget.h \
$$PWD/qrendertarget_p.h \
$$PWD/sphere_p.h \
- $$PWD/qboundingvolumedebug_p.h \
$$PWD/qcamera_p.h \
$$PWD/qcamera.h \
$$PWD/qcameralens.h \
@@ -31,7 +30,6 @@ SOURCES += \
$$PWD/sphere.cpp \
$$PWD/qlayer.cpp \
$$PWD/qrendertarget.cpp \
- $$PWD/qboundingvolumedebug.cpp \
$$PWD/qcamera.cpp \
$$PWD/qcameralens.cpp \
$$PWD/qrendersettings.cpp \
diff --git a/src/render/geometry/qattribute.cpp b/src/render/geometry/qattribute.cpp
index 3067b0527..ef439f2b4 100644
--- a/src/render/geometry/qattribute.cpp
+++ b/src/render/geometry/qattribute.cpp
@@ -65,7 +65,12 @@ QAttributePrivate::QAttributePrivate()
* \qmltype Attribute
* \instantiates Qt3DRender::QAttribute
* \inqmlmodule Qt3D.Render
- * \brief Uncreatable
+ * \brief Defines an attribute and how data should be read from a Buffer.
+ *
+ * When providing your own attributes, it may make sense to name your attribute
+ * using helpers such as QAttribute::defaultPositionAttributeName() as that
+ * will ensure your geometry will be compatible with picking and the various
+ * materials provided in the Qt3DExtras module.
*/
/*!
@@ -74,6 +79,14 @@ QAttributePrivate::QAttributePrivate()
*
* \inherits Qt3DCore::QNode
*
+ * \brief Defines an attribute and how data should be read from a QBuffer.
+ *
+ * When providing your own attributes, it may make sense to name your attribute
+ * using helpers such as QAttribute::defaultPositionAttributeName() as that
+ * will ensure your geometry will be compatible with picking and the various
+ * materials provided in the Qt3DExtras module.
+ *
+ * \sa QBuffer.
*/
/*!
@@ -119,7 +132,7 @@ QAttribute::QAttribute(QNode *parent)
* and \a stride with \a parent.
*/
QAttribute::QAttribute(QBuffer *buf, VertexBaseType type, uint dataSize, uint count, uint offset, uint stride, QNode *parent)
- : QNode(*new QAttributePrivate(), parent)
+ : QAttribute(parent)
{
Q_D(QAttribute);
setBuffer(buf);
@@ -136,7 +149,7 @@ QAttribute::QAttribute(QBuffer *buf, VertexBaseType type, uint dataSize, uint co
* dataSize, \a count, \a offset, and \a stride with \a parent.
*/
QAttribute::QAttribute(QBuffer *buf, const QString &name, VertexBaseType type, uint dataSize, uint count, uint offset, uint stride, QNode *parent)
- : QNode(*new QAttributePrivate(), parent)
+ : QAttribute(parent)
{
Q_D(QAttribute);
setBuffer(buf);
diff --git a/src/render/geometry/qbuffer.cpp b/src/render/geometry/qbuffer.cpp
index 779f808f7..e63798027 100644
--- a/src/render/geometry/qbuffer.cpp
+++ b/src/render/geometry/qbuffer.cpp
@@ -59,6 +59,9 @@ QBufferPrivate::QBufferPrivate()
* \qmltype Buffer
* \instantiates Qt3DRender::QBuffer
* \inqmlmodule Qt3D.Render
+ *
+ * \brief Provides a data store for raw data to later be used as vertices or
+ * uniforms.
*/
/*!
@@ -89,6 +92,16 @@ QBufferPrivate::QBufferPrivate()
* \inmodule Qt3DRender
*
* \inherits Qt3DCore::QNode
+ *
+ * \brief Provides a data store for raw data to later be used as vertices or
+ * uniforms.
+ *
+ * Data can either be provided directly using QBuffer::setData() or by
+ * specifying a generator with QBuffer::setDataGenerator() and providing a
+ * Qt3DRender::QBufferDataGeneratorPtr.
+ *
+ * When using a generator the data will be loaded asynchronously in a job. The
+ * loaded data can be read back if the QBuffer::syncData flag is set to true.
*/
/*!
diff --git a/src/render/graphicshelpers/graphicscontext.cpp b/src/render/graphicshelpers/graphicscontext.cpp
index 5169c8fb4..acec8edf6 100644
--- a/src/render/graphicshelpers/graphicscontext.cpp
+++ b/src/render/graphicshelpers/graphicscontext.cpp
@@ -71,6 +71,7 @@
#include <Qt3DRender/private/graphicshelpergl4_p.h>
#endif
#include <Qt3DRender/private/graphicshelperes2_p.h>
+#include <Qt3DRender/private/graphicshelperes3_p.h>
#include <QSurface>
#include <QWindow>
@@ -285,7 +286,6 @@ void GraphicsContext::endDrawing(bool swapBuffers)
m_gl->swapBuffers(m_surface);
if (m_ownCurrent)
m_gl->doneCurrent();
- m_stateSet = nullptr;
decayTextureScores();
}
@@ -557,7 +557,7 @@ void GraphicsContext::bindFrameBufferAttachmentHelper(GLuint fboId, const Attach
if (fboSize.isEmpty())
fboSize = QSize(glTex->width(), glTex->height());
else
- fboSize = QSize(qMin(fboSize.width(), glTex->width()), qMin(fboSize.width(), glTex->width()));
+ fboSize = QSize(qMin(fboSize.width(), glTex->width()), qMin(fboSize.height(), glTex->height()));
m_glHelper->bindFrameBufferAttachment(glTex, attachment);
}
}
@@ -647,7 +647,10 @@ GraphicsHelperInterface *GraphicsContext::resolveHighestOpenGLFunctions()
GraphicsHelperInterface *glHelper = nullptr;
if (m_gl->isOpenGLES()) {
- glHelper = new GraphicsHelperES2();
+ if (m_gl->format().majorVersion() >= 3)
+ glHelper = new GraphicsHelperES3();
+ else
+ glHelper = new GraphicsHelperES2();
glHelper->initializeHelper(m_gl, nullptr);
qCDebug(Backend) << Q_FUNC_INFO << " Building OpenGL 2/ES2 Helper";
}
diff --git a/src/render/graphicshelpers/graphicshelperes2.cpp b/src/render/graphicshelpers/graphicshelperes2.cpp
index 6bf287cee..b09e33291 100644
--- a/src/render/graphicshelpers/graphicshelperes2.cpp
+++ b/src/render/graphicshelpers/graphicshelperes2.cpp
@@ -80,9 +80,6 @@ void GraphicsHelperES2::initializeHelper(QOpenGLContext *context,
Q_ASSERT(context);
m_funcs = context->functions();
Q_ASSERT(m_funcs);
- m_isES3 = context->format().majorVersion() >= 3;
- if (m_isES3)
- m_extraFuncs = QOpenGLContext::currentContext()->extraFunctions();
}
void GraphicsHelperES2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,
@@ -99,19 +96,11 @@ void GraphicsHelperES2::drawElementsInstancedBaseVertexBaseInstance(GLenum primi
if (baseVertex != 0)
qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 2";
- if (m_isES3 && m_extraFuncs) {
- m_extraFuncs->glDrawElementsInstanced(primitiveType,
- primitiveCount,
- indexType,
- indices,
- instances);
- } else {
- for (GLint i = 0; i < instances; i++)
- drawElements(primitiveType,
- primitiveCount,
- indexType,
- indices);
- }
+ for (GLint i = 0; i < instances; i++)
+ drawElements(primitiveType,
+ primitiveCount,
+ indexType,
+ indices);
}
void GraphicsHelperES2::drawArraysInstanced(GLenum primitiveType,
@@ -241,8 +230,8 @@ QVector<ShaderStorageBlock> GraphicsHelperES2::programShaderStorageBlocks(GLuint
void GraphicsHelperES2::vertexAttribDivisor(GLuint index, GLuint divisor)
{
- if (m_isES3 && m_extraFuncs)
- m_extraFuncs->glVertexAttribDivisor(index, divisor);
+ Q_UNUSED(index);
+ Q_UNUSED(divisor);
}
void GraphicsHelperES2::blendEquation(GLenum mode)
@@ -365,7 +354,7 @@ bool GraphicsHelperES2::supportsFeature(GraphicsHelperInterface::Feature feature
return false;
}
}
-void GraphicsHelperES2::drawBuffers(GLsizei , const int *)
+void GraphicsHelperES2::drawBuffers(GLsizei, const int *)
{
qWarning() << "drawBuffers is not supported by ES 2.0";
}
@@ -462,13 +451,8 @@ void GraphicsHelperES2::bindUniform(const QVariant &v, const ShaderUniform &desc
case GL_SAMPLER_CUBE_SHADOW:
case GL_SAMPLER_2D_ARRAY:
case GL_SAMPLER_2D_ARRAY_SHADOW:
- if (m_isES3) {
- Q_ASSERT(description.m_size == 1);
- m_funcs->glUniform1i(description.m_location, v.toInt());
- } else {
- qWarning() << Q_FUNC_INFO << "ES 3.0 uniform type" << description.m_type << "for"
- << description.m_name << "is not supported in ES 2.0";
- }
+ qWarning() << Q_FUNC_INFO << "ES 3.0 uniform type" << description.m_type << "for"
+ << description.m_name << "is not supported in ES 2.0";
break;
default:
diff --git a/src/render/graphicshelpers/graphicshelperes2_p.h b/src/render/graphicshelpers/graphicshelperes2_p.h
index 5f4413e09..df8f148a9 100644
--- a/src/render/graphicshelpers/graphicshelperes2_p.h
+++ b/src/render/graphicshelpers/graphicshelperes2_p.h
@@ -118,10 +118,8 @@ public:
uint uniformByteSize(const ShaderUniform &description) Q_DECL_OVERRIDE;
void useProgram(GLuint programId) Q_DECL_OVERRIDE;
void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE;
-private:
+protected:
QOpenGLFunctions *m_funcs;
- QOpenGLExtraFunctions *m_extraFuncs = nullptr;
- bool m_isES3;
};
} // namespace Render
diff --git a/src/render/graphicshelpers/graphicshelperes3.cpp b/src/render/graphicshelpers/graphicshelperes3.cpp
new file mode 100644
index 000000000..fe39d9d3f
--- /dev/null
+++ b/src/render/graphicshelpers/graphicshelperes3.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2016 Svenn-Arne Dragly.
+** 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 "graphicshelperes3_p.h"
+#include <private/attachmentpack_p.h>
+#include <QOpenGLExtraFunctions>
+
+QT_BEGIN_NAMESPACE
+
+// ES 3.0+
+#ifndef GL_SAMPLER_3D
+#define GL_SAMPLER_3D 0x8B5F
+#endif
+#ifndef GL_SAMPLER_2D_SHADOW
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#endif
+#ifndef GL_SAMPLER_CUBE_SHADOW
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#endif
+#ifndef GL_SAMPLER_2D_ARRAY
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#endif
+#ifndef GL_SAMPLER_2D_ARRAY_SHADOW
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#endif
+
+namespace Qt3DRender {
+namespace Render {
+
+GraphicsHelperES3::GraphicsHelperES3()
+{
+}
+
+GraphicsHelperES3::~GraphicsHelperES3()
+{
+}
+
+void GraphicsHelperES3::initializeHelper(QOpenGLContext *context,
+ QAbstractOpenGLFunctions *functions)
+{
+ GraphicsHelperES2::initializeHelper(context, functions);
+ m_extraFuncs = context->extraFunctions();
+ Q_ASSERT(m_extraFuncs);
+}
+
+void GraphicsHelperES3::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,
+ GLsizei primitiveCount,
+ GLint indexType,
+ void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLint baseInstance)
+{
+ if (baseInstance != 0)
+ qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 3";
+
+ if (baseVertex != 0)
+ qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 3";
+
+ m_extraFuncs->glDrawElementsInstanced(primitiveType,
+ primitiveCount,
+ indexType,
+ indices,
+ instances);
+}
+
+void GraphicsHelperES3::vertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ m_extraFuncs->glVertexAttribDivisor(index, divisor);
+}
+
+void GraphicsHelperES3::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment)
+{
+ GLenum attr = GL_COLOR_ATTACHMENT0;
+
+ if (attachment.m_point <= QRenderTargetOutput::Color15)
+ attr = GL_COLOR_ATTACHMENT0 + attachment.m_point;
+ else if (attachment.m_point == QRenderTargetOutput::Depth)
+ attr = GL_DEPTH_ATTACHMENT;
+ else if (attachment.m_point == QRenderTargetOutput::Stencil)
+ attr = GL_STENCIL_ATTACHMENT;
+ else
+ qCritical() << "Unsupported FBO attachment OpenGL ES 3.0";
+
+ texture->bind();
+ QOpenGLTexture::Target target = texture->target();
+ if (target == QOpenGLTexture::Target2D)
+ m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel);
+ else if (target == QOpenGLTexture::TargetCubeMap)
+ m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
+ else
+ qCritical() << "Unsupported Texture FBO attachment format";
+ texture->release();
+}
+
+bool GraphicsHelperES3::supportsFeature(GraphicsHelperInterface::Feature feature) const
+{
+ switch (feature) {
+ case RenderBufferDimensionRetrieval:
+ case MRT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void GraphicsHelperES3::drawBuffers(GLsizei n, const int *bufs)
+{
+ QVarLengthArray<GLenum, 16> drawBufs(n);
+
+ for (int i = 0; i < n; i++)
+ drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i];
+ m_extraFuncs->glDrawBuffers(n, drawBufs.constData());
+}
+
+void GraphicsHelperES3::bindUniform(const QVariant &v, const ShaderUniform &description)
+{
+ switch (description.m_type) {
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ Q_ASSERT(description.m_size == 1);
+ m_funcs->glUniform1i(description.m_location, v.toInt());
+ break;
+ default:
+ GraphicsHelperES2::bindUniform(v, description);
+ break;
+ }
+}
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/render/frontend/qboundingvolumedebug_p.h b/src/render/graphicshelpers/graphicshelperes3_p.h
index 8ffe556b5..e5bb51c53 100644
--- a/src/render/frontend/qboundingvolumedebug_p.h
+++ b/src/render/graphicshelpers/graphicshelperes3_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2016 Svenn-Arne Dragly.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
@@ -37,10 +38,8 @@
**
****************************************************************************/
-#if 0
-
-#ifndef QT3DRENDER_QBOUNDINGVOLUMEDEBUG_P_H
-#define QT3DRENDER_QBOUNDINGVOLUMEDEBUG_P_H
+#ifndef QT3DRENDER_RENDER_GRAPHICSHELPERES3_H
+#define QT3DRENDER_RENDER_GRAPHICSHELPERES3_H
//
// W A R N I N G
@@ -53,46 +52,34 @@
// We mean it.
//
-#include <Qt3DCore/qcomponent.h>
-#include <Qt3DRender/qt3drender_global.h>
+#include <Qt3DRender/private/graphicshelperes2_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
+namespace Render {
-class QGeometry;
-class QBoundingVolumeDebugPrivate;
-
-class QT3DRENDERSHARED_EXPORT QBoundingVolumeDebug : public Qt3DCore::QComponent
+class GraphicsHelperES3 : public GraphicsHelperES2
{
- Q_OBJECT
- Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
-
public:
- explicit QBoundingVolumeDebug(Qt3DCore::QNode *parent = nullptr);
- ~QBoundingVolumeDebug();
-
- bool recursive() const;
-
-public Q_SLOTS:
- void setRecursive(bool recursive);
-
-Q_SIGNALS:
- void recursiveChanged(bool recursive);
-
+ GraphicsHelperES3();
+ virtual ~GraphicsHelperES3();
+
+ // QGraphicHelperInterface interface
+ virtual void bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment) Q_DECL_OVERRIDE;
+ virtual void bindUniform(const QVariant &v, const ShaderUniform &description) Q_DECL_OVERRIDE;
+ virtual void drawBuffers(GLsizei n, const int *bufs) Q_DECL_OVERRIDE;
+ virtual void drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType, GLsizei primitiveCount, GLint indexType, void *indices, GLsizei instances, GLint baseVertex = 0, GLint baseInstance = 0) Q_DECL_OVERRIDE;
+ virtual void initializeHelper(QOpenGLContext *context, QAbstractOpenGLFunctions *functions) Q_DECL_OVERRIDE;
+ virtual bool supportsFeature(Feature feature) const Q_DECL_OVERRIDE;
+ virtual void vertexAttribDivisor(GLuint index, GLuint divisor) Q_DECL_OVERRIDE;
protected:
- void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE;
-
-private:
- Q_DECLARE_PRIVATE(QBoundingVolumeDebug)
-
- // TODO: Handle creation changes
+ QOpenGLExtraFunctions *m_extraFuncs = Q_NULLPTR;
};
-} // Qt3DRender
+} // namespace Render
+} // namespace Qt3DRender
QT_END_NAMESPACE
-#endif // QT3DRENDER_QBOUNDINGVOLUMEDEBUG_P_H
-
-#endif
+#endif // QT3DRENDER_RENDER_GRAPHICSHELPERES3_H
diff --git a/src/render/graphicshelpers/graphicshelpers.pri b/src/render/graphicshelpers/graphicshelpers.pri
index a5dcbe808..ecf2e6b54 100644
--- a/src/render/graphicshelpers/graphicshelpers.pri
+++ b/src/render/graphicshelpers/graphicshelpers.pri
@@ -6,6 +6,7 @@ HEADERS += \
$$PWD/graphicscontext_p.h \
$$PWD/graphicshelperinterface_p.h \
$$PWD/graphicshelperes2_p.h \
+ $$PWD/graphicshelperes3_p.h \
$$PWD/graphicshelpergl2_p.h \
$$PWD/graphicshelpergl3_p.h \
$$PWD/graphicshelpergl3_3_p.h \
@@ -14,6 +15,7 @@ HEADERS += \
SOURCES += \
$$PWD/graphicscontext.cpp \
$$PWD/graphicshelperes2.cpp \
+ $$PWD/graphicshelperes3.cpp \
$$PWD/graphicshelpergl2.cpp \
$$PWD/graphicshelpergl3.cpp \
$$PWD/graphicshelpergl3_3.cpp \
diff --git a/src/render/io/qsceneloader.cpp b/src/render/io/qsceneloader.cpp
index 215f8edd0..2d0c3311c 100644
--- a/src/render/io/qsceneloader.cpp
+++ b/src/render/io/qsceneloader.cpp
@@ -67,6 +67,28 @@ QSceneLoaderPrivate::QSceneLoaderPrivate()
\brief Provides the facility to load an existing Scene
+ Given a 3D source file, the Qt3DRender::QSceneLoader will try to parse it and
+ build a tree of Qt3DCore::QEntity with proper Qt3DRender::QGeometryRenderer
+ Qt3DCore::QTransform and QtRender::QMaterial components.
+
+ The loader will try to determine the best material to be used based on the properties
+ of the model file. If you wish to use a custom material, you will have to traverse
+ the tree and replace the default associated materials with yours.
+
+ As the name implies, Qt3DRender::QSceneLoader loads a complete scene subtree.
+ If you wish to load a single piece of geometry, you should rather be using
+ the Qt3DRender::QMesh instead.
+
+ Qt3DRender::QSceneLoader internally relies on the use of plugins to support a
+ wide variety of 3D file formats. \l
+ {http://www.assimp.org/main_features_formats.html}{Here} is a list of formats
+ that are supported by Qt3D.
+
+ \note this component shouldn't be shared among several Qt3DCore::QEntity instances.
+ Undefined behavior will result.
+
+ \sa Qt3DRender::QMesh
+ \sa Qt3DRender::QGeometryRenderer
*/
/*!
@@ -76,16 +98,40 @@ QSceneLoaderPrivate::QSceneLoaderPrivate()
\inherits Component
\since 5.7
\qmlabstract Provides the facility to load an existing Scene
+
+ Given a 3D source file, the SceneLoader will try to parse it and build a
+ tree of Entity with proper GeometryRenderer, Transform and Material
+ components.
+
+ The loader will try to determine the best material to be used based on the
+ properties of the model file. If you wish to use a custom material, you
+ will have to traverse the tree and replace the default associated materials
+ with yours.
+
+ As the name implies, SceneLoader loads a complete scene subtree. If you
+ wish to load a single piece of geometry, you should rather be using the
+ Mesh instead.
+
+ SceneLoader internally relies on the use of plugins to support a wide
+ variety of 3D file formats. \l
+ {http://www.assimp.org/main_features_formats.html}{Here} is a list of
+ formats that are supported by Qt3D.
+
+ \note this component shouldn't be shared among several Entity instances.
+ Undefined behavior will result.
+
+ \sa Mesh
+ \sa GeometryRenderer
*/
/*!
\enum QSceneLoader::Status
This enum identifies the state of loading
- \value None
- \value Loading
- \value Ready
- \value Error
+ \value None The Qt3DRender::QSceneLoader hasn't been used yet.
+ \value Loading The Qt3DRender::QSceneLoader is currently loading the scene file.
+ \value Ready The Qt3DRender::QSceneLoader successfully loaded the scene file.
+ \value Error The Qt3DRender::QSceneLoader encountered an error while loading the scene file.
*/
/*!
diff --git a/src/render/jobs/filterlayerentityjob.cpp b/src/render/jobs/filterlayerentityjob.cpp
index 5e3536cf2..d22b61337 100644
--- a/src/render/jobs/filterlayerentityjob.cpp
+++ b/src/render/jobs/filterlayerentityjob.cpp
@@ -93,6 +93,10 @@ void FilterLayerEntityJob::filterLayerAndEntity()
for (const HEntity handle : handles) {
Entity *entity = entityManager->data(handle);
+
+ if (!entity->isEnabled())
+ continue;
+
const Qt3DCore::QNodeIdVector entityLayers = entity->componentsUuid<Layer>();
// An Entity is positively filtered if it contains at least one Layer component with the same id as the
@@ -114,8 +118,11 @@ void FilterLayerEntityJob::selectAllEntities()
const QVector<HEntity> handles = entityManager->activeHandles();
m_filteredEntities.reserve(handles.size());
- for (const HEntity handle : handles)
- m_filteredEntities.push_back(entityManager->data(handle));
+ for (const HEntity handle : handles) {
+ Entity *e = entityManager->data(handle);
+ if (e->isEnabled())
+ m_filteredEntities.push_back(e);
+ }
}
} // Render
diff --git a/src/render/jobs/frustumcullingjob_p.h b/src/render/jobs/frustumcullingjob_p.h
index 087b7687c..cb4b38b2b 100644
--- a/src/render/jobs/frustumcullingjob_p.h
+++ b/src/render/jobs/frustumcullingjob_p.h
@@ -62,7 +62,7 @@ namespace Render {
class Entity;
class EntityManager;
-class Plane;
+struct Plane;
class FrustumCullingJob : public Qt3DCore::QAspectJob
{
diff --git a/src/render/jobs/loadscenejob.cpp b/src/render/jobs/loadscenejob.cpp
index d0d8be9ef..758e0b135 100644
--- a/src/render/jobs/loadscenejob.cpp
+++ b/src/render/jobs/loadscenejob.cpp
@@ -63,23 +63,29 @@ void LoadSceneJob::run()
{
// Iterate scene IO handlers until we find one that can handle this file type
Qt3DCore::QEntity *sceneSubTree = nullptr;
- for (QSceneIOHandler *sceneIOHandler : qAsConst(m_sceneIOHandlers)) {
- if (!sceneIOHandler->isFileTypeSupported(m_source))
- continue;
- // File type is supported, try to load it
- sceneIOHandler->setSource(m_source);
- Qt3DCore::QEntity *sub = sceneIOHandler->scene();
- if (sub) {
- sceneSubTree = sub;
- break;
+ // Perform the loading only if the source wasn't explicitly set to empty
+ if (!m_source.isEmpty()) {
+ for (QSceneIOHandler *sceneIOHandler : qAsConst(m_sceneIOHandlers)) {
+ if (!sceneIOHandler->isFileTypeSupported(m_source))
+ continue;
+
+ // File type is supported, try to load it
+ sceneIOHandler->setSource(m_source);
+ Qt3DCore::QEntity *sub = sceneIOHandler->scene();
+ if (sub) {
+ sceneSubTree = sub;
+ break;
+ }
}
}
-
// Set clone of sceneTree in sceneComponent. This will move the sceneSubTree
// to the QCoreApplication thread which is where the frontend object tree lives.
Scene *scene = m_managers->sceneManager()->lookupResource(m_sceneComponent);
- if (scene && sceneSubTree)
+
+ // If the sceneSubTree is null it will trigger the frontend to unload
+ // any subtree it may hold
+ if (scene)
scene->setSceneSubtree(sceneSubTree);
}
diff --git a/src/render/jobs/pickboundingvolumejob.cpp b/src/render/jobs/pickboundingvolumejob.cpp
index 5c713e1a7..11faf5138 100644
--- a/src/render/jobs/pickboundingvolumejob.cpp
+++ b/src/render/jobs/pickboundingvolumejob.cpp
@@ -118,6 +118,15 @@ private:
return vca;
}
+ bool isUnique(const QVector<ViewportCameraAreaTriplet> &vcaTriplets, const ViewportCameraAreaTriplet &vca) const
+ {
+ for (const ViewportCameraAreaTriplet &triplet : vcaTriplets) {
+ if (vca.cameraId == triplet.cameraId && vca.viewport == triplet.viewport && vca.area == triplet.area)
+ return false;
+ }
+ return true;
+ }
+
public:
QVector<ViewportCameraAreaTriplet> gather(FrameGraphNode *root)
{
@@ -129,7 +138,7 @@ public:
// Find all viewport/camera pairs by traversing from leaf to root
for (Render::FrameGraphNode *leaf : qAsConst(m_leaves)) {
ViewportCameraAreaTriplet vcaTriplet = gatherUpViewportCameraAreas(leaf);
- if (!vcaTriplet.cameraId.isNull())
+ if (!vcaTriplet.cameraId.isNull() && isUnique(vcaTriplets, vcaTriplet))
vcaTriplets.push_back(vcaTriplet);
}
return vcaTriplets;
@@ -519,11 +528,12 @@ void PickBoundingVolumeJob::run()
}
case QEvent::MouseButtonRelease: {
- // Send release event to m_currentPicker
- if (lastCurrentPicker != nullptr) {
+ if (lastCurrentPicker != nullptr && m_currentPicker == objectPickerHandle)
m_currentPicker = HObjectPicker();
- lastCurrentPicker->onClicked(pickEvent);
- lastCurrentPicker->onReleased(pickEvent);
+ // Only send the release event if it was pressed
+ if (objectPicker->isPressed()) {
+ objectPicker->onClicked(pickEvent);
+ objectPicker->onReleased(pickEvent);
}
break;
}
diff --git a/src/render/jobs/renderviewinitializerjob_p.h b/src/render/jobs/renderviewinitializerjob_p.h
index 35620bc65..dbc80c162 100644
--- a/src/render/jobs/renderviewinitializerjob_p.h
+++ b/src/render/jobs/renderviewinitializerjob_p.h
@@ -54,7 +54,6 @@
#include <Qt3DCore/qaspectjob.h>
#include <Qt3DCore/private/qframeallocator_p.h>
-#include <QThreadStorage>
#include <QSize>
QT_BEGIN_NAMESPACE
diff --git a/src/render/materialsystem/qgraphicsapifilter.cpp b/src/render/materialsystem/qgraphicsapifilter.cpp
index 5a52ff0fd..119a294ac 100644
--- a/src/render/materialsystem/qgraphicsapifilter.cpp
+++ b/src/render/materialsystem/qgraphicsapifilter.cpp
@@ -55,20 +55,36 @@ GraphicsApiFilterData::GraphicsApiFilterData()
bool GraphicsApiFilterData::operator ==(const GraphicsApiFilterData &other) const
{
- if (other.m_api == m_api
- && other.m_profile <= m_profile
- && (other.m_major < m_major
- || (other.m_major == m_major && other.m_minor <= m_minor))) {
- for (const QString &neededExt : other.m_extensions)
- if (!m_extensions.contains(neededExt))
- return false;
- // If a vendor name was specified in sample, we perform comparison,
- // otherwise we assume the vendor name doesn't matter
- if (!other.m_vendor.isEmpty())
- return (other.m_vendor == m_vendor);
- return true;
+ // Check API
+ if (other.m_api != m_api)
+ return false;
+
+ // Check versions
+ const bool versionsCompatible = other.m_major < m_major
+ || (other.m_major == m_major && other.m_minor <= m_minor);
+ if (!versionsCompatible)
+ return false;
+
+ // Check profiles if requiring OpenGL (profiles not relevant for OpenGL ES)
+ if (other.m_api == QGraphicsApiFilter::OpenGL) {
+ const bool profilesCompatible = m_profile != QGraphicsApiFilter::CoreProfile
+ || other.m_profile == m_profile;
+ if (!profilesCompatible)
+ return false;
}
- return false;
+
+ // Check extensions
+ for (const QString &neededExt : other.m_extensions) {
+ if (!m_extensions.contains(neededExt))
+ return false;
+ }
+
+ // Check vendor
+ if (!other.m_vendor.isEmpty())
+ return (other.m_vendor == m_vendor);
+
+ // If we get here everything looks good :)
+ return true;
}
bool GraphicsApiFilterData::operator <(const GraphicsApiFilterData &other) const
diff --git a/src/render/materialsystem/qgraphicsapifilter.h b/src/render/materialsystem/qgraphicsapifilter.h
index d09c2f753..c618358dd 100644
--- a/src/render/materialsystem/qgraphicsapifilter.h
+++ b/src/render/materialsystem/qgraphicsapifilter.h
@@ -95,8 +95,8 @@ public Q_SLOTS:
void setVendor(const QString &vendor);
Q_SIGNALS:
- void apiChanged(Api api);
- void profileChanged(OpenGLProfile profile);
+ void apiChanged(Qt3DRender::QGraphicsApiFilter::Api api);
+ void profileChanged(Qt3DRender::QGraphicsApiFilter::OpenGLProfile profile);
void minorVersionChanged(int minorVersion);
void majorVersionChanged(int majorVersion);
void extensionsChanged(const QStringList &extensions);
@@ -107,8 +107,8 @@ private:
Q_DECLARE_PRIVATE(QGraphicsApiFilter)
};
-bool operator ==(const QGraphicsApiFilter &reference, const QGraphicsApiFilter &sample);
-bool operator !=(const QGraphicsApiFilter &reference, const QGraphicsApiFilter &sample);
+Q_AUTOTEST_EXPORT bool operator ==(const QGraphicsApiFilter &reference, const QGraphicsApiFilter &sample);
+Q_AUTOTEST_EXPORT bool operator !=(const QGraphicsApiFilter &reference, const QGraphicsApiFilter &sample);
} // namespace Qt3DRender
diff --git a/src/render/picking/qobjectpicker.cpp b/src/render/picking/qobjectpicker.cpp
index 29912fa79..1842b7fee 100644
--- a/src/render/picking/qobjectpicker.cpp
+++ b/src/render/picking/qobjectpicker.cpp
@@ -313,7 +313,7 @@ void QObjectPickerPrivate::propagateEvent(QPickEvent *event, EventType type)
if (!m_entities.isEmpty()) {
Qt3DCore::QEntity *entity = m_entities.first();
Qt3DCore::QEntity *parentEntity = nullptr;
- while (entity != nullptr && entity->parent() != nullptr && !event->isAccepted()) {
+ while (entity != nullptr && entity->parentEntity() != nullptr && !event->isAccepted()) {
parentEntity = entity->parentEntity();
const auto components = parentEntity->components();
for (Qt3DCore::QComponent *c : components) {
diff --git a/src/render/renderstates/renderstatenode.cpp b/src/render/renderstates/renderstatenode.cpp
index 47e82a9bd..d1698e4b6 100644
--- a/src/render/renderstates/renderstatenode.cpp
+++ b/src/render/renderstates/renderstatenode.cpp
@@ -63,7 +63,7 @@ void RenderStateNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBaseP
{
cleanup();
const auto renderStateChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChangeBase>(change);
- m_impl = std::move(RenderStateSet::initializeStateFromPeer(renderStateChange));
+ m_impl = RenderStateSet::initializeStateFromPeer(renderStateChange);
}
void RenderStateNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
diff --git a/src/render/renderstates/renderstateset.cpp b/src/render/renderstates/renderstateset.cpp
index ffe7f6ee8..992d649e8 100644
--- a/src/render/renderstates/renderstateset.cpp
+++ b/src/render/renderstates/renderstateset.cpp
@@ -94,7 +94,6 @@ namespace Render {
RenderStateSet::RenderStateSet()
: m_stateMask(0)
- , m_cachedPrevious(0)
{
}
@@ -153,24 +152,15 @@ void RenderStateSet::apply(GraphicsContext *gc)
}
qCDebug(RenderStates) << " current states " << QString::number(stateMask(), 2) << "inverse " << QString::number(invOurState, 2) << " -> states to change: " << QString::number(stateToReset, 2);
+ // Reset states that aren't active in the current state set
resetMasked(stateToReset, gc);
- if (m_cachedPrevious && previousStates == m_cachedPrevious) {
- // state-change cache hit
- for (const StateVariant &ds : qAsConst(m_cachedDeltaStates))
- ds.apply(gc);
- } else {
- // compute deltas and cache for next frame
- m_cachedDeltaStates.clear();
- m_cachedPrevious = previousStates;
-
- for (const StateVariant &ds : qAsConst(m_states)) {
- if (previousStates && previousStates->contains(ds))
- continue;
-
- m_cachedDeltaStates.push_back(ds);
- ds.apply(gc);
- }
+ // Apply states that weren't in the previous state or that have
+ // different values
+ for (const StateVariant &ds : qAsConst(m_states)) {
+ if (previousStates && previousStates->contains(ds))
+ continue;
+ ds.apply(gc);
}
}
diff --git a/src/render/renderstates/renderstateset_p.h b/src/render/renderstates/renderstateset_p.h
index 96af97f84..307e0ff1d 100644
--- a/src/render/renderstates/renderstateset_p.h
+++ b/src/render/renderstates/renderstateset_p.h
@@ -114,9 +114,7 @@ private:
bool contains(const StateVariant &ds) const;
StateMaskSet m_stateMask;
- RenderStateSet* m_cachedPrevious;
QVector<StateVariant> m_states;
- QVector<StateVariant> m_cachedDeltaStates;
};
template<>
diff --git a/src/render/renderstates/statevariant.cpp b/src/render/renderstates/statevariant.cpp
index 7a47d429e..f472d9920 100644
--- a/src/render/renderstates/statevariant.cpp
+++ b/src/render/renderstates/statevariant.cpp
@@ -79,7 +79,7 @@ void StateVariant::apply(GraphicsContext *gc) const
data.scissorTest.apply(gc);
return;
case StencilTestStateMask:
- data.scissorTest.apply(gc);
+ data.stencilTest.apply(gc);
return;
case AlphaCoverageStateMask:
data.alphaCoverage.apply(gc);
diff --git a/src/render/texture/qtexture.cpp b/src/render/texture/qtexture.cpp
index 09ace37d0..13e6a04ab 100644
--- a/src/render/texture/qtexture.cpp
+++ b/src/render/texture/qtexture.cpp
@@ -954,6 +954,7 @@ bool QTextureFromSourceGenerator::operator ==(const QTextureGenerator &other) co
QTextureFromSourceGenerator::QTextureFromSourceGenerator(const QUrl &url)
: QTextureGenerator()
, m_url(url)
+ , m_status(QAbstractTexture::None)
{
}
diff --git a/src/render/texture/qtextureimage.cpp b/src/render/texture/qtextureimage.cpp
index cc8d7acfe..dab92082a 100644
--- a/src/render/texture/qtextureimage.cpp
+++ b/src/render/texture/qtextureimage.cpp
@@ -170,6 +170,7 @@ void QTextureImage::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change)
QImageTextureDataFunctor::QImageTextureDataFunctor(const QUrl &url)
: QTextureImageDataGenerator()
, m_url(url)
+ , m_status(QTextureImage::None)
{
if (url.isLocalFile()) {
QFileInfo info(url.toLocalFile());