summaryrefslogtreecommitdiffstats
path: root/src/render/backend
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-09-23 09:33:53 +0200
committerLiang Qi <liang.qi@qt.io>2016-09-23 09:33:53 +0200
commitec2c6c0f13004bc1bba92f14443228778da287a0 (patch)
tree5c4e2621091ad7bbd31e6ffb6a277c1aaee39b55 /src/render/backend
parent5476bc6b4b6a12c921da502c24c4e078b04dd3b3 (diff)
parent0e3d54f8d7f9be26687afebcc9f456e4cefc2357 (diff)
Merge remote-tracking branch 'origin/5.8' into devwip/particles
Diffstat (limited to 'src/render/backend')
-rw-r--r--src/render/backend/commandexecuter.cpp8
-rw-r--r--src/render/backend/render-backend.pri10
-rw-r--r--src/render/backend/rendercommand_p.h2
-rw-r--r--src/render/backend/renderer.cpp6
-rw-r--r--src/render/backend/renderer_p.h2
-rw-r--r--src/render/backend/renderview.cpp127
-rw-r--r--src/render/backend/renderview_p.h46
-rw-r--r--src/render/backend/shaderparameterpack.cpp (renamed from src/render/backend/quniformvalue.cpp)34
-rw-r--r--src/render/backend/shaderparameterpack_p.h (renamed from src/render/backend/quniformvalue_p.h)125
-rw-r--r--src/render/backend/uniform.cpp164
-rw-r--r--src/render/backend/uniform_p.h208
11 files changed, 484 insertions, 248 deletions
diff --git a/src/render/backend/commandexecuter.cpp b/src/render/backend/commandexecuter.cpp
index 92f44c511..2f13b27ea 100644
--- a/src/render/backend/commandexecuter.cpp
+++ b/src/render/backend/commandexecuter.cpp
@@ -251,13 +251,9 @@ QJsonObject parameterPackToJson(const Render::ShaderParameterPack &pack)
for (auto it = uniforms.cbegin(), end = uniforms.cend(); it != end; ++it) {
QJsonObject uniformObj;
uniformObj.insert(QLatin1String("name"), Render::StringToInt::lookupString(it.key()));
- const Render::QUniformValue::UniformType type = it.value().type();
- uniformObj.insert(QLatin1String("value"),
- type == Render::QUniformValue::Value
- ? typeToJsonValue(it.value().value())
- : typeToJsonValue(it.value().textureId()));
+ const Render::UniformValue::ValueType type = it.value().valueType();
uniformObj.insert(QLatin1String("type"),
- type == Render::QUniformValue::Value
+ type == Render::UniformValue::ScalarValue
? QLatin1String("value")
: QLatin1String("texture"));
uniformsArray.push_back(uniformObj);
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri
index 256cba78e..a55a72d8b 100644
--- a/src/render/backend/render-backend.pri
+++ b/src/render/backend/render-backend.pri
@@ -7,7 +7,6 @@ HEADERS += \
$$PWD/renderthread_p.h \
$$PWD/renderconfiguration_p.h \
$$PWD/renderer_p.h \
- $$PWD/quniformvalue_p.h \
$$PWD/renderview_p.h \
$$PWD/rendercommand_p.h \
$$PWD/renderqueue_p.h \
@@ -36,13 +35,14 @@ HEADERS += \
$$PWD/stringtoint_p.h \
$$PWD/backendnode_p.h \
$$PWD/rendertargetoutput_p.h \
- $$PWD/commandexecuter_p.h
+ $$PWD/commandexecuter_p.h \
+ $$PWD/uniform_p.h \
+ $$PWD/shaderparameterpack_p.h
SOURCES += \
$$PWD/renderthread.cpp \
$$PWD/renderconfiguration.cpp \
$$PWD/renderer.cpp \
- $$PWD/quniformvalue.cpp \
$$PWD/renderview.cpp \
$$PWD/rendercommand.cpp \
$$PWD/renderqueue.cpp \
@@ -66,5 +66,7 @@ SOURCES += \
$$PWD/rendertargetoutput.cpp \
$$PWD/attachmentpack.cpp \
$$PWD/commandexecuter.cpp \
- $$PWD/openglvertexarrayobject.cpp
+ $$PWD/openglvertexarrayobject.cpp \
+ $$PWD/uniform.cpp \
+ $$PWD/shaderparameterpack.cpp
diff --git a/src/render/backend/rendercommand_p.h b/src/render/backend/rendercommand_p.h
index dc65ac7ed..012cdbe9a 100644
--- a/src/render/backend/rendercommand_p.h
+++ b/src/render/backend/rendercommand_p.h
@@ -53,7 +53,7 @@
//
#include <qglobal.h>
-#include <Qt3DRender/private/quniformvalue_p.h>
+#include <Qt3DRender/private/shaderparameterpack_p.h>
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/qgeometryrenderer.h>
#include <QOpenGLShaderProgram>
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index ca60b8e33..7f53d3c99 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -919,6 +919,12 @@ Renderer::ViewSubmissionResultData Renderer::submitRenderViews(const QVector<Ren
frameElapsed = timer.elapsed();
}
+ // Bind lastBoundFBOId back. Needed also in threaded mode.
+ // lastBoundFBOId != m_graphicsContext->activeFBO() when the last FrameGraph leaf node/renderView
+ // contains RenderTargetSelector/RenderTarget
+ if (lastBoundFBOId != m_graphicsContext->activeFBO())
+ m_graphicsContext->bindFramebuffer(lastBoundFBOId);
+
// Reset state and call doneCurrent if the surface
// is valid and was actually activated
if (surface && m_graphicsContext->hasValidGLHelper()) {
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index da3d4e1e9..ffc60273a 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -54,7 +54,7 @@
#include <Qt3DRender/qrenderaspect.h>
#include <Qt3DRender/qtechnique.h>
-#include <Qt3DRender/private/quniformvalue_p.h>
+#include <Qt3DRender/private/shaderparameterpack_p.h>
#include <Qt3DRender/private/handle_types_p.h>
#include <Qt3DRender/private/abstractrenderer_p.h>
#include <Qt3DCore/qaspectjob.h>
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 552e66f6d..df165e2d0 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -133,80 +133,80 @@ RenderView::StandardUniformsPFuncsHash RenderView::initializeStandardUniformSett
return setters;
}
-QUniformValue RenderView::modelMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::modelMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue(model));
+ return UniformValue(model);
}
-QUniformValue RenderView::viewMatrix(const QMatrix4x4 &) const
+UniformValue RenderView::viewMatrix(const QMatrix4x4 &) const
{
- return QUniformValue(QVariant::fromValue(m_data.m_viewMatrix));
+ return UniformValue(m_data.m_viewMatrix);
}
-QUniformValue RenderView::projectionMatrix(const QMatrix4x4 &) const
+UniformValue RenderView::projectionMatrix(const QMatrix4x4 &) const
{
- return QUniformValue(QVariant::fromValue(m_data.m_renderCameraLens->projection()));
+ return UniformValue(m_data.m_renderCameraLens->projection());
}
-QUniformValue RenderView::modelViewMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::modelViewMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue(m_data.m_viewMatrix * model));
+ return UniformValue(m_data.m_viewMatrix * model);
}
-QUniformValue RenderView::viewProjectionMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::viewProjectionMatrix(const QMatrix4x4 &model) const
{
Q_UNUSED(model);
- return QUniformValue(QVariant::fromValue(m_data.m_renderCameraLens->projection() * m_data.m_viewMatrix));
+ return UniformValue(m_data.m_renderCameraLens->projection() * m_data.m_viewMatrix);
}
-QUniformValue RenderView::modelViewProjectionMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::modelViewProjectionMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue(m_data.m_viewProjectionMatrix * model));
+ return UniformValue(m_data.m_viewProjectionMatrix * model);
}
-QUniformValue RenderView::inverseModelMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::inverseModelMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue(model.inverted()));
+ return UniformValue(model.inverted());
}
-QUniformValue RenderView::inverseViewMatrix(const QMatrix4x4 &) const
+UniformValue RenderView::inverseViewMatrix(const QMatrix4x4 &) const
{
- return QUniformValue(QVariant::fromValue(m_data.m_viewMatrix.inverted()));
+ return UniformValue(m_data.m_viewMatrix.inverted());
}
-QUniformValue RenderView::inverseProjectionMatrix(const QMatrix4x4 &) const
+UniformValue RenderView::inverseProjectionMatrix(const QMatrix4x4 &) const
{
QMatrix4x4 projection;
if (m_data.m_renderCameraLens)
projection = m_data.m_renderCameraLens->projection();
- return QUniformValue(QVariant::fromValue(projection.inverted()));
+ return UniformValue(projection.inverted());
}
-QUniformValue RenderView::inverseModelViewMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::inverseModelViewMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue((m_data.m_viewMatrix * model).inverted()));
+ return UniformValue((m_data.m_viewMatrix * model).inverted());
}
-QUniformValue RenderView::inverseViewProjectionMatrix(const QMatrix4x4 &model) const
+UniformValue 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()));
+ return UniformValue(viewProjectionMatrix.inverted());
}
-QUniformValue RenderView::inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue((m_data.m_viewProjectionMatrix * model).inverted(0)));
+ return UniformValue((m_data.m_viewProjectionMatrix * model).inverted(0));
}
-QUniformValue RenderView::modelNormalMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::modelNormalMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue(model.normalMatrix()));
+ return UniformValue(model.normalMatrix());
}
-QUniformValue RenderView::modelViewNormalMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::modelViewNormalMatrix(const QMatrix4x4 &model) const
{
- return QUniformValue(QVariant::fromValue((m_data.m_viewMatrix * model).normalMatrix()));
+ return UniformValue((m_data.m_viewMatrix * model).normalMatrix());
}
// TODO: Move this somewhere global where GraphicsContext::setViewport() can use it too
@@ -218,38 +218,38 @@ static QRectF resolveViewport(const QRectF &fractionalViewport, const QSize &sur
fractionalViewport.height() * surfaceSize.height());
}
-QUniformValue RenderView::viewportMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::viewportMatrix(const QMatrix4x4 &model) const
{
// TODO: Can we avoid having to pass the model matrix in to these functions?
Q_UNUSED(model);
QMatrix4x4 viewportMatrix;
viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
- return QUniformValue(QVariant::fromValue(viewportMatrix));
+ return UniformValue(viewportMatrix);
}
-QUniformValue RenderView::inverseViewportMatrix(const QMatrix4x4 &model) const
+UniformValue RenderView::inverseViewportMatrix(const QMatrix4x4 &model) const
{
Q_UNUSED(model);
QMatrix4x4 viewportMatrix;
viewportMatrix.viewport(resolveViewport(m_viewport, m_surfaceSize));
QMatrix4x4 inverseViewportMatrix = viewportMatrix.inverted();
- return QUniformValue(QVariant::fromValue(inverseViewportMatrix));
+ return UniformValue(inverseViewportMatrix);
}
-QUniformValue RenderView::time(const QMatrix4x4 &model) const
+UniformValue RenderView::time(const QMatrix4x4 &model) const
{
Q_UNUSED(model);
qint64 time = m_renderer->time();
float t = time / 1000000000.0f;
- return QUniformValue(QVariant(t));
+ return UniformValue(t);
}
-QUniformValue RenderView::eyePosition(const QMatrix4x4 &model) const
+UniformValue RenderView::eyePosition(const QMatrix4x4 &model) const
{
Q_UNUSED(model);
- return QUniformValue(QVariant::fromValue(m_data.m_eyePos));
+ return UniformValue(m_data.m_eyePos);
}
RenderView::RenderView()
@@ -326,7 +326,7 @@ void RenderView::sort()
// sharing the same material (shader) are rendered, we can't have the case
// where two uniforms, referencing the same texture eventually have 2 different
// texture unit values
- const QUniformValue refValue = cachedUniforms.value(it.key());
+ const UniformValue refValue = cachedUniforms.value(it.key());
if (it.value() == refValue) {
it = uniforms.erase(it);
} else {
@@ -532,27 +532,24 @@ void RenderView::updateMatrices()
}
}
-void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const QVariant &value) const
+void RenderView::setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const
{
- Texture *tex = nullptr;
// At this point a uniform value can only be a scalar type
// or a Qt3DCore::QNodeId corresponding to a Texture
// ShaderData/Buffers would be handled as UBO/SSBO and would therefore
// not be in the default uniform block
- if (static_cast<QMetaType::Type>(value.userType()) == qNodeIdTypeId) {
- // Speed up conversion to avoid using QVariant::value()
- const Qt3DCore::QNodeId texId = variant_value<Qt3DCore::QNodeId>(value);
+ if (value.valueType() == UniformValue::NodeId) {
+ Texture *tex = nullptr;
+ const Qt3DCore::QNodeId texId = *value.constData<Qt3DCore::QNodeId>();
if ((tex = m_manager->textureManager()->lookupResource(texId))
!= nullptr) {
uniformPack.setTexture(nameId, tex->peerId());
- //TextureUniform *texUniform = m_allocator->allocate<TextureUniform>();
- QUniformValue texUniform;
- texUniform.setType(QUniformValue::TextureSampler);
- texUniform.setTextureId(tex->peerId());
- uniformPack.setUniform(nameId, texUniform);
+ UniformValue::Texture textureValue;
+ textureValue.nodeId = texId;
+ uniformPack.setUniform(nameId, UniformValue(textureValue));
}
} else {
- uniformPack.setUniform(nameId, QUniformValue(value));
+ uniformPack.setUniform(nameId, value);
}
}
@@ -564,14 +561,14 @@ void RenderView::setStandardUniformValue(ShaderParameterPack &uniformPack, int g
void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
Shader *shader,
const ShaderUniformBlock &block,
- const QVariant &value) const
+ const UniformValue &value) const
{
Q_UNUSED(shader)
- if (static_cast<QMetaType::Type>(value.userType()) == qNodeIdTypeId) {
+ if (value.valueType() == UniformValue::NodeId) {
Buffer *buffer = nullptr;
- if ((buffer = m_manager->bufferManager()->lookupResource(variant_value<Qt3DCore::QNodeId>(value))) != nullptr) {
+ if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) {
BlockToUBO uniformBlockUBO;
uniformBlockUBO.m_blockIndex = block.m_index;
uniformBlockUBO.m_bufferID = buffer->peerId();
@@ -634,12 +631,12 @@ void RenderView::setUniformBlockValue(ShaderParameterPack &uniformPack,
void RenderView::setShaderStorageValue(ShaderParameterPack &uniformPack,
Shader *shader,
const ShaderStorageBlock &block,
- const QVariant &value) const
+ const UniformValue &value) const
{
Q_UNUSED(shader)
- if (static_cast<QMetaType::Type>(value.userType()) == qNodeIdTypeId) {
+ if (value.valueType() == UniformValue::NodeId) {
Buffer *buffer = nullptr;
- if ((buffer = m_manager->bufferManager()->lookupResource(variant_value<Qt3DCore::QNodeId>(value))) != nullptr) {
+ if ((buffer = m_manager->bufferManager()->lookupResource(*value.constData<Qt3DCore::QNodeId>())) != nullptr) {
BlockToSSBO shaderStorageBlock;
shaderStorageBlock.m_blockIndex = block.m_index;
shaderStorageBlock.m_bufferID = buffer->peerId();
@@ -654,10 +651,8 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif
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);
-
+ // Set the view matrix to be used to transform "Transformed" properties in the ShaderData
+ builder->viewMatrix = m_data.m_viewMatrix;
// Force to update the whole block
builder->updatedPropertiesOnly = false;
// Retrieve names and description of each active uniforms in the uniform block
@@ -668,8 +663,9 @@ void RenderView::setDefaultUniformBlockShaderDataValue(ShaderParameterPack &unif
QHash<int, QVariant>::const_iterator activeValuesIt = builder->activeUniformNamesToValue.constBegin();
const QHash<int, QVariant>::const_iterator activeValuesEnd = builder->activeUniformNamesToValue.constEnd();
+ // TO DO: Make the ShaderData store UniformValue
while (activeValuesIt != activeValuesEnd) {
- setUniformValue(uniformPack, activeValuesIt.key(), activeValuesIt.value());
+ setUniformValue(uniformPack, activeValuesIt.key(), UniformValue::fromVariant(activeValuesIt.value()));
++activeValuesIt;
}
}
@@ -769,10 +765,10 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
} else if (shaderStorageBlockNamesIds.indexOf(it->nameId) != -1) { // Parameters is a SSBO
setShaderStorageValue(command->m_parameterPack, shader, shader->storageBlockForBlockNameId(it->nameId), it->value);
} else { // Parameter is a struct
- const QVariant &v = it->value;
+ const UniformValue &v = it->value;
ShaderData *shaderData = nullptr;
- if (static_cast<QMetaType::Type>(v.userType()) == qNodeIdTypeId &&
- (shaderData = m_manager->shaderDataManager()->lookupResource(variant_value<Qt3DCore::QNodeId>(v))) != nullptr) {
+ if (v.valueType() == UniformValue::NodeId &&
+ (shaderData = m_manager->shaderDataManager()->lookupResource(*v.constData<Qt3DCore::QNodeId>())) != nullptr) {
// Try to check if we have a struct or array matching a QShaderData parameter
setDefaultUniformBlockShaderDataValue(command->m_parameterPack, shader, shaderData, StringToInt::lookupString(it->nameId));
}
@@ -797,11 +793,15 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
if (lightIdx == MAX_LIGHTS)
break;
+ // Note: implicit conversion of values to UniformValue
setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[lightIdx], worldPos);
setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[lightIdx], int(QAbstractLight::PointLight));
setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[lightIdx], QVector3D(1.0f, 1.0f, 1.0f));
setUniformValue(command->m_parameterPack, LIGHT_INTENSITY_NAMES[lightIdx], 0.5f);
+ // There is no risk in doing that even if multithreaded
+ // since we are sure that a shaderData is unique for a given light
+ // and won't ever be referenced as a Component either
QMatrix4x4 *worldTransform = lightEntity->worldTransform();
if (worldTransform)
shaderData->updateWorldTransform(*worldTransform);
@@ -812,9 +812,10 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderPass *rPass,
}
if (uniformNamesIds.contains(LIGHT_COUNT_NAME_ID))
- setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, qMax(1, lightIdx));
+ setUniformValue(command->m_parameterPack, LIGHT_COUNT_NAME_ID, UniformValue(qMax(1, lightIdx)));
if (activeLightSources.isEmpty()) {
+ // Note: implicit conversion of values to UniformValue
setUniformValue(command->m_parameterPack, LIGHT_POSITION_NAMES[0], QVector3D(10.0f, 10.0f, 0.0f));
setUniformValue(command->m_parameterPack, LIGHT_TYPE_NAMES[0], int(QAbstractLight::PointLight));
setUniformValue(command->m_parameterPack, LIGHT_COLOR_NAMES[0], QVector3D(1.0f, 1.0f, 1.0f));
diff --git a/src/render/backend/renderview_p.h b/src/render/backend/renderview_p.h
index f974741aa..41b0192c0 100644
--- a/src/render/backend/renderview_p.h
+++ b/src/render/backend/renderview_p.h
@@ -279,39 +279,39 @@ private:
QHash<Qt3DCore::QNodeId, QVector<RenderPassParameterData>> m_parameters;
- typedef QHash<int, QUniformValue (RenderView::*)(const QMatrix4x4& model) const> StandardUniformsPFuncsHash;
+ typedef QHash<int, UniformValue (RenderView::*)(const QMatrix4x4& model) const> StandardUniformsPFuncsHash;
static StandardUniformsPFuncsHash ms_standardUniformSetters;
static StandardUniformsPFuncsHash initializeStandardUniformSetters();
- QUniformValue modelMatrix(const QMatrix4x4& model) const;
- 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;
- QUniformValue viewportMatrix(const QMatrix4x4 &model) const;
- QUniformValue inverseViewportMatrix(const QMatrix4x4 &model) const;
- QUniformValue time(const QMatrix4x4 &model) const;
- QUniformValue eyePosition(const QMatrix4x4 &model) const;
-
- void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const QVariant &value) const;
+ UniformValue modelMatrix(const QMatrix4x4& model) const;
+ UniformValue viewMatrix(const QMatrix4x4&) const;
+ UniformValue projectionMatrix(const QMatrix4x4 &) const;
+ UniformValue modelViewMatrix(const QMatrix4x4 &model) const;
+ UniformValue viewProjectionMatrix(const QMatrix4x4 &model) const;
+ UniformValue modelViewProjectionMatrix(const QMatrix4x4 &model) const;
+ UniformValue inverseModelMatrix(const QMatrix4x4 &model) const;
+ UniformValue inverseViewMatrix(const QMatrix4x4 &) const;
+ UniformValue inverseProjectionMatrix(const QMatrix4x4 &) const;
+ UniformValue inverseModelViewMatrix(const QMatrix4x4 &model) const;
+ UniformValue inverseViewProjectionMatrix(const QMatrix4x4 &model) const;
+ UniformValue inverseModelViewProjectionMatrix(const QMatrix4x4 &model) const;
+ UniformValue modelNormalMatrix(const QMatrix4x4 &model) const;
+ UniformValue modelViewNormalMatrix(const QMatrix4x4 &model) const;
+ UniformValue viewportMatrix(const QMatrix4x4 &model) const;
+ UniformValue inverseViewportMatrix(const QMatrix4x4 &model) const;
+ UniformValue time(const QMatrix4x4 &model) const;
+ UniformValue eyePosition(const QMatrix4x4 &model) const;
+
+ void setUniformValue(ShaderParameterPack &uniformPack, int nameId, const UniformValue &value) const;
void setStandardUniformValue(ShaderParameterPack &uniformPack, int glslNameId, int nameId, const QMatrix4x4 &worldTransform) const;
void setUniformBlockValue(ShaderParameterPack &uniformPack,
Shader *shader,
const ShaderUniformBlock &block,
- const QVariant &value) const;
+ const UniformValue &value) const;
void setShaderStorageValue(ShaderParameterPack &uniformPack,
Shader *shader,
const ShaderStorageBlock &block,
- const QVariant &value) const;
+ const UniformValue &value) const;
void setDefaultUniformBlockShaderDataValue(ShaderParameterPack &uniformPack,
Shader *shader,
ShaderData *shaderData,
diff --git a/src/render/backend/quniformvalue.cpp b/src/render/backend/shaderparameterpack.cpp
index 09327c213..01a977aee 100644
--- a/src/render/backend/quniformvalue.cpp
+++ b/src/render/backend/shaderparameterpack.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "quniformvalue_p.h"
+#include "shaderparameterpack_p.h"
#include <Qt3DRender/private/graphicscontext_p.h>
#include <Qt3DRender/private/texture_p.h>
@@ -55,42 +55,12 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
-void QUniformValue::apply(GraphicsContext *ctx, const ShaderUniform &description) const
-{
- switch (m_type) {
- case Value:
- ctx->bindUniform(m_var, description);
- break;
-
- case TextureSampler:
- // We assume that the texture has been successfully bound and attache to a texture unit
- if (m_textureIdUnit.m_textureUnit != -1) {
- ctx->bindUniform(m_textureIdUnit.m_textureUnit, description);
-#if defined(QT3D_RENDER_ASPECT_OPENGL_DEBUG)
- int err = ctx->openGLContext()->functions()->glGetError();
- if (err) {
- qCWarning(Render::Backend, "Error %d after setting uniform \"%s\" at location %d",
- err, qUtf8Printable(description.m_name), description.m_location);
- }
-#endif
- } else {
- qCWarning(Render::Backend, "Invalid texture unit supplied for \"%s\"",
- qUtf8Printable(description.m_nameId));
- }
- break;
-
- default:
- break;
- }
-}
-
-
ShaderParameterPack::~ShaderParameterPack()
{
m_uniforms.clear();
}
-void ShaderParameterPack::setUniform(const int glslNameId, const QUniformValue &val)
+void ShaderParameterPack::setUniform(const int glslNameId, const UniformValue &val)
{
m_uniforms.insert(glslNameId, val);
}
diff --git a/src/render/backend/quniformvalue_p.h b/src/render/backend/shaderparameterpack_p.h
index fb8158d84..c0ab05e57 100644
--- a/src/render/backend/quniformvalue_p.h
+++ b/src/render/backend/shaderparameterpack_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QT3DRENDER_RENDER_QUNIFORMVALUE_H
-#define QT3DRENDER_RENDER_QUNIFORMVALUE_H
+#ifndef QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H
+#define QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H
//
// W A R N I N G
@@ -58,6 +58,7 @@
#include <Qt3DCore/qnodeid.h>
#include <Qt3DRender/private/renderlogging_p.h>
#include <Qt3DRender/private/shadervariables_p.h>
+#include <Qt3DRender/private/uniform_p.h>
QT_BEGIN_NAMESPACE
@@ -72,118 +73,6 @@ namespace Render {
class GraphicsContext;
-class QUniformValue
-{
-public:
- enum UniformType {
- Value,
- TextureSampler,
- Unknown
- };
-
- QUniformValue()
- : m_type(Unknown)
- , m_var()
- {
- }
-
- explicit QUniformValue(const QVariant &var, UniformType type = Value)
- : m_type(type)
- , m_var(var)
- {
- }
-
- void setType(UniformType type) Q_DECL_NOTHROW { m_type = type; }
- UniformType type() const Q_DECL_NOTHROW { return m_type; }
- bool isTexture() const Q_DECL_NOTHROW { return m_type == TextureSampler; }
-
- void setValue(const QVariant &value)
- {
- Q_ASSERT(m_type == Value);
- m_var = value;
- }
-
- QVariant value() const
- {
- Q_ASSERT(m_type == Value);
- return m_var;
- }
-
- void setTextureUnit(int textureUnit)
- {
- Q_ASSERT(m_type == TextureSampler);
- m_textureIdUnit.m_textureUnit = textureUnit;
- }
-
- int textureUnit() const
- {
- Q_ASSERT(m_type == TextureSampler);
- return m_textureIdUnit.m_textureUnit;
- }
-
- void setTextureId(Qt3DCore::QNodeId textureId)
- {
- Q_ASSERT(m_type == TextureSampler);
- m_textureIdUnit.m_textureId = textureId;
- }
-
- Qt3DCore::QNodeId textureId() const
- {
- Q_ASSERT(m_type == TextureSampler);
- return m_textureIdUnit.m_textureId;
- }
-
- bool operator ==(const QUniformValue &other)
- {
- if (other.m_type != m_type)
- return false;
-
- switch (m_type) {
- case Value:
- return other.m_var == m_var;
- case TextureSampler:
- return other.m_textureIdUnit == m_textureIdUnit;
- default:
- break;
- }
- return false;
- }
-
- bool operator !=(const QUniformValue &other)
- {
- return !operator ==(other);
- }
-
- void apply(GraphicsContext *ctx, const ShaderUniform &description) const;
-
-protected:
- struct TextureIdUnit {
- Qt3DCore::QNodeId m_textureId;
- int m_textureUnit;
-
- TextureIdUnit()
- : m_textureId()
- , m_textureUnit(-1)
- {}
-
- bool operator == (const TextureIdUnit &other) const Q_DECL_NOTHROW
- {
- return (other.m_textureId == m_textureId) && (other.m_textureUnit == m_textureUnit);
- }
-
- bool operator !=(const TextureIdUnit &other) const Q_DECL_NOTHROW
- {
- return !operator ==(other);
- }
- };
-
- // TODO: Replace QVariant with our own union of GLSL types as we don't
- // need the full flexibility of QVariant on the backend
- UniformType m_type;
- QVariant m_var;
- TextureIdUnit m_textureIdUnit;
-};
-
struct BlockToUBO {
int m_blockIndex;
Qt3DCore::QNodeId m_bufferID;
@@ -199,14 +88,14 @@ struct BlockToSSBO {
QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, BlockToSSBO, Q_PRIMITIVE_TYPE)
-typedef QHash<int, QUniformValue> PackUniformHash;
+typedef QHash<int, UniformValue> PackUniformHash;
class ShaderParameterPack
{
public:
~ShaderParameterPack();
- void setUniform(const int glslNameId, const QUniformValue &val);
+ void setUniform(const int glslNameId, const UniformValue &val);
void setTexture(const int glslNameId, Qt3DCore::QNodeId id);
void setUniformBuffer(BlockToUBO blockToUBO);
void setShaderStorageBuffer(BlockToSSBO blockToSSBO);
@@ -214,7 +103,7 @@ public:
inline PackUniformHash &uniforms() { return m_uniforms; }
inline const PackUniformHash &uniforms() const { return m_uniforms; }
- QUniformValue uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); }
+ UniformValue uniform(const int glslNameId) const { return m_uniforms.value(glslNameId); }
struct NamedTexture
{
@@ -249,4 +138,4 @@ QT3D_DECLARE_TYPEINFO_2(Qt3DRender, Render, ShaderParameterPack::NamedTexture, Q
QT_END_NAMESPACE
-#endif // QT3DRENDER_RENDER_QUNIFORMVALUE_H
+#endif // QT3DRENDER_RENDER_SHADERPARAMETERPACK_P_H
diff --git a/src/render/backend/uniform.cpp b/src/render/backend/uniform.cpp
new file mode 100644
index 000000000..3bc1f78ce
--- /dev/null
+++ b/src/render/backend/uniform.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "uniform_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+
+namespace {
+
+const int qNodeIdTypeId = qMetaTypeId<Qt3DCore::QNodeId>();
+
+}
+
+UniformValue UniformValue::fromVariant(const QVariant &variant)
+{
+ // Texture/Buffer case
+ if (variant.userType() == qNodeIdTypeId)
+ return UniformValue(variant.value<Qt3DCore::QNodeId>());
+
+ UniformValue v;
+ switch (variant.userType()) {
+ case QMetaType::Bool:
+ v.m_data.ivec[0] = variant.toBool();
+ break;
+ case QMetaType::Int:
+ case QMetaType::UInt:
+ case QMetaType::Long:
+ case QMetaType::LongLong:
+ case QMetaType::Short:
+ case QMetaType::ULong:
+ case QMetaType::ULongLong:
+ case QMetaType::UShort:
+ case QMetaType::Char:
+ case QMetaType::UChar:
+ v.m_data.ivec[0] = variant.toInt();
+ break;
+ case QMetaType::Float:
+ case QMetaType::Double: // Convert double to floats
+ v.m_data.fvec[0] = variant.toFloat();
+ break;
+ case QMetaType::QPoint: {
+ const QPoint p = variant.toPoint();
+ v.m_data.ivec[0] = p.x();
+ v.m_data.ivec[1] = p.y();
+ break;
+ }
+ case QMetaType::QSize: {
+ const QSize s = variant.toSize();
+ v.m_data.ivec[0] = s.width();
+ v.m_data.ivec[1] = s.height();
+ break;
+ }
+ case QMetaType::QRect: {
+ const QRect r = variant.toRect();
+ v.m_data.ivec[0] = r.x();
+ v.m_data.ivec[1] = r.y();
+ v.m_data.ivec[2] = r.width();
+ v.m_data.ivec[3] = r.height();
+ break;
+ }
+ case QMetaType::QSizeF: {
+ const QSizeF s = variant.toSize();
+ v.m_data.fvec[0] = s.width();
+ v.m_data.fvec[1] = s.height();
+ break;
+ }
+ case QMetaType::QPointF: {
+ const QPointF p = variant.toPointF();
+ v.m_data.fvec[0] = p.x();
+ v.m_data.fvec[1] = p.y();
+ break;
+ }
+ case QMetaType::QRectF: {
+ const QRectF r = variant.toRect();
+ v.m_data.fvec[0] = r.x();
+ v.m_data.fvec[1] = r.y();
+ v.m_data.fvec[2] = r.width();
+ v.m_data.fvec[3] = r.height();
+ break;
+ }
+ case QMetaType::QVector2D: {
+ const QVector2D vec2 = variant.value<QVector2D>();
+ v.m_data.fvec[0] = vec2.x();
+ v.m_data.fvec[1] = vec2.y();
+ break;
+ }
+ case QMetaType::QVector3D: {
+ const QVector3D vec3 = variant.value<QVector3D>();
+ v.m_data.fvec[0] = vec3.x();
+ v.m_data.fvec[1] = vec3.y();
+ v.m_data.fvec[2] = vec3.z();
+ break;
+ }
+ case QMetaType::QVector4D: {
+ const QVector4D vec4 = variant.value<QVector4D>();
+ v.m_data.fvec[0] = vec4.x();
+ v.m_data.fvec[1] = vec4.y();
+ v.m_data.fvec[2] = vec4.z();
+ v.m_data.fvec[3] = vec4.w();
+ break;
+ }
+ case QMetaType::QColor: {
+ const QColor col = variant.value<QColor>();
+ v.m_data.fvec[0] = col.redF();
+ v.m_data.fvec[1] = col.greenF();
+ v.m_data.fvec[2] = col.blueF();
+ v.m_data.fvec[3] = col.alphaF();
+ break;
+ }
+ case QMetaType::QMatrix4x4: {
+ const QMatrix4x4 mat44 = variant.value<QMatrix4x4>();
+ // Use constData because we want column-major layout
+ memcpy(v.data<float>(), mat44.constData(), sizeof(16 * sizeof(float)));
+ break;
+ }
+ default:
+ Q_UNREACHABLE();
+ }
+ return v;
+}
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/render/backend/uniform_p.h b/src/render/backend/uniform_p.h
new file mode 100644
index 000000000..aa4b06bf9
--- /dev/null
+++ b/src/render/backend/uniform_p.h
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DRENDER_RENDER_UNIFORM_P_H
+#define QT3DRENDER_RENDER_UNIFORM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qt3drender_global.h>
+#include <Qt3DCore/qnodeid.h>
+
+#include <QMatrix4x4>
+#include <QVector2D>
+#include <QVector3D>
+#include <QColor>
+
+#include <QDebug>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+namespace Render {
+
+enum UniformType {
+ Float = 0,
+ Vec2,
+ Vec3,
+ Vec4,
+ Double,
+ DVec2,
+ DVec3,
+ DVec4,
+ Int,
+ IVec2,
+ IVec3,
+ IVec4,
+ UInt,
+ UIVec2,
+ UIVec3,
+ UIVec4,
+ Bool,
+ BVec2,
+ BVec3,
+ BVec4,
+ Mat2,
+ Mat3,
+ Mat4,
+ Mat2x3,
+ Mat3x2,
+ Mat2x4,
+ Mat4x2,
+ Mat3x4,
+ Mat4x3,
+ Sampler,
+ Unknown
+};
+
+class Q_AUTOTEST_EXPORT UniformValue
+{
+public:
+ enum ValueType {
+ ScalarValue,
+ NodeId,
+ TextureValue,
+ BufferValue
+ };
+
+ struct Texture {
+ int textureId = 0; // Set first so that glUniform1iv will work
+ Qt3DCore::QNodeId nodeId;
+ };
+
+ // UniformValue implicitely converts doubles to floats to ensure
+ // correct rendering behavior for the cases where Qt3D parameters created from
+ // a double or QVariant(double) are used to fill uniform values that in reality
+ // should be floats. This occur especially with QML where qreal might be double
+ // and not float. Otherwise, at when filling the uniforms, calling constData<float>
+ // on something that contains a double will result in wrong values
+
+ UniformValue() {}
+ UniformValue(int i) { m_data.ivec[0] = i; }
+ UniformValue(uint i) { m_data.ivec[0] = i; }
+ UniformValue(float f) { m_data.fvec[0] = f; }
+ UniformValue(double d) { m_data.fvec[0] = d; } // Double to float conversion
+ UniformValue(bool b) { m_data.ivec[0] = b; }
+ UniformValue(const QVector2D &vec2) { memcpy(&m_data, &vec2, sizeof(QVector2D)); }
+ UniformValue(const QVector3D &vec3) { memcpy(&m_data, &vec3, sizeof(QVector3D)); }
+ UniformValue(const QVector4D &vec4) { memcpy(&m_data, &vec4, sizeof(QVector4D)); }
+
+ UniformValue(const QMatrix3x3 &mat33)
+ {
+ // Use constData because we want column-major layout
+ memcpy(&m_data, mat33.constData(), 9 * sizeof(float));
+ }
+
+ UniformValue(const QMatrix4x4 &mat44)
+ {
+ // Use constData because we want column-major layout
+ memcpy(&m_data, mat44.constData(), 16 * sizeof(float));
+ }
+
+ // For nodes which will later be replaced by a Texture or Buffer
+ UniformValue(Qt3DCore::QNodeId id)
+ {
+ m_valueType = NodeId;
+ memcpy(&m_data, &id, sizeof(Qt3DCore::QNodeId));
+ }
+
+ // For textures
+ UniformValue(UniformValue::Texture t)
+ {
+ m_valueType = TextureValue;
+ memcpy(&m_data, &t, sizeof(Texture));
+ }
+
+ ValueType valueType() const { return m_valueType; }
+
+ static UniformValue fromVariant(const QVariant &variant);
+
+ template<typename T>
+ const T *constData() const
+ {
+ return reinterpret_cast<const T *>(&m_data);
+ }
+
+ template<typename T>
+ T *data()
+ {
+ return reinterpret_cast<T *>(&m_data);
+ }
+
+ bool operator==(const UniformValue &other) const
+ {
+ return memcmp(&m_data, &other.m_data, sizeof(u_Uniform)) == 0;
+ }
+
+ bool operator!=(const UniformValue &other) const
+ {
+ return !(*this == other);
+ }
+private:
+ union u_Uniform {
+ int ivec[4]; // store uint/ints/bools
+ float fvec[16]; // for matrix4 (note: we could have a special case for matrices)
+
+ u_Uniform()
+ {
+ memset(this, 0, sizeof(u_Uniform));
+ }
+ } m_data;
+
+ ValueType m_valueType = ScalarValue;
+};
+
+} // namespace Render
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(Qt3DRender::Render::UniformType)
+
+#endif // QT3DRENDER_RENDER_UNIFORM_P_H