diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2015-11-17 12:48:56 +0100 |
---|---|---|
committer | Andy Nichols <andy.nichols@theqtcompany.com> | 2015-11-24 16:53:40 +0000 |
commit | 2283cf838010d1c5264ab27553d30ce000fb01e6 (patch) | |
tree | 6257c543cc781570c023bde1d483baf4ab5e616f /src/render/backend | |
parent | 92311456e21ff0ff0e9e290e728dcca7cbd86c24 (diff) |
RenderView: frustum culling
Change-Id: Iacfcfce5d4a339acd29bcaacffb38ce339220ad2
Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
Diffstat (limited to 'src/render/backend')
-rw-r--r-- | src/render/backend/renderview.cpp | 29 | ||||
-rw-r--r-- | src/render/backend/renderview_p.h | 22 |
2 files changed, 38 insertions, 13 deletions
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp index 88e9ecc2f..62233b267 100644 --- a/src/render/backend/renderview.cpp +++ b/src/render/backend/renderview.cpp @@ -91,7 +91,16 @@ bool isEntityInLayers(const Entity *entity, const QStringList &layers) if (layers.contains(layerName)) return true; } + return false; +} +bool isEntityFrustumCulled(const Entity *entity, const Plane *planes) +{ + const Sphere *s = entity->worldBoundingVolumeWithChildren(); + for (int i = 0; i < 6; ++i) { + if (QVector3D::dotProduct(s->center(), planes[i].normal) + planes[i].d < -s->radius()) + return true; + } return false; } @@ -168,10 +177,7 @@ QUniformValue *RenderView::modelViewMatrix(const QMatrix4x4 &model) const QUniformValue *RenderView::modelViewProjectionMatrix(const QMatrix4x4 &model) const { - QMatrix4x4 projection; - if (m_data->m_renderCamera) - projection = m_data->m_renderCamera->projection(); - return QUniformValue::fromVariant(projection * *m_data->m_viewMatrix * model, m_allocator); + return QUniformValue::fromVariant(*m_data->m_viewProjectionMatrix * model, m_allocator); } QUniformValue *RenderView::inverseModelMatrix(const QMatrix4x4 &model) const @@ -199,10 +205,7 @@ QUniformValue *RenderView::inverseModelViewMatrix(const QMatrix4x4 &model) const QUniformValue *RenderView::inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const { - QMatrix4x4 projection; - if (m_data->m_renderCamera) - projection = m_data->m_renderCamera->projection(); - return QUniformValue::fromVariant((projection * *m_data->m_viewMatrix * model).inverted(0), m_allocator); + return QUniformValue::fromVariant((*m_data->m_viewProjectionMatrix * model).inverted(0), m_allocator); } QUniformValue *RenderView::modelNormalMatrix(const QMatrix4x4 &model) const @@ -285,8 +288,9 @@ RenderView::~RenderView() m_allocator->deallocate<RenderCommand>(command); } - // Deallocate viewMatrix + // Deallocate viewMatrix/viewProjectionMatrix m_allocator->deallocate<QMatrix4x4>(m_data->m_viewMatrix); + m_allocator->deallocate<QMatrix4x4>(m_data->m_viewProjectionMatrix); // Deallocate viewport rect m_allocator->deallocate<QRectF>(m_viewport); // Deallocate clearColor @@ -374,12 +378,15 @@ void RenderView::setRenderer(Renderer *renderer) } // Tries to order renderCommand by shader so as to minimize shader changes -void RenderView::buildRenderCommands(Entity *node) +void RenderView::buildRenderCommands(Entity *node, const Plane *planes) { // Skip branches that are not enabled if (!node->isEnabled()) return; + if (isEntityFrustumCulled(node, planes)) + return; + // Build renderCommand for current node if (isEntityInLayers(node, m_data->m_layers)) { GeometryRenderer *geometryRenderer = Q_NULLPTR; @@ -469,7 +476,7 @@ void RenderView::buildRenderCommands(Entity *node) // Traverse children Q_FOREACH (Entity *child, node->children()) - buildRenderCommands(child); + buildRenderCommands(child, planes); } const AttachmentPack &RenderView::attachmentPack() const diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h index e585cb7ff..650d634bc 100644 --- a/src/render/backend/renderview_p.h +++ b/src/render/backend/renderview_p.h @@ -86,6 +86,19 @@ class RenderPass; typedef QPair<ShaderUniform, QVariant> ActivePropertyContent; typedef QPair<QString, ActivePropertyContent > ActiveProperty; +struct Q_AUTOTEST_EXPORT Plane +{ + explicit Plane(const QVector4D &planeEquation) + : planeEquation(planeEquation) + , normal(planeEquation.toVector3D().normalized()) + , d(planeEquation.w() / planeEquation.toVector3D().length()) + {} + + const QVector4D planeEquation; + const QVector3D normal; + const float d; +}; + // This class is kind of analogous to RenderBin but I want to avoid trampling // on that until we get this working @@ -117,15 +130,19 @@ public: // level of memory management would be better in Entity's matrices as they will // help cache performance during iteration m_data->m_viewMatrix = m_allocator->allocate<QMatrix4x4>(); + m_data->m_viewProjectionMatrix = m_allocator->allocate<QMatrix4x4>(); } inline Qt3DCore::QFrameAllocator *allocator() const { return m_allocator; } inline void setRenderCamera(CameraLens *renderCamera) { m_data->m_renderCamera = renderCamera; } inline CameraLens *renderCamera() const { return m_data->m_renderCamera; } - inline void setViewMatrix(const QMatrix4x4 viewMatrix) { *(m_data->m_viewMatrix) = viewMatrix; } + inline void setViewMatrix(const QMatrix4x4 &viewMatrix) { *(m_data->m_viewMatrix) = viewMatrix; } inline QMatrix4x4 viewmatrix() const { Q_ASSERT(m_data->m_viewMatrix); return *(m_data->m_viewMatrix); } + inline void setViewProjectionMatrix(const QMatrix4x4 &viewProjectionMatrix) { *(m_data->m_viewProjectionMatrix) = viewProjectionMatrix; } + inline QMatrix4x4 viewProjectionMatrix() const { return *(m_data->m_viewProjectionMatrix); } + inline void setEyePosition(const QVector3D &eyePos) { m_data->m_eyePos = eyePos; } inline QVector3D eyePosition() const { return m_data->m_eyePos; } @@ -188,7 +205,7 @@ public: inline void setClearBuffer(QClearBuffer::BufferType clearBuffer) { m_clearBuffer = clearBuffer; } inline QClearBuffer::BufferType clearBuffer() const { return m_clearBuffer; } - void buildRenderCommands(Entity *preprocessedTreeRoot); + void buildRenderCommands(Entity *preprocessedTreeRoot, const Plane *planes); QVector<RenderCommand *> commands() const { return m_commands; } void addRenderAttachment(Attachment attachment) { m_attachmentPack.addAttachment(attachment); } @@ -215,6 +232,7 @@ public: const TechniqueFilter *m_techniqueFilter; const RenderPassFilter *m_passFilter; QMatrix4x4 *m_viewMatrix; + QMatrix4x4 *m_viewProjectionMatrix; QStringList m_layers; QList<Qt3DCore::QNodeId> m_sortingCriteria; QVector3D m_eyePos; |