diff options
author | Paul Lemire <paul.lemire.ecortex@kdab.com> | 2014-11-20 14:27:52 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2014-12-12 14:17:04 +0100 |
commit | af6f95dd538f06736349ad42305814177aa81d92 (patch) | |
tree | 457052cd541807b9f0c28516feaae7f6e49c8d86 /src/render/backend/rendershaderdata.cpp | |
parent | 9dd1b0c993873772e2719844be71f86bc0c92a02 (diff) |
RenderShaderData completed to build UBO
Contains a UniformBuffer internally.
Once initialized created UBO on the GPU.
When properties of the QShaderData are updated, updated data is uploaded to
the UBO.
Some room for improvement, we'll improve that once the whole UBO/QShaderData
architecture is in place.
Change-Id: I26e55b78ad9633f75b988d8976ba496a7c7738fc
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/backend/rendershaderdata.cpp')
-rw-r--r-- | src/render/backend/rendershaderdata.cpp | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/src/render/backend/rendershaderdata.cpp b/src/render/backend/rendershaderdata.cpp index 7d73977fe..4617caf2a 100644 --- a/src/render/backend/rendershaderdata.cpp +++ b/src/render/backend/rendershaderdata.cpp @@ -44,6 +44,7 @@ #include <QMetaProperty> #include <QMetaObject> #include <Qt3DCore/qscenepropertychange.h> +#include <private/qgraphicscontext_p.h> QT_BEGIN_NAMESPACE @@ -53,6 +54,8 @@ namespace Render { RenderShaderData::RenderShaderData() : QBackendNode() + , m_initialized(false) + , m_needsBufferUpdate(true) { } @@ -72,12 +75,59 @@ void RenderShaderData::updateFromPeer(QNode *peer) } } +void RenderShaderData::initialize(const ShaderUniformBlock &block) +{ + m_block = block; + Q_ASSERT(m_block.m_size > 0); + // Allocate CPU side buffer + m_data = QByteArray(m_block.m_size, 0); + m_initialized = true; + // Force UBO buffer to be allocated on the GPU when apply is called + m_needsBufferUpdate = true; +} + +void RenderShaderData::appendActiveProperty(const char *propertyName, const ShaderUniform &description) +{ + m_activeProperties.insert(propertyName, description); +} + +void RenderShaderData::updateUniformBuffer(QGraphicsContext *ctx) +{ + if (!m_ubo.isCreated()) { + m_ubo.create(ctx); + m_ubo.allocate(ctx, m_block.m_size); + } + + // TO DO: Only update values that have changed rather than the whole buffer + QHash<const char *, ShaderUniform>::const_iterator uniformsIt = m_activeProperties.begin(); + const QHash<const char *, ShaderUniform>::const_iterator uniformsEnd = m_activeProperties.end(); + + while (uniformsIt != uniformsEnd) { + ctx->buildUniformBuffer(m_properties.value(uniformsIt.key()), uniformsIt.value(), m_data); + ++uniformsIt; + } + m_ubo.update(ctx, m_data.constData(), m_block.m_size); +} + +// Make sure QGraphicsContext::bindUniformBlock is called prior to this +void RenderShaderData::apply(QGraphicsContext *ctx, int bindingPoint) +{ + // Upload new data to GPU if it has changed + if (m_needsBufferUpdate) { + updateUniformBuffer(ctx); + m_needsBufferUpdate = false; + } + m_ubo.bindToUniformBlock(ctx, bindingPoint); +} + void RenderShaderData::sceneChangeEvent(const QSceneChangePtr &e) { if (e->type() == NodeUpdated) { QScenePropertyChangePtr propertyChange = qSharedPointerCast<QScenePropertyChange>(e); - if (m_properties.contains(propertyChange->propertyName())) + if (m_properties.contains(propertyChange->propertyName())) { m_properties.insert(propertyChange->propertyName(), propertyChange->value()); + m_needsBufferUpdate = true; + } } } |