Renderer: launch proximity filter job

Also added a manual test example

Change-Id: Ib560dcfdd5e0996cb40d892886c94212e3f8e32d
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
This commit is contained in:
Paul Lemire 2017-08-18 15:32:48 +02:00
parent 4885783db8
commit 5fc71fa768
11 changed files with 279 additions and 8 deletions

View File

@ -153,6 +153,9 @@ public:
inline void appendLayerFilter(const Qt3DCore::QNodeId layerFilterId) Q_DECL_NOTHROW { m_data.m_layerFilterIds.push_back(layerFilterId); }
inline Qt3DCore::QNodeIdVector layerFilters() const Q_DECL_NOTHROW { return m_data.m_layerFilterIds; }
inline void appendProximityFilterId(const Qt3DCore::QNodeId proximityFilterId) { m_data.m_proximityFilterIds.push_back(proximityFilterId); }
inline Qt3DCore::QNodeIdVector proximityFilterIds() const { return m_data.m_proximityFilterIds; }
inline void setRenderPassFilter(const RenderPassFilter *rpFilter) Q_DECL_NOTHROW { m_data.m_passFilter = rpFilter; }
inline const RenderPassFilter *renderPassFilter() const Q_DECL_NOTHROW { return m_data.m_passFilter; }
@ -247,6 +250,7 @@ public:
Qt3DCore::QNodeIdVector m_layerFilterIds;
QVector<Qt3DRender::QSortPolicy::SortType> m_sortingTypes;
QVector3D m_eyePos;
Qt3DCore::QNodeIdVector m_proximityFilterIds;
};
bool isDownloadBuffersEnable() const;

View File

@ -123,11 +123,13 @@ public:
explicit SyncRenderViewInitialization(const RenderViewInitializerJobPtr &renderViewJob,
const FrustumCullingJobPtr &frustumCullingJob,
const FilterLayerEntityJobPtr &filterEntityByLayerJob,
const FilterProximityDistanceJobPtr &filterProximityJob,
const QVector<MaterialParameterGathererJobPtr> &materialGathererJobs,
const QVector<RenderViewBuilderJobPtr> &renderViewBuilderJobs)
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCullingJob)
, m_filterEntityByLayerJob(filterEntityByLayerJob)
, m_filterProximityJob(filterProximityJob)
, m_materialGathererJobs(materialGathererJobs)
, m_renderViewBuilderJobs(renderViewBuilderJobs)
{}
@ -139,6 +141,9 @@ public:
// Layer filtering
m_filterEntityByLayerJob->setLayerFilters(rv->layerFilters());
// Proximity filtering
m_filterProximityJob->setProximityFilterIds(rv->proximityFilterIds());
// Material Parameter building
for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
materialGatherer->setRenderPassFilter(const_cast<RenderPassFilter *>(rv->renderPassFilter()));
@ -157,6 +162,7 @@ private:
RenderViewInitializerJobPtr m_renderViewJob;
FrustumCullingJobPtr m_frustumCullingJob;
FilterLayerEntityJobPtr m_filterEntityByLayerJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
QVector<MaterialParameterGathererJobPtr> m_materialGathererJobs;
QVector<RenderViewBuilderJobPtr> m_renderViewBuilderJobs;
};
@ -167,6 +173,7 @@ public:
explicit SyncRenderCommandBuilding(const RenderViewInitializerJobPtr &renderViewJob,
const FrustumCullingJobPtr &frustumCullingJob,
const FilterLayerEntityJobPtr &filterEntityByLayerJob,
const FilterProximityDistanceJobPtr &filterProximityJob,
const LightGathererPtr &lightGathererJob,
const RenderableEntityFilterPtr &renderableEntityFilterJob,
const ComputableEntityFilterPtr &computableEntityFilterJob,
@ -175,6 +182,7 @@ public:
: m_renderViewJob(renderViewJob)
, m_frustumCullingJob(frustumCullingJob)
, m_filterEntityByLayerJob(filterEntityByLayerJob)
, m_filterProximityJob(filterProximityJob)
, m_lightGathererJob(lightGathererJob)
, m_renderableEntityFilterJob(renderableEntityFilterJob)
, m_computableEntityFilterJob(computableEntityFilterJob)
@ -204,7 +212,7 @@ public:
std::sort(renderableEntities.begin(), renderableEntities.end());
// Remove all entities from the compute and renderable vectors that aren't in the filtered layer vector
QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities();
const QVector<Entity *> filteredEntities = m_filterEntityByLayerJob->filteredEntities();
RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, filteredEntities);
// Set the light sources, with layer filters applied.
@ -215,9 +223,13 @@ public:
}
rv->setLightSources(lightSources);
if (isDraw) {
// Filter out frustum culled entity for drawable entities
if (isDraw && rv->frustumCulling())
if (rv->frustumCulling())
RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, m_frustumCullingJob->visibleEntities());
// Filter out entities which didn't satisfy proximity filtering
RenderViewBuilder::removeEntitiesNotInSubset(renderableEntities, m_filterProximityJob->filteredEntities());
}
// Split among the number of command builders
int i = 0;
@ -243,6 +255,7 @@ private:
RenderViewInitializerJobPtr m_renderViewJob;
FrustumCullingJobPtr m_frustumCullingJob;
FilterLayerEntityJobPtr m_filterEntityByLayerJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
LightGathererPtr m_lightGathererJob;
RenderableEntityFilterPtr m_renderableEntityFilterJob;
ComputableEntityFilterPtr m_computableEntityFilterJob;
@ -284,10 +297,12 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
, m_frustumCullingJob(Render::FrustumCullingJobPtr::create())
, m_syncFrustumCullingJob(SynchronizerJobPtr::create(SyncFrustumCulling(m_renderViewJob, m_frustumCullingJob), JobTypes::SyncFrustumCulling))
, m_setClearDrawBufferIndexJob(SynchronizerJobPtr::create(SetClearDrawBufferIndex(m_renderViewJob), JobTypes::ClearBufferDrawIndex))
, m_filterProximityJob(Render::FilterProximityDistanceJobPtr::create())
{
// Init what we can here
EntityManager *entityManager = m_renderer->nodeManagers()->renderNodesManager();
m_filterEntityByLayerJob->setManager(m_renderer->nodeManagers());
m_filterProximityJob->setManager(m_renderer->nodeManagers());
m_renderableEntityFilterJob->setManager(entityManager);
m_computableEntityFilterJob->setManager(entityManager);
m_frustumCullingJob->setRoot(m_renderer->sceneRoot());
@ -325,6 +340,7 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
m_syncRenderViewInitializationJob = SynchronizerJobPtr::create(SyncRenderViewInitialization(m_renderViewJob,
m_frustumCullingJob,
m_filterEntityByLayerJob,
m_filterProximityJob,
m_materialGathererJobs,
m_renderViewBuilderJobs),
JobTypes::SyncRenderViewInitialization);
@ -332,6 +348,7 @@ RenderViewBuilder::RenderViewBuilder(Render::FrameGraphNode *leafNode, int rende
m_syncRenderCommandBuildingJob = SynchronizerJobPtr::create(SyncRenderCommandBuilding(m_renderViewJob,
m_frustumCullingJob,
m_filterEntityByLayerJob,
m_filterProximityJob,
m_lightGathererJob,
m_renderableEntityFilterJob,
m_computableEntityFilterJob,
@ -410,6 +427,11 @@ SynchronizerJobPtr RenderViewBuilder::setClearDrawBufferIndexJob() const
return m_setClearDrawBufferIndexJob;
}
FilterProximityDistanceJobPtr RenderViewBuilder::filterProximityJob() const
{
return m_filterProximityJob;
}
QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
{
QVector<Qt3DCore::QAspectJobPtr> jobs;
@ -436,6 +458,9 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_filterEntityByLayerJob->addDependency(m_syncRenderViewInitializationJob);
m_filterEntityByLayerJob->addDependency(m_renderer->updateTreeEnabledJob());
m_filterProximityJob->addDependency(m_renderer->expandBoundingVolumeJob());
m_filterProximityJob->addDependency(m_syncRenderViewInitializationJob);
m_syncRenderCommandBuildingJob->addDependency(m_syncRenderViewInitializationJob);
for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) {
materialGatherer->addDependency(m_syncRenderViewInitializationJob);
@ -445,6 +470,7 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
m_syncRenderCommandBuildingJob->addDependency(m_renderableEntityFilterJob);
m_syncRenderCommandBuildingJob->addDependency(m_computableEntityFilterJob);
m_syncRenderCommandBuildingJob->addDependency(m_filterEntityByLayerJob);
m_syncRenderCommandBuildingJob->addDependency(m_filterProximityJob);
m_syncRenderCommandBuildingJob->addDependency(m_lightGathererJob);
m_syncRenderCommandBuildingJob->addDependency(m_frustumCullingJob);
@ -468,6 +494,7 @@ QVector<Qt3DCore::QAspectJobPtr> RenderViewBuilder::buildJobHierachy() const
jobs.push_back(m_syncFrustumCullingJob); // Step 3
jobs.push_back(m_filterEntityByLayerJob); // Step 3
jobs.push_back(m_filterProximityJob); // Step 3
jobs.push_back(m_setClearDrawBufferIndexJob); // Step 3
for (const auto &materialGatherer : qAsConst(m_materialGathererJobs)) // Step3

View File

@ -62,6 +62,7 @@
#include <Qt3DRender/private/renderview_p.h>
#include <Qt3DRender/private/frustumcullingjob_p.h>
#include <Qt3DRender/private/lightgatherer_p.h>
#include <Qt3DRender/private/filterproximitydistancejob_p.h>
QT_BEGIN_NAMESPACE
@ -93,6 +94,7 @@ public:
SynchronizerJobPtr syncRenderCommandBuildingJob() const;
SynchronizerJobPtr syncRenderViewCommandBuildersJob() const;
SynchronizerJobPtr setClearDrawBufferIndexJob() const;
FilterProximityDistanceJobPtr filterProximityJob() const;
QVector<Qt3DCore::QAspectJobPtr> buildJobHierachy() const;
@ -120,6 +122,7 @@ private:
SynchronizerJobPtr m_syncRenderCommandBuildingJob;
SynchronizerJobPtr m_syncRenderViewCommandBuildersJob;
SynchronizerJobPtr m_setClearDrawBufferIndexJob;
FilterProximityDistanceJobPtr m_filterProximityJob;
static const int m_optimalParallelJobCount;
};

View File

@ -121,6 +121,10 @@ void setRenderViewConfigFromFrameGraphLeafNode(RenderView *rv, const FrameGraphN
rv->appendLayerFilter(static_cast<const LayerFilterNode *>(node)->peerId());
break;
case FrameGraphNode::ProximityFilter: // Can be set multiple times in the tree
rv->appendProximityFilterId(node->peerId());
break;
case FrameGraphNode::RenderPassFilter:
// Can be set once
// TODO: Amalgamate all render pass filters from leaf to root

View File

@ -60,7 +60,7 @@ private Q_SLOTS:
renderer.setSettings(&settings);
renderer.initialize();
const int singleRenderViewJobCount = 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount();
const int singleRenderViewJobCount = 12 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount();
// RenderViewBuilder renderViewJob,
// renderableEntityFilterJob,
// lightGatherJob,
@ -68,6 +68,7 @@ private Q_SLOTS:
// syncRenderViewInitializationJob,
// syncFrustumCullingJob,
// filterEntityByLayerJob,
// filterProximityJob,
// setClearDrawBufferIndexJob,
// frustumCullingJob,
// syncRenderCommandBuldingJob,

View File

@ -199,7 +199,7 @@ private Q_SLOTS:
QCOMPARE(renderViewBuilder.renderViewBuilderJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
QCOMPARE(renderViewBuilder.materialGathererJobs().size(), Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 11 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
QCOMPARE(renderViewBuilder.buildJobHierachy().size(), 12 + 2 * Qt3DRender::Render::RenderViewBuilder::optimalJobCount());
}
void checkCheckJobDependencies()
@ -233,6 +233,10 @@ private Q_SLOTS:
QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
QVERIFY(renderViewBuilder.filterEntityByLayerJob()->dependencies().contains(testAspect.renderer()->updateTreeEnabledJob()));
QCOMPARE(renderViewBuilder.filterProximityJob()->dependencies().size(), 2);
QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
QVERIFY(renderViewBuilder.filterProximityJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().size(), 1);
QCOMPARE(renderViewBuilder.setClearDrawBufferIndexJob()->dependencies().first().data(), renderViewBuilder.syncRenderViewInitializationJob().data());
@ -252,7 +256,7 @@ private Q_SLOTS:
QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(renderViewBuilder.syncFrustumCullingJob()));
QVERIFY(renderViewBuilder.frustumCullingJob()->dependencies().contains(testAspect.renderer()->expandBoundingVolumeJob()));
QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 6);
QCOMPARE(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().size(), renderViewBuilder.materialGathererJobs().size() + 7);
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.syncRenderViewInitializationJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.renderableEntityFilterJob()));
QVERIFY(renderViewBuilder.syncRenderCommandBuildingJob()->dependencies().contains(renderViewBuilder.computableEntityFilterJob()));

View File

@ -52,7 +52,8 @@ SUBDIRS += \
anim-viewer \
animation-keyframe-programmatic \
layerfilter-qml \
skinned-mesh
skinned-mesh \
proximityfilter
qtHaveModule(widgets): {
SUBDIRS += \

View File

@ -0,0 +1,63 @@
/****************************************************************************
**
** 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: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 <Qt3DQuickExtras/qt3dquickwindow.h>
#include <QGuiApplication>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}

View File

@ -0,0 +1,148 @@
/****************************************************************************
**
** Copyright (C) 2017 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: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.9
import Qt3D.Core 2.10
import Qt3D.Render 2.10
import Qt3D.Input 2.0
import Qt3D.Extras 2.9
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, 150.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: RenderSurfaceSelector {
Viewport {
normalizedRect: Qt.rect(0, 0, 1, 1)
ClearBuffers {
buffers: ClearBuffers.ColorDepthBuffer
clearColor: Qt.rgba(0.6, 0.6, 0.6, 1.0)
NoDraw {}
}
FrustumCulling {
CameraSelector {
camera: camera
ProximityFilter {
entity: proximityTarget
distanceThreshold: 30
}
}
}
}
}
},
// Event Source will be set by the Qt3DQuickWindow
InputSettings { }
]
SphereMesh {
id: sphereMesh
}
PhongMaterial {
id: phongMaterial
diffuse: "orange"
}
NodeInstantiator {
id: instantiator
model: 64
Entity {
readonly property real angle: Math.PI * 2.0 * model.index % 8
readonly property real radius: 20
readonly property real verticalStep: 10
readonly property color meshColor: Qt.hsla(model.index / instantiator.count, 0.5, 0.5, 1.0);
readonly property Transform transform: Transform {
translation: Qt.vector3d(radius * Math.cos(angle),
(-(instantiator.count / (8 * 2)) + model.index / 8) * verticalStep,
radius * Math.sin(angle))
}
readonly property Material material: Material {
effect: phongMaterial.effect
parameters: Parameter { name: "kd"; value: meshColor }
}
readonly property SphereMesh mesh: sphereMesh
components: [ transform, mesh, material ]
}
}
Entity {
id: proximityTarget
readonly property Transform transform: Transform
{
property real y: 0;
SequentialAnimation on y {
NumberAnimation { from: -50; to: 50; duration: 2000; easing.type: Easing.InOutQuart }
NumberAnimation { from: 50; to: -50; duration: 2000; easing.type: Easing.InOutQuart }
loops: Animation.Infinite
}
translation: Qt.vector3d(0.0, y, 0.0)
}
components: [ sphereMesh, phongMaterial, transform ]
}
}

View File

@ -0,0 +1,11 @@
!include( ../manual.pri ) {
error( "Couldn't find the manual.pri file!" )
}
QT += 3dcore 3drender 3dinput 3dquick quick 3dquickextras
SOURCES += \
main.cpp
RESOURCES += \
proximityfilter.qrc

View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>