summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Kokko <antti.kokko@qt.io>2020-06-25 07:32:53 +0300
committerAntti Kokko <antti.kokko@qt.io>2020-06-25 07:32:53 +0300
commitdd9baa255af6aff800e536781bce369fcc8a3547 (patch)
tree224c0d11aa0e82eb609bcff0eacc1d42b95604f9
parent02e4d56d055d73340d3af1257b908a52aecc320f (diff)
parent1c2f256c2afd320bec7e94bfc94760892d6fc9e8 (diff)
Merge branch '2.7'
-rw-r--r--commonplatform.pri2
-rw-r--r--ogl-runtime.pro3
m---------src/3rdparty/EASTL0
-rw-r--r--src/api/studio3d/q3dscommandqueue.cpp5
-rw-r--r--src/api/studio3d/q3dscommandqueue_p.h2
-rw-r--r--src/api/studio3d/q3dspresentation.cpp40
-rw-r--r--src/api/studio3d/q3dsviewersettings.cpp54
-rw-r--r--src/api/studio3d/q3dsviewersettings.h4
-rw-r--r--src/api/studio3d/q3dsviewersettings_p.h2
-rw-r--r--src/api/studio3dqml/q3dsrenderer.cpp2
-rw-r--r--src/engine/Qt3DSRenderRuntimeBinding.cpp23
-rw-r--r--src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp10
-rw-r--r--src/engine/Qt3DSRuntimeView.h2
-rw-r--r--src/foundation/Qt3DSAllocator.h4
-rw-r--r--src/runtime/Qt3DSActivationManager.cpp19
-rw-r--r--src/runtime/Qt3DSApplication.cpp30
-rw-r--r--src/runtime/Qt3DSIScriptBridge.h1
-rw-r--r--src/runtime/Qt3DSQmlEngine.cpp13
-rw-r--r--src/runtimerender/Qt3DSRenderContextCore.cpp36
-rw-r--r--src/runtimerender/Qt3DSRenderContextCore.h7
-rw-r--r--src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp50
-rw-r--r--src/runtimerender/Qt3DSRenderEffectSystem.cpp8
-rw-r--r--src/runtimerender/Qt3DSRenderSubpresentation.cpp5
-rw-r--r--src/runtimerender/Qt3DSRenderer.h2
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp20
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderImage.cpp10
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderNode.h9
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderScene.cpp4
-rw-r--r--src/runtimerender/graphobjects/Qt3DSRenderScene.h2
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp2
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImpl.h4
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp101
-rw-r--r--src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp2
-rw-r--r--src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp2
-rw-r--r--src/uipparser/Qt3DSUIPParserImpl.cpp14
-rw-r--r--src/uipparser/Qt3DSUIPParserImpl.h3
-rw-r--r--src/viewer/Qt3DSViewerApp.cpp6
-rw-r--r--src/viewer/Qt3DSViewerApp.h2
38 files changed, 384 insertions, 121 deletions
diff --git a/commonplatform.pri b/commonplatform.pri
index 732d874..f1a114c 100644
--- a/commonplatform.pri
+++ b/commonplatform.pri
@@ -62,7 +62,6 @@ linux-clang {
macos {
DEFINES += _MACOSX _LINUXPLATFORM WIDE_IS_DIFFERENT_TYPE_THAN_CHAR16_T
- INCLUDEPATH += /usr/local/include
# macOS builds treat most warnings as errors to prevent slipping more warnings
# in to the code
@@ -262,7 +261,6 @@ clang {
android {
QMAKE_CXXFLAGS -= -fstack-protector-strong
QMAKE_CFLAGS -= -fstack-protector-strong
- INCLUDEPATH += $$(ANDROID_NDK_ROOT)/sysroot/usr/include
DEFINES += __BITS_PER_LONG=32
}
diff --git a/ogl-runtime.pro b/ogl-runtime.pro
index 44d9fd6..0e399c3 100644
--- a/ogl-runtime.pro
+++ b/ogl-runtime.pro
@@ -8,7 +8,7 @@ integrity {
CHECK_INTEGRITY_DIR = $$(INTEGRITY_DIR)
}
-ios|tvos|watchos|winrt|wasm|*-icc*|contains(CHECK_INTEGRITY_DIR, .*int1144$) {
+ios|tvos|watchos|winrt|wasm|*-icc*|contains(CHECK_INTEGRITY_DIR, .*int1144$)|contains(QMAKE_HOST.arch, mips64)|contains(QT_ARCH, mips64) {
message("WARNING, target not supported by ogl-runtime")
#Exclude non-working cross-compile targets, see:
# QT3DS-3647 ogl-runtime doesn't compile on TvOS_ANY in CI
@@ -16,6 +16,7 @@ ios|tvos|watchos|winrt|wasm|*-icc*|contains(CHECK_INTEGRITY_DIR, .*int1144$) {
# QT3DS-3646 ogl-runtime doesn't compile on IOS_ANY in CI
# QT3DS-3649 ogl-runtime doesn't compile on WinRT in CI
# QT3DS-3650 ogl-runtime doesn't compile on WebAssembly in CI
+ # QT3DS-4129 ogl-runtime doesn't compile on Qemu mips64 in CI
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += src_dummy
diff --git a/src/3rdparty/EASTL b/src/3rdparty/EASTL
-Subproject 31697c758f2ed19bd7c6bbe61f1b91f9e12035b
+Subproject 0d1d5505c1e6c2af3f77680979d9b237e9fbf35
diff --git a/src/api/studio3d/q3dscommandqueue.cpp b/src/api/studio3d/q3dscommandqueue.cpp
index 300c0bf..a839e69 100644
--- a/src/api/studio3d/q3dscommandqueue.cpp
+++ b/src/api/studio3d/q3dscommandqueue.cpp
@@ -219,6 +219,8 @@ void CommandQueue::copyCommands(CommandQueue &fromQueue)
= m_stereoEyeSeparationChanged || fromQueue.m_stereoEyeSeparationChanged;
m_stereoProgressiveEnabledChanged
= m_stereoProgressiveEnabledChanged || fromQueue.m_stereoProgressiveEnabledChanged;
+ m_skipFramesIntervalChanged
+ = m_skipFramesIntervalChanged || fromQueue.m_skipFramesIntervalChanged;
m_shadeModeChanged = m_shadeModeChanged || fromQueue.m_shadeModeChanged;
m_showRenderStatsChanged = m_showRenderStatsChanged || fromQueue.m_showRenderStatsChanged;
m_matteColorChanged = m_matteColorChanged || fromQueue.m_matteColorChanged;
@@ -240,6 +242,8 @@ void CommandQueue::copyCommands(CommandQueue &fromQueue)
m_stereoEyeSeparation = fromQueue.m_stereoEyeSeparation;
if (fromQueue.m_stereoProgressiveEnabledChanged)
m_stereoProgressiveEnabled = fromQueue.m_stereoProgressiveEnabled;
+ if (fromQueue.m_skipFramesIntervalChanged)
+ m_skipFramesInterval = fromQueue.m_skipFramesInterval;
if (fromQueue.m_shadeModeChanged)
m_shadeMode = fromQueue.m_shadeMode;
if (fromQueue.m_showRenderStatsChanged)
@@ -343,6 +347,7 @@ void CommandQueue::clear(bool deleteCommandData)
m_stereoModeChanged = false;
m_stereoEyeSeparationChanged = false;
m_stereoProgressiveEnabledChanged = false;
+ m_skipFramesIntervalChanged = false;
m_shadeModeChanged = false;
m_showRenderStatsChanged = false;
m_matteColorChanged = false;
diff --git a/src/api/studio3d/q3dscommandqueue_p.h b/src/api/studio3d/q3dscommandqueue_p.h
index 6096439..9939cb0 100644
--- a/src/api/studio3d/q3dscommandqueue_p.h
+++ b/src/api/studio3d/q3dscommandqueue_p.h
@@ -144,6 +144,7 @@ public:
bool m_stereoModeChanged = false;
bool m_stereoEyeSeparationChanged = false;
bool m_stereoProgressiveEnabledChanged = false;
+ bool m_skipFramesIntervalChanged = false;
bool m_shadeModeChanged = false;
bool m_showRenderStatsChanged = false;
bool m_matteColorChanged = false;
@@ -159,6 +160,7 @@ public:
Q3DSViewerSettings::StereoMode m_stereoMode = Q3DSViewerSettings::StereoModeMono;
double m_stereoEyeSeparation = 0.4;
bool m_stereoProgressiveEnabled = false;
+ int m_skipFramesInterval = 0;
Q3DSViewerSettings::ShadeMode m_shadeMode = Q3DSViewerSettings::ShadeModeShaded;
bool m_showRenderStats = false;
QColor m_matteColor = QColor(Qt::black);
diff --git a/src/api/studio3d/q3dspresentation.cpp b/src/api/studio3d/q3dspresentation.cpp
index f0ca867..c711bbc 100644
--- a/src/api/studio3d/q3dspresentation.cpp
+++ b/src/api/studio3d/q3dspresentation.cpp
@@ -943,6 +943,22 @@ void Q3DSPresentation::setShaderCacheFile(const QUrl &fileName)
*/
/*!
+ \qmlsignal Presentation::shaderCacheLoadErrors(string errors)
+ \since QtStudio3D.OpenGL 2.7
+
+ Emitted when a shader cache loading fails. The parameter \a errors contains the error
+ message(s).
+ */
+
+/*!
+ \fn Q3DSPresentation::shaderCacheLoadErrors(const QString &errors)
+ \since Qt 3D Studio 2.7
+
+ Emitted when a shader cache loading fails. The parameter \a errors contains the error
+ message(s).
+ */
+
+/*!
This function is for backwards compatibility. We recommend using \l{DataInput}s to control
slide changes. \l{DataInput} provides stronger contract between the design and
code as it avoids use of elementPath (a reference to design's internal structure).
@@ -1126,6 +1142,30 @@ void Q3DSPresentation::setAttribute(const QString &elementPath, const QString &a
"image://colors/blue" where "image://" tells the runtime to look for an
image provider, "colors" is the image provider id and rest are the image
id the provider uses to create the image.
+
+ Usage is similar to the examples in https://doc.qt.io/qt-5/qquickimageprovider.html
+
+ \badcode
+ // Example implementation of a request function
+ // This returns a 50 x 50 px size green texture as a QPixmap
+ QPixmap ImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
+ {
+ // Size needs to be more than 0,0 or nothing will be drawn
+ if (size)
+ *size = QSize(50, 50);
+
+ QPixmap pixmap(50, 50);
+ pixmap.fill(QColor("green"));
+ return pixmap;
+ }
+
+ // Image providers are added to the presentation after viewer creation
+ viewer.create(&window, &context);
+ viewer.presentation()->addImageProvider("green", new ImageProvider());
+
+ // Use as texture
+ viewer.presentation()->setAttribute("Scene.Layer.Rectangle.Material.diffusemap", "sourcepath", "image://green");
+ \endcode
*/
void Q3DSPresentation::addImageProvider(const QString &providerId, QQmlImageProviderBase *provider)
{
diff --git a/src/api/studio3d/q3dsviewersettings.cpp b/src/api/studio3d/q3dsviewersettings.cpp
index 9025bb8..cbb273a 100644
--- a/src/api/studio3d/q3dsviewersettings.cpp
+++ b/src/api/studio3d/q3dsviewersettings.cpp
@@ -371,6 +371,44 @@ void Q3DSViewerSettings::setStereoProgressiveEnabled(bool enabled)
}
/*!
+ \qmlproperty int ViewerSettings::skipFramesInterval
+
+ \since QtStudio3D.OpenGL 2.7
+
+ Sets interval for skipping frame rendering. The default value is 0
+ meaning all frames are rendered. Setting this to 1 renders every
+ other frame (30fps on 60Hz screen), 2 every third frame (20fps on
+ 60Hz screen) etc. This property allows slowing down 3D rendering
+ while keeping QtQuick UI rendering intact, decreasing the CPU/GPU
+ usage.
+ */
+/*!
+ \property Q3DSViewerSettings::skipFramesInterval
+
+ \since Qt 3D Studio 2.7
+
+ Sets interval for skipping frame rendering. The default value is 0
+ meaning all frames are rendered. Setting this to 1 renders every
+ other frame (30fps on 60Hz screen), 2 every third frame (20fps on
+ 60Hz screen) etc. This property allows slowing down 3D rendering
+ while keeping QtQuick UI rendering intact, decreasing the CPU/GPU
+ usage.
+ */
+
+int Q3DSViewerSettings::skipFramesInterval() const
+{
+ return d_ptr->m_skipFramesInterval;
+}
+
+void Q3DSViewerSettings::setSkipFramesInterval(int interval)
+{
+ if (d_ptr->m_skipFramesInterval != interval) {
+ d_ptr->setSkipFramesInterval(interval);
+ Q_EMIT skipFramesIntervalChanged(interval);
+ }
+}
+
+/*!
\qmlproperty bool ViewerSettings::matteEnabled
Specifies if the empty area around the presentation (applicable when
@@ -450,6 +488,7 @@ Q3DSViewerSettingsPrivate::Q3DSViewerSettingsPrivate(Q3DSViewerSettings *q)
, m_stereoMode(Q3DSViewerSettings::StereoModeMono)
, m_stereoEyeSeparation(0.4)
, m_stereoProgressiveEnabled(false)
+ , m_skipFramesInterval(0)
, m_savedSettings(nullptr)
{
}
@@ -470,6 +509,7 @@ void Q3DSViewerSettingsPrivate::setViewerApp(Q3DSViewer::Q3DSViewerApp *app)
setStereoMode(m_stereoMode);
setStereoEyeSeparation(m_stereoEyeSeparation);
setStereoProgressiveEnabled(m_stereoProgressiveEnabled);
+ setSkipFramesInterval(m_skipFramesInterval);
}
}
@@ -485,6 +525,7 @@ void Q3DSViewerSettingsPrivate::setCommandQueue(CommandQueue *queue)
setStereoMode(m_stereoMode);
setStereoEyeSeparation(m_stereoEyeSeparation);
setStereoProgressiveEnabled(m_stereoProgressiveEnabled);
+ setSkipFramesInterval(m_skipFramesInterval);
}
}
@@ -519,6 +560,8 @@ void Q3DSViewerSettingsPrivate::load(const QString &group, const QString &organi
m_savedSettings->value(QStringLiteral("stereoEyeSeparation")).toDouble());
q_ptr->setStereoProgressiveEnabled(
m_savedSettings->value(QStringLiteral("stereoProgressiveEnabled")).toBool());
+ q_ptr->setSkipFramesInterval(
+ m_savedSettings->value(QStringLiteral("skipFramesInterval")).toInt());
q_ptr->setMatteEnabled(m_savedSettings->value(QStringLiteral("matteEnabled")).toBool());
}
@@ -627,6 +670,17 @@ void Q3DSViewerSettingsPrivate::setStereoProgressiveEnabled(bool enabled)
}
}
+void Q3DSViewerSettingsPrivate::setSkipFramesInterval(int interval)
+{
+ m_skipFramesInterval = interval;
+ if (m_viewerApp) {
+ m_viewerApp->SetSkipFramesInterval(interval);
+ } else if (m_commandQueue) {
+ m_commandQueue->m_skipFramesInterval = interval;
+ m_commandQueue->m_skipFramesIntervalChanged = true;
+ }
+}
+
void Q3DSViewerSettingsPrivate::initSettingsStore(const QString &group, const QString &organization,
const QString &application)
{
diff --git a/src/api/studio3d/q3dsviewersettings.h b/src/api/studio3d/q3dsviewersettings.h
index f956649..80b36df 100644
--- a/src/api/studio3d/q3dsviewersettings.h
+++ b/src/api/studio3d/q3dsviewersettings.h
@@ -53,6 +53,7 @@ class Q_STUDIO3D_EXPORT Q3DSViewerSettings : public QObject
Q_PROPERTY(StereoMode stereoMode READ stereoMode WRITE setStereoMode NOTIFY stereoModeChanged REVISION 1)
Q_PROPERTY(double stereoEyeSeparation READ stereoEyeSeparation WRITE setStereoEyeSeparation NOTIFY stereoEyeSeparationChanged REVISION 1)
Q_PROPERTY(bool stereoProgressiveEnabled READ stereoProgressiveEnabled WRITE setStereoProgressiveEnabled NOTIFY stereoProgressiveEnabledChanged REVISION 2)
+ Q_PROPERTY(int skipFramesInterval READ skipFramesInterval WRITE setSkipFramesInterval NOTIFY skipFramesIntervalChanged REVISION 2)
public:
enum ShadeMode {
@@ -84,6 +85,7 @@ public:
StereoMode stereoMode() const;
double stereoEyeSeparation() const;
Q_REVISION(2) bool stereoProgressiveEnabled() const;
+ Q_REVISION(2) int skipFramesInterval() const;
Q_INVOKABLE void save(const QString &group, const QString &organization = QString(),
const QString &application = QString());
@@ -98,6 +100,7 @@ public Q_SLOTS:
void setStereoMode(StereoMode mode);
void setStereoEyeSeparation(double separation);
Q_REVISION(2) void setStereoProgressiveEnabled(bool enabled);
+ Q_REVISION(2) void setSkipFramesInterval(int interval);
Q_SIGNALS:
void matteEnabledChanged(bool enabled);
@@ -108,6 +111,7 @@ Q_SIGNALS:
void stereoModeChanged(StereoMode mode);
void stereoEyeSeparationChanged(double separation);
Q_REVISION(2) void stereoProgressiveEnabledChanged(bool enabled);
+ Q_REVISION(2) void skipFramesIntervalChanged(int interval);
private:
Q_DISABLE_COPY(Q3DSViewerSettings)
diff --git a/src/api/studio3d/q3dsviewersettings_p.h b/src/api/studio3d/q3dsviewersettings_p.h
index 44e1227..6a2dc75 100644
--- a/src/api/studio3d/q3dsviewersettings_p.h
+++ b/src/api/studio3d/q3dsviewersettings_p.h
@@ -70,6 +70,7 @@ public:
void setStereoMode(Q3DSViewerSettings::StereoMode mode);
void setStereoEyeSeparation(double separation);
void setStereoProgressiveEnabled(bool enabled);
+ void setSkipFramesInterval(int interval);
public:
Q3DSViewerSettings *q_ptr;
@@ -88,6 +89,7 @@ private:
Q3DSViewerSettings::StereoMode m_stereoMode;
double m_stereoEyeSeparation;
bool m_stereoProgressiveEnabled;
+ int m_skipFramesInterval;
QSettings *m_savedSettings;
};
diff --git a/src/api/studio3dqml/q3dsrenderer.cpp b/src/api/studio3dqml/q3dsrenderer.cpp
index f7bd25b..8f0081e 100644
--- a/src/api/studio3dqml/q3dsrenderer.cpp
+++ b/src/api/studio3dqml/q3dsrenderer.cpp
@@ -353,6 +353,8 @@ void Q3DSRenderer::processCommands()
m_settings->setStereoEyeSeparation(m_commands.m_stereoEyeSeparation);
if (m_commands.m_stereoProgressiveEnabledChanged)
m_settings->setStereoProgressiveEnabled(m_commands.m_stereoProgressiveEnabled);
+ if (m_commands.m_skipFramesIntervalChanged)
+ m_settings->setSkipFramesInterval(m_commands.m_skipFramesInterval);
if (m_commands.m_shadeModeChanged)
m_settings->setShadeMode(m_commands.m_shadeMode);
if (m_commands.m_matteColorChanged)
diff --git a/src/engine/Qt3DSRenderRuntimeBinding.cpp b/src/engine/Qt3DSRenderRuntimeBinding.cpp
index 7535af6..e099e47 100644
--- a/src/engine/Qt3DSRenderRuntimeBinding.cpp
+++ b/src/engine/Qt3DSRenderRuntimeBinding.cpp
@@ -254,6 +254,24 @@ struct Qt3DSRenderScene : public Q3DStudio::IScene
Q3DStudio::UVariant value;
if (theElement.GetAttribute(ATTRIBUTE_SUBPRESENTATION, value))
subs.push_back(m_Context->GetStringTable().HandleToStr(value.m_StringHandle));
+ } else if (theTranslator && theTranslator->GetUIPType()
+ == GraphObjectTypes::CustomMaterial) {
+ // Add custom material strings to the subpresentation list since any string
+ // property could be a texture with a subpresentation source.
+ // Non-subpresentation strings are filtered out by the function caller.
+ int numProperties = theElement.GetNumProperties();
+ for (int i = 0; i < numProperties; ++i) {
+ auto property = theElement.GetPropertyByIndex(i);
+ if (property.hasValue()) {
+ auto value = property.getValue();
+ if (value.first.type() == ATTRIBUTETYPE_STRING) {
+ auto stringValue = m_Context->GetStringTable().HandleToStr(
+ value.second->m_StringHandle);
+ if (stringValue.IsValid())
+ subs.push_back(stringValue);
+ }
+ }
+ }
}
}
}
@@ -275,10 +293,7 @@ struct Qt3DSRenderScene : public Q3DStudio::IScene
TransferDirtyProperties();
m_LastRenderViewport = m_Context->GetRenderList().GetViewport();
if (m_Presentation && m_Presentation->m_Scene) {
- NVRenderRect theViewportSize(m_LastRenderViewport);
- return m_Presentation->m_Scene->PrepareForRender(
- QT3DSVec2(QT3DSF32(theViewportSize.m_Width), QT3DSF32(theViewportSize.m_Height)),
- *m_Context);
+ return m_Presentation->m_Scene->PrepareForRender(*m_Context);
}
return false;
}
diff --git a/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp b/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp
index 9fda560..e0176c7 100644
--- a/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp
+++ b/src/engine/Qt3DSRenderRuntimeBindingImplRenderer.cpp
@@ -172,6 +172,12 @@ struct SRenderer : public Q3DStudio::ITegraApplicationRenderEngine
return false;
}
+ void SetSkipFramesInterval(int interval) override
+ {
+ if (m_BindingCore && m_BindingCore->m_Context)
+ m_BindingCore->m_Context->SetSkipFramesInterval(interval);
+ }
+
void SetShadeMode(Q3DStudio::TegraRenderShadeModes::Enum inShade) override
{
if (m_BindingCore && m_BindingCore->m_Context) {
@@ -204,10 +210,6 @@ struct SRenderer : public Q3DStudio::ITegraApplicationRenderEngine
m_Viewport = NVRenderRect(inX, inY, inWidth, inHeight);
m_BindingCore->m_RenderContext->SetViewport(m_Viewport);
}
- void SetApplicationViewport(const qt3ds::render::NVRenderRect &inViewport) override
- {
- m_BindingCore->m_Context->SetViewport(inViewport);
- }
void SetMatteColor(Option<QT3DSVec4> inColor) override { m_Context->SetMatteColor(inColor); }
void setMatteEnabled(bool enabled) override { m_Context->setMatteEnabled(enabled); };
diff --git a/src/engine/Qt3DSRuntimeView.h b/src/engine/Qt3DSRuntimeView.h
index 8690b99..72d8908 100644
--- a/src/engine/Qt3DSRuntimeView.h
+++ b/src/engine/Qt3DSRuntimeView.h
@@ -132,7 +132,6 @@ protected:
public:
virtual void SetViewport(INT32 inX, INT32 inY, INT32 inWidth, INT32 inHeight) = 0;
- virtual void SetApplicationViewport(const qt3ds::render::NVRenderRect &inViewport) = 0;
virtual void ensureRenderTarget() = 0;
virtual void CheckResize(bool inForce, IPresentation &inActivePresentation) = 0;
virtual QByteArray exportShaderCache(bool binaryShaders) = 0;
@@ -149,6 +148,7 @@ public:
virtual double GetStereoEyeSeparation() const = 0;
virtual void SetStereoProgressiveEnabled(bool enabled) = 0;
virtual bool GetStereoProgressiveEnabled() const = 0;
+ virtual void SetSkipFramesInterval(int interval) = 0;
// TODO: To be removed, not used anywhere anymore
void CycleScaleMode()
diff --git a/src/foundation/Qt3DSAllocator.h b/src/foundation/Qt3DSAllocator.h
index cdbbe5f..2c90593 100644
--- a/src/foundation/Qt3DSAllocator.h
+++ b/src/foundation/Qt3DSAllocator.h
@@ -36,7 +36,11 @@
#include "foundation/Qt3DSAssert.h"
#if (defined(QT3DS_WINDOWS) | defined(QT3DS_X360))
+#if _MSC_VER < 1920 // 1920+ = MSVC2019
#include <typeinfo.h>
+#else
+#include <typeinfo>
+#endif
#endif
#if (defined(QT3DS_APPLE))
#include <typeinfo>
diff --git a/src/runtime/Qt3DSActivationManager.cpp b/src/runtime/Qt3DSActivationManager.cpp
index e975c7d..ee17f1e 100644
--- a/src/runtime/Qt3DSActivationManager.cpp
+++ b/src/runtime/Qt3DSActivationManager.cpp
@@ -555,17 +555,24 @@ struct STimeContext
inScanBuffer.push_back(SScanBufferEntry(&inNode, parentActive));
}
-
+ bool parentDiActiveChange = false;
for (QT3DSU32 idx = 0, end = inScanBuffer.size(); idx < end; ++idx) {
SScanBufferEntry theEntry(inScanBuffer[idx]);
SElement *theScanNode = theEntry.m_Node;
QT3DS_ASSERT(theScanNode->IsIndependent() == false);
bool parentActive = theEntry.IsParentActive();
bool wasActive = theScanNode->IsGlobalActive();
-
bool isControlledByDi
= controlledList.contains(*theScanNode) && theScanNode->m_OnMaster;
-
+ if (!isControlledByDi && parentDiActiveChange && parentActive && !wasActive
+ && !theScanNode->IsTimeActive() && theScanNode->IsExplicitActive()) {
+ // Set time active for datainput activated child nodes
+ theScanNode->m_ActivationManagerNode.m_Flags.SetTimeActive(true);
+ }
+ bool diActiveChange = isControlledByDi
+ && (theScanNode->IsGlobalActive(parentActive)
+ != theScanNode->IsControlledActive());
+ parentDiActiveChange |= diActiveChange;
// Override visibility for master slide elements that have datainput eyeball controller.
bool isActive = isControlledByDi ? theScanNode->IsControlledActive()
: theScanNode->IsGlobalActive(parentActive);
@@ -576,9 +583,7 @@ struct STimeContext
if (activateChange) {
HandleActivationChange(*theScanNode, activateBuffer, deactivateBuffer, scriptBuffer,
inElementAccessMutex, scriptBufferRequiresSort, isActive);
- } else if (isControlledByDi
- && (theScanNode->IsGlobalActive(parentActive)
- != theScanNode->IsControlledActive())) {
+ } else if (diActiveChange) {
// Notify only if datainput control actually disagreed with activity value
// coming from activity manager.
qCInfo(TRACE_INFO) << "Element" << theScanNode->name().c_str()
@@ -644,7 +649,7 @@ struct STimeContext
TElementNodePtrList &inTempDirtyList, TElementAndSortKeyList &activateBuffer,
TElementAndSortKeyList &deactivateBuffer, TElementAndSortKeyList &scriptBuffer,
bool &scriptBufferRequiresSort, Q3DStudio::CComponentManager &inComponentManager,
- IPerfTimer &inPerfTimer, IActivityZone &inZone)
+ IPerfTimer &, IActivityZone &inZone)
{
SComponent &theContextNode = m_Component;
bool parentActive = true;
diff --git a/src/runtime/Qt3DSApplication.cpp b/src/runtime/Qt3DSApplication.cpp
index f7f8b46..7b4d625 100644
--- a/src/runtime/Qt3DSApplication.cpp
+++ b/src/runtime/Qt3DSApplication.cpp
@@ -658,7 +658,7 @@ struct SApp : public IApplication
DataOutputMap m_dataOutputDefs;
bool m_initialFrame = true;
-
+ int m_skipFrameCount = 0;
SSlideResourceCounter m_resourceCounter;
QSet<QString> m_createSet;
@@ -1119,6 +1119,23 @@ struct SApp : public IApplication
void ResetDirtyCounter() { m_DirtyCountdown = 5; }
+ // Returns true when skipping the frame, false when rendering it
+ bool checkSkipFrame()
+ {
+ auto &rc = m_RuntimeFactory->GetQt3DSRenderContext();
+ int skipFrames = rc.GetSkipFramesInterval();
+ if (skipFrames == 0)
+ return false;
+
+ if (m_skipFrameCount <= 0) {
+ m_skipFrameCount = skipFrames;
+ return false;
+ }
+
+ m_skipFrameCount--;
+ return true;
+ }
+
// Update all the presentations and render them.
bool UpdateAndRender() override
{
@@ -1165,7 +1182,12 @@ struct SApp : public IApplication
bool renderNextFrame = false;
if (m_LastRenderWasDirty || dirty || m_initialFrame)
renderNextFrame = true;
- Render();
+
+ bool skip = checkSkipFrame();
+ // If we skip rendering this frame, mark next frame to be rendered
+ renderNextFrame |= skip;
+ if (!skip)
+ Render();
m_InputEnginePtr->ClearInputFrame();
@@ -2255,6 +2277,10 @@ bool AssetHandlers::handlePresentation(SApp &app, SAssetValue &asset, bool initI
thePathStr.c_str());
return false;
}
+
+ app.GetRuntimeFactory().GetScriptEngineQml()
+ .initializePresentationDataInputsAndOutputs(*thePresentationAsset.m_Presentation);
+
return true;
}
diff --git a/src/runtime/Qt3DSIScriptBridge.h b/src/runtime/Qt3DSIScriptBridge.h
index 9eedfc5..cb13fb2 100644
--- a/src/runtime/Qt3DSIScriptBridge.h
+++ b/src/runtime/Qt3DSIScriptBridge.h
@@ -202,6 +202,7 @@ public: // Components
public: // Presentation
virtual void SetPresentationAttribute(const char *presId, const char *attName,
const char *attValue) = 0;
+ virtual void initializePresentationDataInputsAndOutputs(CPresentation &presentation) = 0;
public: // Multimedia
virtual bool PlaySoundFile(const char *soundPath) = 0;
diff --git a/src/runtime/Qt3DSQmlEngine.cpp b/src/runtime/Qt3DSQmlEngine.cpp
index d063e5e..994f6c1 100644
--- a/src/runtime/Qt3DSQmlEngine.cpp
+++ b/src/runtime/Qt3DSQmlEngine.cpp
@@ -460,6 +460,7 @@ public:
void GotoSlideRelative(const char *, bool, bool, const SScriptEngineGotoSlideArgs &) override;
void SetPresentationAttribute(const char *, const char *, const char *) override;
+ void initializePresentationDataInputsAndOutputs(CPresentation &presentation);
// No need to implement here, as sound playing is done in Qt3DSViewerApp
bool PlaySoundFile(const char *) override { return false; }
@@ -1917,6 +1918,12 @@ void CQmlEngineImpl::SetPresentationAttribute(const char *presId, const char *,
}
}
+void CQmlEngineImpl::initializePresentationDataInputsAndOutputs(CPresentation &presentation)
+{
+ initializeDataInputsInPresentation(presentation, false);
+ initializeDataOutputsInPresentation(presentation, false);
+}
+
void CQmlEngineImpl::GotoSlideIndex(const char *component, const Q3DStudio::INT32 slideIndex,
const SScriptEngineGotoSlideArgs &inArgs)
{
@@ -2135,6 +2142,9 @@ void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentat
bool isPrimary, bool isDynamicAdd,
QList<TElement *> inElements)
{
+ if (!m_Application)
+ return;
+
QList<TElement *> elements;
if (!inElements.empty()) {
elements = inElements;
@@ -2310,6 +2320,9 @@ void CQmlEngineImpl::initializeDataInputsInPresentation(CPresentation &presentat
void CQmlEngineImpl::initializeDataOutputsInPresentation(CPresentation &presentation,
bool isPrimary)
{
+ if (!m_Application)
+ return;
+
TElement *parent = presentation.GetRoot();
QList<TElement *> elements;
listAllElements(parent, elements);
diff --git a/src/runtimerender/Qt3DSRenderContextCore.cpp b/src/runtimerender/Qt3DSRenderContextCore.cpp
index dde70fd..44f10c0 100644
--- a/src/runtimerender/Qt3DSRenderContextCore.cpp
+++ b/src/runtimerender/Qt3DSRenderContextCore.cpp
@@ -241,14 +241,14 @@ struct SRenderContext : public IQt3DSRenderContext
NVScopedRefCounted<IRenderList> m_RenderList;
QT3DSU32 m_FrameCount;
volatile QT3DSI32 mRefCount;
- // Viewport that this render context should use
- Option<NVRenderRect> m_Viewport;
+
QSize m_WindowDimensions;
ScaleModes::Enum m_ScaleMode;
StereoModes::Enum m_StereoMode;
StereoViews::Enum m_StereoView;
double m_StereoEyeSeparation;
bool m_StereoProgressiveEnabled;
+ int m_SkipFramesInterval;
bool m_WireframeMode;
bool m_subPresentationRenderInLayer;
Option<QT3DSVec4> m_SceneColor;
@@ -291,6 +291,7 @@ struct SRenderContext : public IQt3DSRenderContext
, m_StereoView(StereoViews::Mono)
, m_StereoEyeSeparation(0.4)
, m_StereoProgressiveEnabled(false)
+ , m_SkipFramesInterval(0)
, m_WireframeMode(false)
, m_subPresentationRenderInLayer(false)
, m_matteEnabled(false)
@@ -486,13 +487,19 @@ struct SRenderContext : public IQt3DSRenderContext
|| m_StereoMode == StereoModes::TopBottom);
}
+ void SetSkipFramesInterval(int interval) override
+ {
+ m_SkipFramesInterval = interval;
+ }
+
+ int GetSkipFramesInterval() const override {
+ return m_SkipFramesInterval;
+ }
+
void SetWireframeMode(bool inEnable) override { m_WireframeMode = inEnable; }
bool GetWireframeMode() override { return m_WireframeMode; }
- void SetViewport(Option<NVRenderRect> inViewport) override { m_Viewport = inViewport; }
- Option<NVRenderRect> GetViewport() const override { return m_Viewport; }
-
IRenderWidgetContext &GetRenderWidgetContext() override
{
return m_Renderer->GetRenderWidgetContext();
@@ -545,11 +552,7 @@ struct SRenderContext : public IQt3DSRenderContext
NVRenderRect GetContextViewport() const override
{
NVRenderRect retval;
- if (m_Viewport.hasValue())
- retval = *m_Viewport;
- else
- retval = NVRenderRect(0, 0, m_WindowDimensions.width(), m_WindowDimensions.height());
-
+ retval = NVRenderRect(0, 0, m_WindowDimensions.width(), m_WindowDimensions.height());
return retval;
}
@@ -686,12 +689,8 @@ struct SRenderContext : public IQt3DSRenderContext
m_PerFrameAllocator.reset();
IRenderList &theRenderList(*m_RenderList);
theRenderList.BeginFrame();
- if (m_Viewport.hasValue()) {
- theRenderList.SetScissorTestEnabled(true);
- theRenderList.SetScissorRect(theContextViewport);
- } else {
- theRenderList.SetScissorTestEnabled(false);
- }
+ theRenderList.SetScissorRect(theContextViewport);
+ theRenderList.SetScissorTestEnabled(false);
bool renderOffscreen = m_Rotation != RenderRotationValues::NoRotation;
eastl::pair<NVRenderRect, NVRenderRect> thePresViewportAndOuterViewport =
GetPresentationViewportAndOuterViewport();
@@ -771,11 +770,10 @@ struct SRenderContext : public IQt3DSRenderContext
{
bool stereoProgressiveEnabled = GetStereoProgressiveEnabled();
// Clearing for matte / scene background
- if (m_Viewport.hasValue() || stereoProgressiveEnabled) {
+ if (stereoProgressiveEnabled) {
// With progressive stereoscopic rendering needs to be adjusted to viewport
NVRenderRect theContextViewport(GetContextViewport());
- if (stereoProgressiveEnabled)
- adjustRectToStereoMode(theContextViewport);
+ adjustRectToStereoMode(theContextViewport);
m_RenderContext->SetScissorTestEnabled(true);
m_RenderContext->SetScissorRect(theContextViewport);
} else {
diff --git a/src/runtimerender/Qt3DSRenderContextCore.h b/src/runtimerender/Qt3DSRenderContextCore.h
index 8382fc6..c239d78 100644
--- a/src/runtimerender/Qt3DSRenderContextCore.h
+++ b/src/runtimerender/Qt3DSRenderContextCore.h
@@ -184,11 +184,6 @@ namespace render {
virtual void SetWindowDimensions(const QSize &inWindowDimensions) = 0;
virtual QSize GetWindowDimensions() = 0;
- // In addition to the window dimensions which really have to be set, you can optionally
- // set the viewport which will force the entire viewer to render specifically to this
- // viewport.
- virtual void SetViewport(Option<NVRenderRect> inViewport) = 0;
- virtual Option<NVRenderRect> GetViewport() const = 0;
virtual NVRenderRect GetContextViewport() const = 0;
// Only valid between calls to Begin,End.
virtual NVRenderRect GetPresentationViewport() const = 0;
@@ -205,6 +200,8 @@ namespace render {
virtual double GetStereoEyeSeparation() const = 0;
virtual void SetStereoProgressiveEnabled(bool enabled) = 0;
virtual bool GetStereoProgressiveEnabled() const = 0;
+ virtual void SetSkipFramesInterval(int interval) = 0;
+ virtual int GetSkipFramesInterval() const = 0;
virtual void SetWireframeMode(bool inEnable) = 0;
virtual bool GetWireframeMode() = 0;
diff --git a/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp b/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp
index cb94534..03c1a01 100644
--- a/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp
+++ b/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp
@@ -1310,8 +1310,8 @@ struct SMaterialSystem : public ICustomMaterialSystem
SImage *image = (*inMaterial.m_imageMaps)[inPropertyName];
if (image) {
if (image->m_ImagePath != *theStrPtr) {
- image->m_ImagePath = *theStrPtr;
- image->m_Flags.SetDirty(true);
+ // Should not happen
+ QT3DS_ASSERT(false);
} else {
IOffscreenRenderManager &offscreenRenderer(
m_Context->GetOffscreenRenderManager());
@@ -2008,10 +2008,11 @@ struct SMaterialSystem : public ICustomMaterialSystem
{
NVConstDataRef<SPropertyDefinition> thePropDefs = inClass.m_Class->GetProperties();
for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) {
- if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) {
+ const SPropertyDefinition &def = thePropDefs[idx];
+ if (def.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) {
SImage *pImage = nullptr;
CRegisteredString theStrPtr = *reinterpret_cast<CRegisteredString *>(
- inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset);
+ inMaterial.GetDataSectionBegin() + def.m_Offset);
if (theStrPtr.IsValid()) {
QT3DSU32 index = FindAllocatedImage(theStrPtr);
@@ -2022,46 +2023,51 @@ struct SMaterialSystem : public ICustomMaterialSystem
pImage = m_AllocatedImages[index].second;
}
- switch (thePropDefs[idx].m_TexUsageType) {
+ switch (def.m_TexUsageType) {
case NVRenderTextureTypeValue::Displace:
if (inMaterial.m_DisplacementMap != pImage) {
inMaterial.m_DisplacementMap = pImage;
- inMaterial.m_DisplacementMap->m_ImagePath =
- thePropDefs[idx].m_ImagePath;
+ inMaterial.m_DisplacementMap->m_ImagePath = theStrPtr;
inMaterial.m_DisplacementMap->m_ImageShaderName =
- thePropDefs[idx].m_Name; // this is our name in the shader
+ def.m_Name; // this is our name in the shader
inMaterial.m_DisplacementMap->m_VerticalTilingMode =
- thePropDefs[idx].m_CoordOp;
+ def.m_CoordOp;
inMaterial.m_DisplacementMap->m_HorizontalTilingMode =
- thePropDefs[idx].m_CoordOp;
+ def.m_CoordOp;
+ pImage->m_Flags.SetDirty(true);
+ pImage->m_Flags.SetForceLoad(true);
}
break;
case NVRenderTextureTypeValue::Emissive2:
if (inMaterial.m_EmissiveMap2 != pImage) {
inMaterial.m_EmissiveMap2 = pImage;
- inMaterial.m_EmissiveMap2->m_ImagePath = thePropDefs[idx].m_ImagePath;
+ inMaterial.m_EmissiveMap2->m_ImagePath = theStrPtr;
inMaterial.m_EmissiveMap2->m_ImageShaderName =
- thePropDefs[idx].m_Name; // this is our name in the shader
+ def.m_Name; // this is our name in the shader
inMaterial.m_EmissiveMap2->m_VerticalTilingMode =
- thePropDefs[idx].m_CoordOp;
+ def.m_CoordOp;
inMaterial.m_EmissiveMap2->m_HorizontalTilingMode =
- thePropDefs[idx].m_CoordOp;
+ def.m_CoordOp;
+ pImage->m_Flags.SetDirty(true);
+ pImage->m_Flags.SetForceLoad(true);
}
break;
default:
if (!inMaterial.m_imageMaps)
inMaterial.m_imageMaps = newImageMap(m_CoreContext.GetAllocator());
- if ((*inMaterial.m_imageMaps)[thePropDefs[idx].m_Name] != pImage) {
- (*inMaterial.m_imageMaps)[thePropDefs[idx].m_Name] = pImage;
- pImage->m_ImagePath = thePropDefs[idx].m_ImagePath;
- pImage->m_ImageShaderName = thePropDefs[idx].m_Name;
- pImage->m_VerticalTilingMode = thePropDefs[idx].m_CoordOp;
- pImage->m_HorizontalTilingMode = thePropDefs[idx].m_CoordOp;
+ if ((*inMaterial.m_imageMaps)[def.m_Name] != pImage) {
+ (*inMaterial.m_imageMaps)[def.m_Name] = pImage;
+ pImage->m_ImagePath = theStrPtr;
+ pImage->m_ImageShaderName = def.m_Name;
+ pImage->m_VerticalTilingMode = def.m_CoordOp;
+ pImage->m_HorizontalTilingMode = def.m_CoordOp;
+ pImage->m_Flags.SetDirty(true);
+ pImage->m_Flags.SetForceLoad(true);
}
break;
}
} else {
- switch (thePropDefs[idx].m_TexUsageType) {
+ switch (def.m_TexUsageType) {
case NVRenderTextureTypeValue::Displace:
inMaterial.m_DisplacementMap = nullptr;
break;
@@ -2071,7 +2077,7 @@ struct SMaterialSystem : public ICustomMaterialSystem
default:
if (!inMaterial.m_imageMaps)
inMaterial.m_imageMaps = newImageMap(m_CoreContext.GetAllocator());
- (*inMaterial.m_imageMaps)[thePropDefs[idx].m_Name] = nullptr;
+ (*inMaterial.m_imageMaps)[def.m_Name] = nullptr;
break;
}
}
diff --git a/src/runtimerender/Qt3DSRenderEffectSystem.cpp b/src/runtimerender/Qt3DSRenderEffectSystem.cpp
index faaf4d2..b15d0bc 100644
--- a/src/runtimerender/Qt3DSRenderEffectSystem.cpp
+++ b/src/runtimerender/Qt3DSRenderEffectSystem.cpp
@@ -1079,8 +1079,8 @@ struct SEffectSystem : public IEffectSystem
SImage *image = (*inEffect.m_imageMaps)[inPropertyName];
if (image) {
if (image->m_ImagePath != *theStrPtr) {
- image->m_ImagePath = *theStrPtr;
- image->m_Flags.SetDirty(true);
+ // Should not happen
+ QT3DS_ASSERT(false);
} else {
IOffscreenRenderManager &theOffscreenRenderer(
m_Context->GetOffscreenRenderManager());
@@ -1928,10 +1928,12 @@ struct SEffectSystem : public IEffectSystem
if ((*inEffect.m_imageMaps)[theDefs[idx].m_Name] != pImage) {
(*inEffect.m_imageMaps)[theDefs[idx].m_Name] = pImage;
- pImage->m_ImagePath = theDefs[idx].m_ImagePath;
+ pImage->m_ImagePath = *theStrPtr;
pImage->m_ImageShaderName = theDefs[idx].m_Name;
pImage->m_VerticalTilingMode = theDefs[idx].m_CoordOp;
pImage->m_HorizontalTilingMode = theDefs[idx].m_CoordOp;
+ pImage->m_Flags.SetDirty(true);
+ pImage->m_Flags.SetForceLoad(true);
}
}
} else {
diff --git a/src/runtimerender/Qt3DSRenderSubpresentation.cpp b/src/runtimerender/Qt3DSRenderSubpresentation.cpp
index 64f08be..8b13361 100644
--- a/src/runtimerender/Qt3DSRenderSubpresentation.cpp
+++ b/src/runtimerender/Qt3DSRenderSubpresentation.cpp
@@ -68,10 +68,7 @@ namespace render {
QT3DSVec2 /*inPresScale*/,
const SRenderInstanceId instanceId)
{
- NVRenderRect theViewportSize(m_RenderContext.GetRenderList().GetViewport());
- bool wasDirty = m_Presentation.m_Scene->PrepareForRender(
- QT3DSVec2((QT3DSF32)theViewportSize.m_Width, (QT3DSF32)theViewportSize.m_Height),
- m_RenderContext, instanceId);
+ bool wasDirty = m_Presentation.m_Scene->PrepareForRender(m_RenderContext, instanceId);
// Always transparent
return SOffscreenRenderFlags(true, wasDirty);
}
diff --git a/src/runtimerender/Qt3DSRenderer.h b/src/runtimerender/Qt3DSRenderer.h
index 336baab..50c27c3 100644
--- a/src/runtimerender/Qt3DSRenderer.h
+++ b/src/runtimerender/Qt3DSRenderer.h
@@ -132,7 +132,7 @@ namespace render {
virtual void RenderPointsIndirect() = 0;
// Returns true if this layer or a sibling was dirty.
- virtual bool PrepareLayerForRender(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions,
+ virtual bool PrepareLayerForRender(SLayer &inLayer,
bool inRenderSiblings = true,
const SRenderInstanceId id = nullptr) = 0;
virtual void RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions, bool clear,
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp b/src/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp
index 1dd352c..8e927fe 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp
+++ b/src/runtimerender/graphobjects/Qt3DSRenderDynamicObject.cpp
@@ -125,7 +125,25 @@ void SDynamicObject::SetStrPropertyValueT(dynamic::SPropertyDefinition &inDefini
if (inProjectDir == NULL)
inProjectDir = "";
if (CFileTools::RequiresCombineBaseAndRelative(inValue)) {
- QString path = QDir(inProjectDir).cleanPath(inValue);
+ QString value(QDir::cleanPath(inValue));
+ QString projectDir(inProjectDir);
+ QString path = value;
+
+ bool tryResolveRelativePath = !projectDir.startsWith(QStringLiteral(":/"));
+ if (tryResolveRelativePath)
+ path.prepend(projectDir + QChar('/'));
+
+ if (tryResolveRelativePath) {
+ bool exists = QFileInfo(path).exists();
+ if (!exists && value.startsWith("../")) {
+ QString tryPath = projectDir + QChar('/') + value.right(value.size() - 3);
+ exists = QFileInfo(tryPath).exists();
+ if (exists)
+ path = tryPath;
+ else
+ path = value; // reset back to initial value if resolve failed
+ }
+ }
ioWorkspace.assign(path.toLatin1().constData());
SetPropertyValueT(inDefinition, inStrTable.RegisterStr(ioWorkspace.c_str()));
// We also adjust the image path in the definition
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp b/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp
index 69cc35b..44e7f12 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp
+++ b/src/runtimerender/graphobjects/Qt3DSRenderImage.cpp
@@ -95,7 +95,8 @@ bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager
if (newImage.m_Texture == nullptr) {
m_LastFrameOffscreenRenderer = nullptr;
- if (m_ImagePath.IsValid() && !m_OffscreenRendererId.IsValid()) {
+ if (m_ImagePath.IsValid() && !m_OffscreenRendererId.IsValid()
+ && !inRenderManager.HasOffscreenRenderer(m_ImagePath)) {
// Image has sourcepath set
if (!m_LoadedTextureData
|| m_LoadedTextureData->m_path != QString::fromUtf8(m_ImagePath.c_str())) {
@@ -111,6 +112,13 @@ bool SImage::ClearDirty(IBufferManager &inBufferManager, IOffscreenRenderManager
newImage.m_Texture = m_LoadedTextureData->m_Texture;
newImage.m_TextureFlags = m_LoadedTextureData->m_TextureFlags;
newImage.m_BSDFMipMap = m_LoadedTextureData->m_BSDFMipMap;
+ } else if (m_Flags.IsForceLoad()) {
+ QSet<QString> ls;
+ ls.insert(QString(m_ImagePath));
+ inBufferManager.loadSet(ls);
+ newImage.m_Texture = m_LoadedTextureData->m_Texture;
+ newImage.m_TextureFlags = m_LoadedTextureData->m_TextureFlags;
+ newImage.m_BSDFMipMap = m_LoadedTextureData->m_BSDFMipMap;
}
replaceTexture = m_TextureData.m_Texture != newImage.m_Texture;
}
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderNode.h b/src/runtimerender/graphobjects/Qt3DSRenderNode.h
index ea0d481..7f5af1e 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderNode.h
+++ b/src/runtimerender/graphobjects/Qt3DSRenderNode.h
@@ -81,6 +81,7 @@ namespace render {
///mechanism. This can be usefulf or caching purposes.
IgnoreParentTransform = 1 << 13,
LayerEnableDepthPrePass = 1 << 14, ///< True when we render a depth pass before
+ ForceLoad = 1 << 15,
};
};
@@ -178,6 +179,14 @@ namespace render {
{
ClearOrSet(value, NodeFlagValues::LayerEnableDepthPrePass);
}
+ void SetForceLoad(bool value)
+ {
+ ClearOrSet(value, NodeFlagValues::ForceLoad);
+ }
+ bool IsForceLoad()
+ {
+ return this->operator&(NodeFlagValues::ForceLoad);
+ }
};
struct QT3DS_AUTOTEST_EXPORT SNode : public SGraphObject
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderScene.cpp b/src/runtimerender/graphobjects/Qt3DSRenderScene.cpp
index 2dadc26..afe68d5 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderScene.cpp
+++ b/src/runtimerender/graphobjects/Qt3DSRenderScene.cpp
@@ -65,7 +65,7 @@ SLayer *SScene::GetLastChild()
return child;
}
-bool SScene::PrepareForRender(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext,
+bool SScene::PrepareForRender(IQt3DSRenderContext &inContext,
const SRenderInstanceId id)
{
// We need to iterate through the layers in reverse order and ask them to render.
@@ -74,7 +74,7 @@ bool SScene::PrepareForRender(const QT3DSVec2 &inViewportDimensions, IQt3DSRende
if (m_FirstChild) {
wasDirty |=
- inContext.GetRenderer().PrepareLayerForRender(*m_FirstChild, inViewportDimensions,
+ inContext.GetRenderer().PrepareLayerForRender(*m_FirstChild,
true, id);
}
return wasDirty;
diff --git a/src/runtimerender/graphobjects/Qt3DSRenderScene.h b/src/runtimerender/graphobjects/Qt3DSRenderScene.h
index 8c4d3fe..00a4591 100644
--- a/src/runtimerender/graphobjects/Qt3DSRenderScene.h
+++ b/src/runtimerender/graphobjects/Qt3DSRenderScene.h
@@ -69,7 +69,7 @@ namespace render {
inRemapper.Remap(m_FirstChild);
}
// returns true if any of the layers were dirty or if this object was dirty
- bool PrepareForRender(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext,
+ bool PrepareForRender(IQt3DSRenderContext &inContext,
const SRenderInstanceId id = nullptr);
void Render(const QT3DSVec2 &inViewportDimensions, IQt3DSRenderContext &inContext,
RenderClearCommand command = ClearIsOptional,
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp
index 300980c..a8b6a4f 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.cpp
@@ -233,11 +233,9 @@ namespace render {
}
bool Qt3DSRendererImpl::PrepareLayerForRender(SLayer &inLayer,
- const QT3DSVec2 &inViewportDimensions,
bool inRenderSiblings,
const SRenderInstanceId id)
{
- (void)inViewportDimensions;
nvvector<SLayer *> renderableLayers(m_qt3dsContext.GetPerFrameAllocator(), "LayerVector");
// Found by fair roll of the dice.
renderableLayers.reserve(4);
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h
index 99b0b51..decd7fd 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImpl.h
@@ -342,8 +342,8 @@ namespace render {
// Calls prepare layer for render
// and then do render layer.
- bool PrepareLayerForRender(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions,
- bool inRenderSiblings, const SRenderInstanceId id) override;
+ bool PrepareLayerForRender(SLayer &inLayer, bool inRenderSiblings,
+ const SRenderInstanceId id) override;
void RenderLayer(SLayer &inLayer, const QT3DSVec2 &inViewportDimensions,
bool clear, QT3DSVec4 clearColor, bool inRenderSiblings,
const SRenderInstanceId id) override;
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
index 7a7a64c..1a76813 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp
@@ -312,6 +312,36 @@ namespace render {
}
namespace {
+ NVBounds3 calculateShadowCameraBoundingBox(const QT3DSVec3 *points,
+ const QT3DSVec3 &forward,
+ const QT3DSVec3 &up, const QT3DSVec3 &right)
+ {
+ float minDistanceZ = std::numeric_limits<float>::max();
+ float maxDistanceZ = -std::numeric_limits<float>::max();
+ float minDistanceY = std::numeric_limits<float>::max();
+ float maxDistanceY = -std::numeric_limits<float>::max();
+ float minDistanceX = std::numeric_limits<float>::max();
+ float maxDistanceX = -std::numeric_limits<float>::max();
+ for (int i = 0; i < 8; ++i) {
+ float distanceZ = points[i].dot(forward);
+ if (distanceZ < minDistanceZ)
+ minDistanceZ = distanceZ;
+ if (distanceZ > maxDistanceZ)
+ maxDistanceZ = distanceZ;
+ float distanceY = points[i].dot(up);
+ if (distanceY < minDistanceY)
+ minDistanceY = distanceY;
+ if (distanceY > maxDistanceY)
+ maxDistanceY = distanceY;
+ float distanceX = points[i].dot(right);
+ if (distanceX < minDistanceX)
+ minDistanceX = distanceX;
+ if (distanceX > maxDistanceX)
+ maxDistanceX = distanceX;
+ }
+ return NVBounds3(QT3DSVec3(minDistanceX, minDistanceY, minDistanceZ),
+ QT3DSVec3(maxDistanceX, maxDistanceY, maxDistanceZ));
+ }
void computeFrustumBounds(const SCamera &inCamera, const NVRenderRectF &inViewPort,
QT3DSVec3 &ctrBound, QT3DSVec3 camVerts[8])
@@ -353,7 +383,8 @@ namespace render {
void SetupCameraForShadowMap(const QT3DSVec2 &inCameraVec, NVRenderContext & /*inContext*/,
const NVRenderRectF &inViewport, const SCamera &inCamera,
- const SLight *inLight, SCamera &theCamera)
+ const SLight *inLight, SCamera &theCamera,
+ QT3DSVec3 *scenePoints = nullptr)
{
// setup light matrix
QT3DSU32 mapRes = 1 << inLight->m_ShadowMapRes;
@@ -371,8 +402,15 @@ namespace render {
theCamera.m_FOV = inLight->m_ShadowMapFov * QT3DS_DEGREES_TO_RADIANS;
if (inLight->m_LightType == RenderLightTypes::Directional) {
- QT3DSVec3 frustBounds[8], boundCtr;
- computeFrustumBounds(inCamera, inViewport, boundCtr, frustBounds);
+ QT3DSVec3 frustumPoints[8], boundCtr, sceneCtr;
+ computeFrustumBounds(inCamera, inViewport, boundCtr, frustumPoints);
+
+ if (scenePoints) {
+ sceneCtr = QT3DSVec3(0, 0, 0);
+ for (int i = 0; i < 8; ++i)
+ sceneCtr += scenePoints[i];
+ sceneCtr *= 0.125f;
+ }
QT3DSVec3 forward = inLightDir;
forward.normalize();
@@ -382,37 +420,26 @@ namespace render {
up.normalize();
// Calculate bounding box of the scene camera frustum
- float minDistanceZ = std::numeric_limits<float>::max();
- float maxDistanceZ = -std::numeric_limits<float>::max();
- float minDistanceY = std::numeric_limits<float>::max();
- float maxDistanceY = -std::numeric_limits<float>::max();
- float minDistanceX = std::numeric_limits<float>::max();
- float maxDistanceX = -std::numeric_limits<float>::max();
- for (int i = 0; i < 8; ++i) {
- float distanceZ = frustBounds[i].dot(forward);
- if (distanceZ < minDistanceZ)
- minDistanceZ = distanceZ;
- if (distanceZ > maxDistanceZ)
- maxDistanceZ = distanceZ;
- float distanceY = frustBounds[i].dot(up);
- if (distanceY < minDistanceY)
- minDistanceY = distanceY;
- if (distanceY > maxDistanceY)
- maxDistanceY = distanceY;
- float distanceX = frustBounds[i].dot(right);
- if (distanceX < minDistanceX)
- minDistanceX = distanceX;
- if (distanceX > maxDistanceX)
- maxDistanceX = distanceX;
+ NVBounds3 bounds = calculateShadowCameraBoundingBox(frustumPoints, forward, up,
+ right);
+ inLightPos = boundCtr;
+ if (scenePoints) {
+ NVBounds3 sceneBounds = calculateShadowCameraBoundingBox(scenePoints, forward,
+ up, right);
+ if (sceneBounds.getExtents().x * sceneBounds.getExtents().y
+ * sceneBounds.getExtents().z < bounds.getExtents().x
+ * bounds.getExtents().y * bounds.getExtents().z) {
+ bounds = sceneBounds;
+ inLightPos = sceneCtr;
+ }
}
// Apply bounding box parameters to shadow map camera projection matrix
// so that the whole scene is fit inside the shadow map
- inLightPos = boundCtr;
- theViewport.m_Height = abs(maxDistanceY - minDistanceY);
- theViewport.m_Width = abs(maxDistanceX - minDistanceX);
- theCamera.m_ClipNear = -abs(maxDistanceZ - minDistanceZ);
- theCamera.m_ClipFar = abs(maxDistanceZ - minDistanceZ);
+ theViewport.m_Height = bounds.getExtents().y * 2;
+ theViewport.m_Width = bounds.getExtents().x * 2;
+ theCamera.m_ClipNear = -bounds.getExtents().z * 2;
+ theCamera.m_ClipFar = bounds.getExtents().z * 2;
}
theCamera.m_Flags.SetLeftHanded(false);
@@ -710,6 +737,18 @@ namespace render {
| qt3ds::render::NVRenderClearValues::Stencil
| qt3ds::render::NVRenderClearValues::Color);
+ auto bounds = m_Camera->m_Parent->GetBounds(m_Renderer.GetQt3DSContext().GetBufferManager(),
+ m_Renderer.GetQt3DSContext().GetPathManager());
+ QT3DSVec3 scenePoints[8];
+ scenePoints[0] = bounds.minimum;
+ scenePoints[1] = QT3DSVec3(bounds.maximum.x, bounds.minimum.y, bounds.minimum.z);
+ scenePoints[2] = QT3DSVec3(bounds.minimum.x, bounds.maximum.y, bounds.minimum.z);
+ scenePoints[3] = QT3DSVec3(bounds.maximum.x, bounds.maximum.y, bounds.minimum.z);
+ scenePoints[4] = QT3DSVec3(bounds.minimum.x, bounds.minimum.y, bounds.maximum.z);
+ scenePoints[5] = QT3DSVec3(bounds.maximum.x, bounds.minimum.y, bounds.maximum.z);
+ scenePoints[6] = QT3DSVec3(bounds.minimum.x, bounds.maximum.y, bounds.maximum.z);
+ scenePoints[7] = bounds.maximum;
+
for (QT3DSU32 i = 0; i < m_Lights.size(); i++) {
// don't render shadows when not casting
if (m_Lights[i]->m_CastShadow == false)
@@ -721,7 +760,7 @@ namespace render {
QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar);
SetupCameraForShadowMap(theCameraProps, m_Renderer.GetContext(),
__viewport.m_InitialValue, *m_Camera,
- m_Lights[i], theCamera);
+ m_Lights[i], theCamera, scenePoints);
// we need this matrix for the final rendering
theCamera.CalculateViewProjectionMatrix(pEntry->m_LightVP);
pEntry->m_LightView = theCamera.m_GlobalTransform.getInverse();
diff --git a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
index 26b0a3c..54cb55f 100644
--- a/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
+++ b/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
@@ -1414,7 +1414,7 @@ namespace render {
NVRenderRect theViewport(theGraph.GetViewport());
NVRenderRect theScissor(theGraph.GetViewport());
if (theGraph.IsScissorTestEnabled())
- theScissor = m_Renderer.GetContext().GetScissorRect();
+ theScissor = theGraph.GetScissor();
bool wasDirty = false;
bool wasDataDirty = false;
wasDirty = m_Layer.m_Flags.IsDirty();
diff --git a/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp b/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp
index aea4543..93ad2d4 100644
--- a/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp
+++ b/src/runtimerender/resourcemanager/Qt3DSRenderLoadedTextureKTX.cpp
@@ -64,6 +64,8 @@ static inline int blockSizeForTextureFormat(int format)
static inline int runtimeFormat(quint32 internalFormat)
{
switch (internalFormat) {
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ return NVRenderTextureFormats::RGBA8_ETC2_EAC;
case QOpenGLTexture::RGB8_ETC1:
return NVRenderTextureFormats::RGB8_ETC1;
case QOpenGLTexture::RGB8_ETC2:
diff --git a/src/uipparser/Qt3DSUIPParserImpl.cpp b/src/uipparser/Qt3DSUIPParserImpl.cpp
index 02bd3ad..4190915 100644
--- a/src/uipparser/Qt3DSUIPParserImpl.cpp
+++ b/src/uipparser/Qt3DSUIPParserImpl.cpp
@@ -842,16 +842,19 @@ void CUIPParserImpl::AddFloat4Attribute(TPropertyDescAndValueList &outDescList,
void CUIPParserImpl::AddStringAttribute(IPresentation &inPresentation,
TPropertyDescAndValueList &outDescList,
- CRegisteredString inAttStrName, const char *inValue)
+ CRegisteredString inAttStrName, const char *inValue,
+ bool addSourceAsString)
{
qt3ds::foundation::CStringHandle theString = inPresentation.GetStringTable().GetHandle(inValue);
UVariant theValue;
theValue.m_StringHandle = theString.handle();
outDescList.push_back(
eastl::make_pair(SPropertyDesc(inAttStrName, ATTRIBUTETYPE_STRING), theValue));
- if (CHash::HashAttribute(inAttStrName.c_str()) == Q3DStudio::ATTRIBUTE_SOURCEPATH && inValue
- && *inValue)
+ if ((addSourceAsString
+ || CHash::HashAttribute(inAttStrName.c_str()) == Q3DStudio::ATTRIBUTE_SOURCEPATH)
+ && inValue && *inValue) {
AddSourcePath(inValue, false);
+ }
}
void CUIPParserImpl::AddElementRefAttribute(TPropertyDescAndValueList &outDescList,
@@ -944,7 +947,10 @@ void CUIPParserImpl::GetAttributeList(IPresentation &inPresentation,
const char *theDataPtr = "";
if (!IsTrivial(inValue))
theReader.Read(theDataPtr);
- AddStringAttribute(inPresentation, outDescList, inPropNameStrs[0], theDataPtr);
+ bool addSourceAsString = inAdditionalType
+ == ERuntimeAdditionalMetaDataType::ERuntimeAdditionalMetaDataTypeTexture;
+ AddStringAttribute(inPresentation, outDescList, inPropNameStrs[0], theDataPtr,
+ addSourceAsString);
break;
}
case ERuntimeDataModelDataTypeLong4: {
diff --git a/src/uipparser/Qt3DSUIPParserImpl.h b/src/uipparser/Qt3DSUIPParserImpl.h
index 85f8c18..939ba35 100644
--- a/src/uipparser/Qt3DSUIPParserImpl.h
+++ b/src/uipparser/Qt3DSUIPParserImpl.h
@@ -661,7 +661,8 @@ protected:
ERuntimeAdditionalMetaDataType inAdditionalType,
CRegisteredString *inAttStrNames, qt3dsdm::SFloat4 &inValue);
void AddStringAttribute(IPresentation &inPresentation, TPropertyDescAndValueList &outDescList,
- CRegisteredString inAttStrName, const char *inValue);
+ CRegisteredString inAttStrName, const char *inValue,
+ bool addSourceAsString = false);
void AddElementRefAttribute(TPropertyDescAndValueList &outDescList,
CRegisteredString inAttStrName, SElement *inElement);
diff --git a/src/viewer/Qt3DSViewerApp.cpp b/src/viewer/Qt3DSViewerApp.cpp
index 5d8393a..7d94f3a 100644
--- a/src/viewer/Qt3DSViewerApp.cpp
+++ b/src/viewer/Qt3DSViewerApp.cpp
@@ -886,6 +886,12 @@ bool Q3DSViewerApp::GetStereoProgressiveEnabled() const
return 0;
}
+void Q3DSViewerApp::SetSkipFramesInterval(int interval)
+{
+ if (m_Impl.m_view && m_Impl.m_view->GetTegraRenderEngine())
+ m_Impl.m_view->GetTegraRenderEngine()->SetSkipFramesInterval(interval);
+}
+
void Q3DSViewerApp::setMatteColor(const QColor &color)
{
if (m_Impl.m_view && m_Impl.m_view->GetTegraRenderEngine()) {
diff --git a/src/viewer/Qt3DSViewerApp.h b/src/viewer/Qt3DSViewerApp.h
index ab723cd..8aca9e1 100644
--- a/src/viewer/Qt3DSViewerApp.h
+++ b/src/viewer/Qt3DSViewerApp.h
@@ -328,6 +328,8 @@ public:
void SetStereoProgressiveEnabled(bool enabled);
bool GetStereoProgressiveEnabled() const;
+ void SetSkipFramesInterval(int interval);
+
void setMatteColor(const QColor &color);
void setShowOnScreenStats(bool s);