summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/DataModelMetadata/en-us/MetaData.xml10
-rw-r--r--src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp4
-rw-r--r--src/dm/systems/Qt3DSDMComposerTypeDefinitions.h4
-rw-r--r--src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp4
-rw-r--r--src/runtime/Qt3DSAttributeHashes.cpp4
-rw-r--r--src/runtime/Qt3DSAttributeHashes.h4
-rw-r--r--src/runtime/Qt3DSAttributeHashes.txt4
-rw-r--r--src/runtimerender/Qt3DSRenderUIPLoader.cpp4
-rw-r--r--src/runtimerender/Qt3DSRenderUIPSharedTranslation.h4
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderLayer.cpp4
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderLayer.h5
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderNode.cpp92
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderNode.h20
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp16
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp29
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h3
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp179
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h7
18 files changed, 391 insertions, 6 deletions
diff --git a/res/DataModelMetadata/en-us/MetaData.xml b/res/DataModelMetadata/en-us/MetaData.xml
index 99a5254..b1085d4 100644
--- a/res/DataModelMetadata/en-us/MetaData.xml
+++ b/res/DataModelMetadata/en-us/MetaData.xml
@@ -307,6 +307,16 @@
<ShowIfEqual property="vertfields" value="Top/Bottom"/>
<ShowIfEqual property="vertfields" value="Height/Bottom"/>
</Property>
+ <Property name="dynamicresize" formalName="Dynamic Resize" description="Resize the layer dynamically\nbased on the content" type="Boolean" default="False" category="Size" />
+ <Property name="dynamicpadding" formalName="Padding" description="Pad the resized layer to prevent constant\nresizing when small changes are made." min="0" default="0" animatable="False" category="Size">
+ <ShowIfEqual property="dynamicresize" value="True"/>
+ </Property>
+ <Property name="dynamicpaddingunits" formalName="Padding Units" description="Padding is percent of overall\nwidth or absolute pixels" list="percent:pixels" default="percent" category="Size">
+ <ShowIfEqual property="dynamicresize" value="True"/>
+ </Property>
+ <Property name="dynamiccombine" formalName="Combine Bounds" description="Combine layer object bounds for faster\ncalculation, but lower accuracy." type="Boolean" default="False" category="Size">
+ <ShowIfEqual property="dynamicresize" value="True"/>
+ </Property>
<!-- Ambient Occlusion -->
<Property name="aoenabled" formalName="Ambient Occlusion" description="Use ambient occlusion" type="Boolean" default="False" category="Ambient Occlusion">
diff --git a/src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp
index 53fed0c..3aacdec 100644
--- a/src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp
+++ b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.cpp
@@ -244,6 +244,10 @@ struct DataConstructor<SObjectRefType>
#define QT3DS_WCHAR_T_innertess L"innertess"
#define QT3DS_WCHAR_T_scalemode L"scalemode"
#define QT3DS_WCHAR_T_scaleanchor L"scaleanchor"
+#define QT3DS_WCHAR_T_dynamicresize L"dynamicresize"
+#define QT3DS_WCHAR_T_dynamicpaddingunits L"dynamicpaddingunits"
+#define QT3DS_WCHAR_T_dynamicpadding L"dynamicpadding"
+#define QT3DS_WCHAR_T_dynamiccombine L"dynamiccombine"
#define QT3DS_WCHAR_T_horzfields L"horzfields"
#define QT3DS_WCHAR_T_left L"left"
#define QT3DS_WCHAR_T_leftunits L"leftunits"
diff --git a/src/dm/systems/Qt3DSDMComposerTypeDefinitions.h b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.h
index 0770d19..e8bd139 100644
--- a/src/dm/systems/Qt3DSDMComposerTypeDefinitions.h
+++ b/src/dm/systems/Qt3DSDMComposerTypeDefinitions.h
@@ -208,6 +208,10 @@ class IPropertySystem;
HANDLE_COMPOSER_PROPERTY_DUPLICATE(backgroundcolor, m_BackgroundColor, SFloat4, \
SFloat4(0, 0, 0, 1)) \
HANDLE_COMPOSER_PROPERTY(blendtype, m_BlendType, TDataStrPtr, L"Normal") \
+ HANDLE_COMPOSER_PROPERTY(dynamicresize, m_DynamicResize, bool, false) \
+ HANDLE_COMPOSER_PROPERTY(dynamicpaddingunits, m_DynamicPaddingUnits, TDataStrPtr, L"percent") \
+ HANDLE_COMPOSER_PROPERTY(dynamicpadding, m_DynamicPadding, float, 0) \
+ HANDLE_COMPOSER_PROPERTY(dynamiccombine, m_DynamicCombine, bool, false) \
HANDLE_COMPOSER_PROPERTY(horzfields, m_HorizontalFieldValues, TDataStrPtr, L"Left/Width") \
HANDLE_COMPOSER_PROPERTY(left, m_Left, float, 0) \
HANDLE_COMPOSER_PROPERTY(leftunits, m_LeftUnits, TDataStrPtr, L"percent") \
diff --git a/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp b/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp
index f416d66..5c33eba 100644
--- a/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp
+++ b/src/engine/Qt3DSRenderRuntimeBindingImplTranslation.cpp
@@ -505,6 +505,10 @@ struct SRuntimePropertyParser
#define Layer_BlendType ATTRIBUTE_BLENDTYPE
#define Layer_ProgressiveAAMode ATTRIBUTE_PROGRESSIVEAA
#define Layer_MultisampleAAMode ATTRIBUTE_MULTISAMPLEAA
+#define Layer_DynamicResize ATTRIBUTE_DYNAMICRESIZE
+#define Layer_DynamicPaddingUnits ATTRIBUTE_DYNAMICPADDINGUNITS
+#define Layer_DynamicPadding ATTRIBUTE_DYNAMICPADDING
+#define Layer_DynamicCombine ATTRIBUTE_DYNAMICCOMBINE
#define Layer_HorizontalFieldValues ATTRIBUTE_HORZFIELDS
#define Layer_Left ATTRIBUTE_LEFT
#define Layer_LeftUnits ATTRIBUTE_LEFTUNITS
diff --git a/src/runtime/Qt3DSAttributeHashes.cpp b/src/runtime/Qt3DSAttributeHashes.cpp
index e9ef5d1..f126336 100644
--- a/src/runtime/Qt3DSAttributeHashes.cpp
+++ b/src/runtime/Qt3DSAttributeHashes.cpp
@@ -184,6 +184,10 @@ const char *GetAttributeString(const EAttribute inAttribute)
case ATTRIBUTE_MULTISAMPLEAA: return "multisampleaa";
case ATTRIBUTE_TEMPORALAA: return "temporalaa";
case ATTRIBUTE_BLENDTYPE: return "blendtype";
+ case ATTRIBUTE_DYNAMICRESIZE: return "dynamicresize";
+ case ATTRIBUTE_DYNAMICPADDINGUNITS: return "dynamicpaddingunits";
+ case ATTRIBUTE_DYNAMICPADDING: return "dynamicpadding";
+ case ATTRIBUTE_DYNAMICCOMBINE: return "dynamiccombine";
case ATTRIBUTE_HORZFIELDS: return "horzfields";
case ATTRIBUTE_LEFT: return "left";
case ATTRIBUTE_LEFTUNITS: return "leftunits";
diff --git a/src/runtime/Qt3DSAttributeHashes.h b/src/runtime/Qt3DSAttributeHashes.h
index 5127d1a..8979ddb 100644
--- a/src/runtime/Qt3DSAttributeHashes.h
+++ b/src/runtime/Qt3DSAttributeHashes.h
@@ -175,6 +175,10 @@ enum EAttribute {
ATTRIBUTE_MULTISAMPLEAA = 0x013D29FD, // multisampleaa
ATTRIBUTE_TEMPORALAA = 0x00212AFE, // temporalaa
ATTRIBUTE_BLENDTYPE = 0x0035B4F5, // blendtype
+ ATTRIBUTE_DYNAMICRESIZE = 0x030D218D, // dynamicresize
+ ATTRIBUTE_DYNAMICPADDINGUNITS = 0x01B34023, // dynamicpaddingunits
+ ATTRIBUTE_DYNAMICPADDING = 0x00A35EAE, // dynamicpadding
+ ATTRIBUTE_DYNAMICCOMBINE = 0x02CB0FC0, // dynamiccombine
ATTRIBUTE_HORZFIELDS = 0x02B8A818, // horzfields
ATTRIBUTE_LEFT = 0x0196B9B9, // left
ATTRIBUTE_LEFTUNITS = 0x02F9D2D8, // leftunits
diff --git a/src/runtime/Qt3DSAttributeHashes.txt b/src/runtime/Qt3DSAttributeHashes.txt
index 882517a..3549132 100644
--- a/src/runtime/Qt3DSAttributeHashes.txt
+++ b/src/runtime/Qt3DSAttributeHashes.txt
@@ -141,6 +141,10 @@ progressiveaa
multisampleaa
temporalaa
blendtype
+dynamicresize
+dynamicpaddingunits
+dynamicpadding
+dynamiccombine
horzfields
left
leftunits
diff --git a/src/runtimerender/Qt3DSRenderUIPLoader.cpp b/src/runtimerender/Qt3DSRenderUIPLoader.cpp
index 7d3ec0a..9630dc8 100644
--- a/src/runtimerender/Qt3DSRenderUIPLoader.cpp
+++ b/src/runtimerender/Qt3DSRenderUIPLoader.cpp
@@ -727,6 +727,10 @@ struct SRenderUIPLoader : public IDOMReferenceResolver
#define Layer_Size "size"
#define Layer_Location "location"
#define Layer_TexturePath "sourcepath"
+#define Layer_DynamicResize "dynamicresize"
+#define Layer_DynamicPaddingUnits "dynamicpaddingunits"
+#define Layer_DynamicPadding "dynamicpadding"
+#define Layer_DynamicCombine "dynamiccombine"
#define Layer_HorizontalFieldValues "horzfields"
#define Layer_Left "left"
#define Layer_LeftUnits "leftunits"
diff --git a/src/runtimerender/Qt3DSRenderUIPSharedTranslation.h b/src/runtimerender/Qt3DSRenderUIPSharedTranslation.h
index ca0e5e8..a7e8d4a 100644
--- a/src/runtimerender/Qt3DSRenderUIPSharedTranslation.h
+++ b/src/runtimerender/Qt3DSRenderUIPSharedTranslation.h
@@ -326,6 +326,10 @@ namespace render {
HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, BlendType, Dirty) \
HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, Background, Dirty) \
HANDLE_QT3DS_RENDER_SOURCEPATH_PROPERTY(Layer, TexturePath, Dirty) \
+ HANDLE_QT3DS_RENDER_PROPERTY(Layer, DynamicResize, Dirty) \
+ HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, DynamicPaddingUnits, Dirty) \
+ HANDLE_QT3DS_RENDER_PROPERTY(Layer, DynamicPadding, Dirty) \
+ HANDLE_QT3DS_RENDER_PROPERTY(Layer, DynamicCombine, Dirty) \
HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, HorizontalFieldValues, Dirty) \
HANDLE_QT3DS_RENDER_PROPERTY(Layer, Left, Dirty) \
HANDLE_QT3DS_RENDER_ENUM_PROPERTY(Layer, LeftUnits, Dirty) \
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderLayer.cpp b/src/runtimerender/graphobjects/Qt3DSRenderLayer.cpp
index be79fba..73957e8 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderLayer.cpp
+++ b/src/runtimerender/graphobjects/Qt3DSRenderLayer.cpp
@@ -43,6 +43,10 @@ SLayer::SLayer()
, m_Background(LayerBackground::Transparent)
, m_ClearColor(0.0f)
, m_BlendType(LayerBlendTypes::Normal)
+ , m_DynamicResize(false)
+ , m_DynamicPadding(0)
+ , m_DynamicPaddingUnits(LayerUnitTypes::Percent)
+ , m_DynamicCombine(false)
, m_HorizontalFieldValues(HorizontalFieldValues::LeftWidth)
, m_Left(0)
, m_LeftUnits(LayerUnitTypes::Percent)
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderLayer.h b/src/runtimerender/graphobjects/Qt3DSRenderLayer.h
index ac9f559..df1523d 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderLayer.h
+++ b/src/runtimerender/graphobjects/Qt3DSRenderLayer.h
@@ -129,6 +129,11 @@ namespace render {
LayerBlendTypes::Enum m_BlendType;
+ bool m_DynamicResize;
+ QT3DSF32 m_DynamicPadding;
+ LayerUnitTypes::Enum m_DynamicPaddingUnits;
+ bool m_DynamicCombine;
+
HorizontalFieldValues::Enum m_HorizontalFieldValues;
QT3DSF32 m_Left;
LayerUnitTypes::Enum m_LeftUnits;
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderNode.cpp b/src/runtimerender/graphobjects/Qt3DSRenderNode.cpp
index 9d42aa5..b3e557f 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderNode.cpp
+++ b/src/runtimerender/graphobjects/Qt3DSRenderNode.cpp
@@ -434,7 +434,7 @@ NVBounds3 SNode::GetChildBounds(IBufferManager &inManager, IPathManager &inPathM
NVBounds3 retval;
retval.setEmpty();
for (SNode *child = m_FirstChild; child != NULL; child = child->m_NextSibling) {
- if (inChildFilter == NULL || inChildFilter->IncludeNode(*child)) {
+ if (inChildFilter == nullptr || inChildFilter->IncludeNode(*child)) {
NVBounds3 childBounds;
if (child->m_Flags.IsTransformDirty())
child->CalculateLocalTransform();
@@ -449,6 +449,96 @@ NVBounds3 SNode::GetChildBounds(IBufferManager &inManager, IPathManager &inPathM
return retval;
}
+NVBounds3 SNode::GetActiveBounds(IBufferManager &inManager, IPathManager &inPathManager,
+ bool inIncludeChildren,
+ IQt3DSRenderNodeFilter *inChildFilter) const
+{
+ NVBounds3 retval;
+ retval.setEmpty();
+ if (inIncludeChildren)
+ retval = GetActiveChildBounds(inManager, inPathManager, inChildFilter);
+
+ if (m_Type == GraphObjectTypes::Model)
+ retval.include(static_cast<const SModel *>(this)->GetModelBounds(inManager));
+ else if (m_Type == GraphObjectTypes::Text)
+ retval.include(static_cast<const SText *>(this)->GetTextBounds());
+ else if (m_Type == GraphObjectTypes::Path)
+ retval.include(inPathManager.GetBounds(*static_cast<const SPath *>(this)));
+ return retval;
+}
+
+NVBounds3 SNode::GetActiveChildBounds(IBufferManager &inManager, IPathManager &inPathManager,
+ IQt3DSRenderNodeFilter *inChildFilter) const
+{
+ NVBounds3 retval;
+ retval.setEmpty();
+ for (SNode *child = m_FirstChild; child != nullptr; child = child->m_NextSibling) {
+ if (child->m_Flags.IsActive()
+ && (inChildFilter == nullptr || inChildFilter->IncludeNode(*child))) {
+ NVBounds3 childBounds;
+ if (child->m_Flags.IsTransformDirty())
+ child->CalculateLocalTransform();
+ childBounds = child->GetActiveBounds(inManager, inPathManager);
+ if (childBounds.isEmpty() == false) {
+ // Transform the bounds into our local space.
+ childBounds.transform(child->m_LocalTransform);
+ retval.include(childBounds);
+ }
+ }
+ }
+ return retval;
+}
+
+void SNode::GetActiveBoundsList(QVector<QT3DSVec3> &points, IBufferManager &inManager,
+ IPathManager &inPathManager,
+ QT3DSMat44 localTransform,
+ bool inIncludeChildren,
+ IQt3DSRenderNodeFilter *inChildFilter) const
+{
+ if (inIncludeChildren)
+ GetActiveChildBoundsList(points, inManager, inPathManager, localTransform, inChildFilter);
+
+ NVBounds3 bounds;
+ bounds.setEmpty();
+ if (m_Type == GraphObjectTypes::Model)
+ bounds = static_cast<const SModel *>(this)->GetModelBounds(inManager);
+ else if (m_Type == GraphObjectTypes::Text)
+ bounds = static_cast<const SText *>(this)->GetTextBounds();
+ else if (m_Type == GraphObjectTypes::Path)
+ bounds = inPathManager.GetBounds(*static_cast<const SPath *>(this));
+ if (!bounds.isEmpty()) {
+ QT3DSVec3 newPoints[8];
+ newPoints[0] = bounds.minimum;
+ newPoints[1] = QT3DSVec3(bounds.minimum.x, bounds.maximum.y, bounds.minimum.z);
+ newPoints[2] = QT3DSVec3(bounds.maximum.x, bounds.maximum.y, bounds.minimum.z);
+ newPoints[3] = QT3DSVec3(bounds.maximum.x, bounds.minimum.y, bounds.minimum.z);
+ newPoints[4] = QT3DSVec3(bounds.minimum.x, bounds.minimum.y, bounds.maximum.z);
+ newPoints[5] = QT3DSVec3(bounds.minimum.x, bounds.maximum.y, bounds.maximum.z);
+ newPoints[6] = QT3DSVec3(bounds.maximum.x, bounds.minimum.y, bounds.maximum.z);
+ newPoints[7] = bounds.maximum;
+ for (int i = 0; i < 8; ++i) {
+ // Transform the bounds into our local space.
+ points += localTransform.transform(newPoints[i]);
+ }
+ }
+}
+
+void SNode::GetActiveChildBoundsList(QVector<QT3DSVec3> &points, IBufferManager &inManager,
+ IPathManager &inPathManager,
+ QT3DSMat44 localTransform,
+ IQt3DSRenderNodeFilter *inChildFilter) const
+{
+ for (SNode *child = m_FirstChild; child != nullptr; child = child->m_NextSibling) {
+ if (child->m_Flags.IsActive()
+ && (inChildFilter == nullptr || inChildFilter->IncludeNode(*child))) {
+ if (child->m_Flags.IsTransformDirty())
+ child->CalculateLocalTransform();
+ QT3DSMat44 nextTransform = localTransform * child->m_LocalTransform;
+ child->GetActiveBoundsList(points, inManager, inPathManager, nextTransform);
+ }
+ }
+}
+
QT3DSVec3 SNode::GetGlobalPos() const
{
return m_GlobalTransform.getPosition();
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderNode.h b/src/runtimerender/graphobjects/Qt3DSRenderNode.h
index 751ed27..ea0d481 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderNode.h
+++ b/src/runtimerender/graphobjects/Qt3DSRenderNode.h
@@ -271,9 +271,25 @@ namespace render {
// Get the bounds of us and our children in our local space.
NVBounds3 GetBounds(IBufferManager &inManager, IPathManager &inPathManager,
bool inIncludeChildren = true,
- IQt3DSRenderNodeFilter *inChildFilter = NULL) const;
+ IQt3DSRenderNodeFilter *inChildFilter = nullptr) const;
NVBounds3 GetChildBounds(IBufferManager &inManager, IPathManager &inPathManager,
- IQt3DSRenderNodeFilter *inChildFilter = NULL) const;
+ IQt3DSRenderNodeFilter *inChildFilter = nullptr) const;
+ NVBounds3 GetActiveBounds(IBufferManager &inManager, IPathManager &inPathManager,
+ bool inIncludeChildren = true,
+ IQt3DSRenderNodeFilter *inChildFilter = nullptr) const;
+ NVBounds3 GetActiveChildBounds(IBufferManager &inManager, IPathManager &inPathManager,
+ IQt3DSRenderNodeFilter *inChildFilter = nullptr) const;
+ void GetActiveBoundsList(QVector<QT3DSVec3> &points,
+ IBufferManager &inManager,
+ IPathManager &inPathManager,
+ QT3DSMat44 localTransform = QT3DSMat44::createIdentity(),
+ bool inIncludeChildren = true,
+ IQt3DSRenderNodeFilter *inChildFilter = nullptr) const;
+ void GetActiveChildBoundsList(QVector<QT3DSVec3> &points,
+ IBufferManager &inManager,
+ IPathManager &inPathManager,
+ QT3DSMat44 localTransform = QT3DSMat44::createIdentity(),
+ IQt3DSRenderNodeFilter *inChildFilter = nullptr) const;
// Assumes CalculateGlobalVariables has already been called.
QT3DSVec3 GetGlobalPos() const;
QT3DSVec3 GetGlobalPivot() const;
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
index 62ae506..9f47d47 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
@@ -1410,7 +1410,7 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn,
QT3DS_ASSERT(m_LayerPrepResult->m_Flags.ShouldRenderToTexture());
SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult);
NVRenderContext &theRenderContext(m_Renderer.GetContext());
- QSize theLayerTextureDimensions = thePrepResult.GetTextureDimensions();
+ QSize theLayerTextureDimensions(thePrepResult.GetTextureDimensions());
QSize theLayerOriginalTextureDimensions = theLayerTextureDimensions;
NVRenderTextureFormats::Enum DepthTextureFormat = NVRenderTextureFormats::Depth24Stencil8;
NVRenderTextureFormats::Enum ColorTextureFormat = NVRenderTextureFormats::RGBA8;
@@ -1647,6 +1647,20 @@ void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn,
hasDepthObjects || thePrepResult.m_Flags.RequiresStencilBuffer();
NVRenderRect theNewViewport(0, 0, theLayerTextureDimensions.width(),
theLayerTextureDimensions.height());
+
+ if (m_Layer.m_DynamicResize && theLayerOriginalTextureDimensions.width() != 0) {
+ // With dynamic resize the viewport should behave like it just crops the full layer
+ // So a special viewport has to be calculated that keeps the original object sizes
+ float ratio = theLayerTextureDimensions.width()
+ / theLayerOriginalTextureDimensions.width();
+ auto originalLayerViewport = thePrepResult.getOriginalLayerToPresentationViewport();
+ auto layerViewport = thePrepResult.GetLayerToPresentationViewport();
+ theNewViewport = NVRenderRect((-layerViewport.m_X + originalLayerViewport.m_X) * ratio,
+ (-layerViewport.m_Y + originalLayerViewport.m_Y) * ratio,
+ originalLayerViewport.m_Width * ratio,
+ originalLayerViewport.m_Height * ratio);
+ }
+
{
theRenderContext.SetRenderTarget(theFB);
NVRenderContextScopedProperty<NVRenderRect> __viewport(
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp
index 49d6468..4fef629 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.cpp
@@ -178,9 +178,9 @@ SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewpo
m_Viewport.m_Width = NVMax(1.0f, m_Viewport.m_Width);
m_Viewport.m_Height = NVMax(1.0f, m_Viewport.m_Height);
- // Now force the viewport to be a multiple of four in width and height. This is because
+ // Now force the viewport to be a multiple of four in width and height. This is because
// when rendering to a texture we have to respect this and not forcing it causes scaling issues
- // that are noticeable especially in situations where customers are using text and such.
+ // that are noticeable especially in situations where customers are using text.
QT3DSF32 originalWidth = m_Viewport.m_Width;
QT3DSF32 originalHeight = m_Viewport.m_Height;
@@ -191,6 +191,7 @@ SLayerRenderHelper::SLayerRenderHelper(const NVRenderRectF &inPresentationViewpo
m_Viewport.m_X += (originalWidth - m_Viewport.m_Width) / 2.0f;
m_Viewport.m_Y += (originalHeight - m_Viewport.m_Height) / 2.0f;
+ m_originalViewport = m_Viewport;
m_Scissor = m_Viewport;
m_Scissor.EnsureInBounds(inPresentationScissor);
QT3DS_ASSERT(m_Scissor.m_Width >= 0.0f);
@@ -341,6 +342,30 @@ bool SLayerRenderHelper::isStereoscopic() const
return m_StereoMode != StereoModes::Mono;
}
+void SLayerRenderHelper::setViewport(const NVRenderRectF &viewport)
+{
+ m_Viewport = viewport;
+ m_Viewport.m_Width = NVMax(1.0f, m_Viewport.m_Width);
+ m_Viewport.m_Height = NVMax(1.0f, m_Viewport.m_Height);
+ // Now force the viewport to be a multiple of four in width and height. This is because
+ // when rendering to a texture we have to respect this and not forcing it causes scaling issues
+ // that are noticeable especially in situations where customers are using text.
+ QT3DSF32 originalWidth = m_Viewport.m_Width;
+ QT3DSF32 originalHeight = m_Viewport.m_Height;
+
+ m_Viewport.m_Width = (QT3DSF32)ITextRenderer::NextMultipleOf4((QT3DSU32)m_Viewport.m_Width);
+ m_Viewport.m_Height = (QT3DSF32)ITextRenderer::NextMultipleOf4((QT3DSU32)m_Viewport.m_Height);
+
+ // Now fudge the offsets to account for this slight difference
+ m_Viewport.m_X += (originalWidth - m_Viewport.m_Width) / 2.0f;
+ m_Viewport.m_Y += (originalHeight - m_Viewport.m_Height) / 2.0f;
+}
+
+NVRenderRectF SLayerRenderHelper::getOriginalLayerToPresentationViewport() const
+{
+ return m_originalViewport;
+}
+
void SLayerRenderHelper::copyCameraProperties(SCamera *sourceCamera,
SCamera *destinationCamera)
{
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h
index 19fd3f5..59f4e08 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderHelper.h
@@ -64,6 +64,7 @@ namespace render {
SCamera *m_CameraRightEye;
bool m_Offscreen;
+ NVRenderRectF m_originalViewport;
NVRenderRectF m_Viewport;
NVRenderRectF m_Scissor;
@@ -103,8 +104,10 @@ namespace render {
QT3DSF32 getEyeSeparation() const { return m_StereoEyeSeparation; }
void setEyeSeparation(QT3DSF32 separation) { m_StereoEyeSeparation = separation; }
+ void setViewport(const NVRenderRectF &viewport);
// Does not differ whether offscreen or not, simply states how this layer maps to the
// presentation
+ NVRenderRectF getOriginalLayerToPresentationViewport() const;
NVRenderRectF GetLayerToPresentationViewport() const;
// Does not differ whether offscreen or not, scissor rect of how this layer maps to
// presentation.
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
index 9c1da26..eb098b4 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
@@ -1220,6 +1220,181 @@ namespace render {
}
};
+ void SLayerRenderPreparationData::calculateDynamicLayerSize(
+ SLayerRenderPreparationResult &prepResult)
+ {
+ m_boundPoints.clear();
+ if (m_Layer.m_DynamicCombine) {
+ // Combine all bounds of the layer objects to one spanning the whole active scene
+ // Only needs 8 projections but has low accuracy
+ NVBounds3 layerBounds;
+ layerBounds.setEmpty();
+ for (SNode *child = m_Layer.m_FirstChild; child; child = child->m_NextSibling) {
+ if (child->m_Flags.IsActive()) {
+ auto &context = m_Renderer.GetQt3DSContext();
+ qt3ds::NVBounds3 childBounds = child->GetActiveBounds(
+ context.GetBufferManager(), context.GetPathManager());
+ if (childBounds.isEmpty() == false) {
+ childBounds.transform(child->m_GlobalTransform);
+ layerBounds.include(childBounds);
+ }
+ }
+ }
+
+ m_boundPoints += QT3DSVec3(layerBounds.minimum.x, layerBounds.minimum.y,
+ layerBounds.minimum.z);
+ m_boundPoints += QT3DSVec3(layerBounds.maximum.x, layerBounds.minimum.y,
+ layerBounds.minimum.z);
+ m_boundPoints += QT3DSVec3(layerBounds.maximum.x, layerBounds.maximum.y,
+ layerBounds.minimum.z);
+ m_boundPoints += QT3DSVec3(layerBounds.minimum.x, layerBounds.maximum.y,
+ layerBounds.minimum.z);
+ m_boundPoints += QT3DSVec3(layerBounds.minimum.x, layerBounds.minimum.y,
+ layerBounds.maximum.z);
+ m_boundPoints += QT3DSVec3(layerBounds.maximum.x, layerBounds.minimum.y,
+ layerBounds.maximum.z);
+ m_boundPoints += QT3DSVec3(layerBounds.maximum.x, layerBounds.maximum.y,
+ layerBounds.maximum.z);
+ m_boundPoints += QT3DSVec3(layerBounds.minimum.x, layerBounds.maximum.y,
+ layerBounds.maximum.z);
+ } else {
+ // Add 8 points for each active object to the point list
+ // Provides accurate 2d bounds, but causes a lot of projections for large scenes
+ for (SNode *child = m_Layer.m_FirstChild; child; child = child->m_NextSibling) {
+ if (child->m_Flags.IsActive()) {
+ auto &context = m_Renderer.GetQt3DSContext();
+ child->GetActiveBoundsList(m_boundPoints, context.GetBufferManager(),
+ context.GetPathManager(), child->m_GlobalTransform);
+ }
+ }
+ }
+
+ auto layerViewport = prepResult.GetLayerToPresentationViewport();
+
+ QT3DSVec2 projectedMinimum(std::numeric_limits<float>::max(),
+ std::numeric_limits<float>::max());
+ QT3DSVec2 projectedMaximum(std::numeric_limits<float>::lowest(),
+ std::numeric_limits<float>::lowest());
+
+ for (const auto &point : qAsConst(m_boundPoints)) {
+ QT3DSVec4 projectedPoint = m_ViewProjection.transform(QT3DSVec4(point, 1.0f));
+ projectedPoint.x /= projectedPoint.w;
+ projectedPoint.y /= projectedPoint.w;
+ projectedPoint.x += 1.0f;
+ projectedPoint.y += 1.0f;
+ projectedPoint.x *= 0.5f;
+ projectedPoint.y *= 0.5f;
+
+ QT3DSVec2 dims(QT3DSF32(layerViewport.m_Width),
+ QT3DSF32(layerViewport.m_Height));
+ projectedPoint.x *= dims.x;
+ projectedPoint.y *= dims.y;
+ projectedPoint.x += layerViewport.m_X;
+ projectedPoint.y += layerViewport.m_Y;
+
+ if (projectedPoint.x < projectedMinimum.x)
+ projectedMinimum.x = projectedPoint.x;
+ if (projectedPoint.y < projectedMinimum.y)
+ projectedMinimum.y = projectedPoint.y;
+ if (projectedPoint.x > projectedMaximum.x)
+ projectedMaximum.x = projectedPoint.x;
+ if (projectedPoint.y > projectedMaximum.y)
+ projectedMaximum.y = projectedPoint.y;
+ }
+
+ float boundsLeft = projectedMinimum.x;
+ float boundsBottom = projectedMinimum.y;
+ float boundsWidth = qAbs(projectedMaximum.x - projectedMinimum.x);
+ float boundsHeight = qAbs(projectedMaximum.y - projectedMinimum.y);
+
+ float paddedBoundsLeft = boundsLeft;
+ float paddedBoundsBottom = boundsBottom;
+ float paddedBoundsWidth = boundsWidth;
+ float paddedBoundsHeight = boundsHeight;
+
+ if (m_Layer.m_DynamicPadding > 0) {
+ float unpaddedBoundsLeft;
+ float unpaddedBoundsBottom;
+ float unpaddedBoundsWidth;
+ float unpaddedBoundsHeight;
+
+ if (m_Layer.m_DynamicPaddingUnits == LayerUnitTypes::Pixels) {
+ paddedBoundsLeft = boundsLeft - m_Layer.m_DynamicPadding;
+ paddedBoundsBottom = boundsBottom - m_Layer.m_DynamicPadding;
+ paddedBoundsWidth = boundsWidth + m_Layer.m_DynamicPadding * 2;
+ paddedBoundsHeight = boundsHeight + m_Layer.m_DynamicPadding * 2;
+
+ unpaddedBoundsLeft = boundsLeft + m_Layer.m_DynamicPadding;
+ unpaddedBoundsBottom = boundsBottom + m_Layer.m_DynamicPadding;
+ unpaddedBoundsWidth = boundsWidth - m_Layer.m_DynamicPadding * 2;
+ unpaddedBoundsHeight = boundsHeight - m_Layer.m_DynamicPadding * 2;
+ } else {
+ const float leftPadding = boundsWidth * m_Layer.m_DynamicPadding * 0.01f;
+ const float bottomPadding = boundsHeight * m_Layer.m_DynamicPadding * 0.01f;
+ const float widthPadding = m_Layer.m_DynamicPadding * 0.02f;
+ const float heightPadding = m_Layer.m_DynamicPadding * 0.02f;
+
+ paddedBoundsLeft = boundsLeft - leftPadding;
+ paddedBoundsBottom = boundsBottom - bottomPadding;
+ paddedBoundsWidth = boundsWidth * (1.0f + widthPadding);
+ paddedBoundsHeight = boundsHeight * (1.0f + heightPadding);
+
+ unpaddedBoundsLeft = boundsLeft + leftPadding;
+ unpaddedBoundsBottom = boundsBottom + bottomPadding;
+ unpaddedBoundsWidth = boundsWidth * (1.0f - widthPadding);
+ unpaddedBoundsHeight = boundsHeight * (1.0f - heightPadding);
+ }
+
+ // Both the padded and unpadded bounds are calculated
+ // Padded provides the upper bound when size has to be recalculated
+ // Unpadded provides the lower bound
+ // If the newly calculated bounds fit between the padded and unpadded ones
+ // use the previous calculations instead
+ if (m_Layer.m_DynamicPadding == m_lastDynamicPadding
+ && m_Layer.m_DynamicPaddingUnits == m_lastDynamicPaddingUnits
+ && m_unpaddedDynamicSize.m_X >= boundsLeft
+ && m_unpaddedDynamicSize.m_Y >= boundsBottom
+ && m_unpaddedDynamicSize.m_X + m_unpaddedDynamicSize.m_Width
+ <= boundsLeft + boundsWidth
+ && m_unpaddedDynamicSize.m_Y + m_unpaddedDynamicSize.m_Height
+ <= boundsBottom + boundsHeight
+ && m_dynamicSize.m_X <= boundsLeft
+ && m_dynamicSize.m_Y <= boundsBottom
+ && m_dynamicSize.m_X + m_dynamicSize.m_Width
+ >= boundsLeft + boundsWidth
+ && m_dynamicSize.m_Y + m_dynamicSize.m_Height
+ >= boundsBottom + boundsHeight) {
+ paddedBoundsLeft = m_dynamicSize.m_X;
+ paddedBoundsBottom = m_dynamicSize.m_Y;
+ paddedBoundsWidth = m_dynamicSize.m_Width;
+ paddedBoundsHeight = m_dynamicSize.m_Height;
+ } else {
+ m_unpaddedDynamicSize = NVRenderRectF(unpaddedBoundsLeft,
+ unpaddedBoundsBottom,
+ unpaddedBoundsWidth,
+ unpaddedBoundsHeight);
+ m_dynamicSize = NVRenderRectF(paddedBoundsLeft,
+ paddedBoundsBottom,
+ paddedBoundsWidth,
+ paddedBoundsHeight);
+ }
+ m_lastDynamicPadding = m_Layer.m_DynamicPadding;
+ m_lastDynamicPaddingUnits = m_Layer.m_DynamicPaddingUnits;
+ }
+
+ if (paddedBoundsLeft < layerViewport.m_X)
+ paddedBoundsLeft = layerViewport.m_X;
+ if (paddedBoundsBottom < layerViewport.m_Y)
+ paddedBoundsBottom = layerViewport.m_Y;
+ if (paddedBoundsWidth > layerViewport.m_Width)
+ paddedBoundsWidth = layerViewport.m_Width;
+ if (paddedBoundsHeight > layerViewport.m_Height)
+ paddedBoundsHeight = layerViewport.m_Height;
+
+ prepResult.setViewport(NVRenderRectF(paddedBoundsLeft, paddedBoundsBottom,
+ paddedBoundsWidth, paddedBoundsHeight));
+ }
+
bool SLayerRenderPreparationData::PrepareForRender(const QSize &inViewportDimensions)
{
QT3DS_PERF_SCOPED_TIMER(m_Renderer.GetQt3DSContext().GetPerfTimer(),
@@ -1497,6 +1672,10 @@ namespace render {
QT3DSF32 theTextScaleFactor = 1.0f;
if (m_Camera) {
m_Camera->CalculateViewProjectionMatrix(m_ViewProjection);
+
+ if (m_Layer.m_DynamicResize)
+ calculateDynamicLayerSize(thePrepResult);
+
theTextScaleFactor = m_Camera->GetTextScaleFactor(
thePrepResult.GetLayerToPresentationViewport(),
thePrepResult.GetPresentationDesignDimensions());
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h
index 376749e..fd9b86e 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.h
@@ -267,6 +267,11 @@ namespace render {
TRenderableObjectList m_OpaqueObjects;
TRenderableObjectList m_TransparentObjects;
TRenderableObjectList m_GroupObjects;
+ QVector<QT3DSVec3> m_boundPoints;
+ NVRenderRectF m_dynamicSize;
+ NVRenderRectF m_unpaddedDynamicSize;
+ float m_lastDynamicPadding = 0;
+ LayerUnitTypes::Enum m_lastDynamicPaddingUnits = LayerUnitTypes::Percent;
// Sorted lists of the rendered objects. There may be other transforms applied so
// it is simplest to duplicate the lists.
TRenderableObjectList m_RenderedOpaqueObjects;
@@ -343,6 +348,8 @@ namespace render {
QT3DSF32 inTextScaleFactor,
SLayerRenderPreparationResultFlags &ioFlags);
+ void calculateDynamicLayerSize(SLayerRenderPreparationResult &prepResult);
+
// returns true if this object will render something different than it rendered the last
// time.
virtual bool PrepareForRender(const QSize &inViewportDimensions);