From 02e4d56d055d73340d3af1257b908a52aecc320f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaj=20Gr=C3=B6nholm?= Date: Mon, 16 Mar 2020 12:22:32 +0200 Subject: Add support for progressive stereoscopic rendering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In progressive mode, single eye is rendered per frame. So full rendering of stereoscopic view takes 2 frames. This mode can be enabled from Q3DSViewerSettings, and for viewer from menu or with "--enableprogressivestereo" command-line parameter. Task-number: QT3DS-4076 Change-Id: Ie69e37da028743164b959036136485b88c61b009 Reviewed-by: Janne Kangas Reviewed-by: Tomi Korpipää --- src/runtimerender/Qt3DSRenderContextCore.cpp | 59 +++++++++++++++++++++++++--- src/runtimerender/Qt3DSRenderContextCore.h | 2 + 2 files changed, 56 insertions(+), 5 deletions(-) (limited to 'src/runtimerender') diff --git a/src/runtimerender/Qt3DSRenderContextCore.cpp b/src/runtimerender/Qt3DSRenderContextCore.cpp index 484a805..dde70fd 100644 --- a/src/runtimerender/Qt3DSRenderContextCore.cpp +++ b/src/runtimerender/Qt3DSRenderContextCore.cpp @@ -248,6 +248,7 @@ struct SRenderContext : public IQt3DSRenderContext StereoModes::Enum m_StereoMode; StereoViews::Enum m_StereoView; double m_StereoEyeSeparation; + bool m_StereoProgressiveEnabled; bool m_WireframeMode; bool m_subPresentationRenderInLayer; Option m_SceneColor; @@ -289,6 +290,7 @@ struct SRenderContext : public IQt3DSRenderContext , m_StereoMode(StereoModes::Mono) , m_StereoView(StereoViews::Mono) , m_StereoEyeSeparation(0.4) + , m_StereoProgressiveEnabled(false) , m_WireframeMode(false) , m_subPresentationRenderInLayer(false) , m_matteEnabled(false) @@ -474,6 +476,16 @@ struct SRenderContext : public IQt3DSRenderContext double GetStereoEyeSeparation() const override { return m_StereoEyeSeparation; } + void SetStereoProgressiveEnabled(bool enabled) override + { + m_StereoProgressiveEnabled = enabled; + } + + bool GetStereoProgressiveEnabled() const override { + return m_StereoProgressiveEnabled && (m_StereoMode == StereoModes::LeftRight + || m_StereoMode == StereoModes::TopBottom); + } + void SetWireframeMode(bool inEnable) override { m_WireframeMode = inEnable; } bool GetWireframeMode() override { return m_WireframeMode; } @@ -732,10 +744,38 @@ struct SRenderContext : public IQt3DSRenderContext QT3DSVec2 GetPresentationScaleFactor() const override { return m_PresentationScale; } + void adjustRectToStereoMode(NVRenderRect &rect) + { + if (m_StereoMode == StereoModes::LeftRight) { + if (m_StereoView == StereoViews::Left) { + rect = NVRenderRect(rect.m_X, rect.m_Y, rect.m_Width / 2, + rect.m_Height); + } + if (m_StereoView == StereoViews::Right) { + rect = NVRenderRect(rect.m_X + rect.m_Width / 2, rect.m_Y, + rect.m_Width / 2, rect.m_Height); + } + } else if (m_StereoMode == StereoModes::TopBottom) { + if (m_StereoView == StereoViews::Left) { + rect = NVRenderRect(rect.m_X, rect.m_Y + rect.m_Height / 2, + rect.m_Width, rect.m_Height / 2); + } + if (m_StereoView == StereoViews::Right) { + rect = NVRenderRect(rect.m_X, rect.m_Y, + rect.m_Width, rect.m_Height / 2); + } + } + } + virtual void SetupRenderTarget() { - NVRenderRect theContextViewport(GetContextViewport()); - if (m_Viewport.hasValue()) { + bool stereoProgressiveEnabled = GetStereoProgressiveEnabled(); + // Clearing for matte / scene background + if (m_Viewport.hasValue() || stereoProgressiveEnabled) { + // With progressive stereoscopic rendering needs to be adjusted to viewport + NVRenderRect theContextViewport(GetContextViewport()); + if (stereoProgressiveEnabled) + adjustRectToStereoMode(theContextViewport); m_RenderContext->SetScissorTestEnabled(true); m_RenderContext->SetScissorRect(theContextViewport); } else { @@ -758,7 +798,10 @@ struct SRenderContext : public IQt3DSRenderContext } bool renderOffscreen = m_BeginFrameResult.m_RenderOffscreen; m_RenderContext->SetViewport(m_BeginFrameResult.m_Viewport); - m_RenderContext->SetScissorRect(m_BeginFrameResult.m_ScissorRect); + NVRenderRect scissorRect = m_BeginFrameResult.m_ScissorRect; + if (stereoProgressiveEnabled) + adjustRectToStereoMode(scissorRect); + m_RenderContext->SetScissorRect(scissorRect); m_RenderContext->SetScissorTestEnabled(m_BeginFrameResult.m_ScissorTestEnabled); if (m_PresentationViewport.m_Width > 0 && m_PresentationViewport.m_Height > 0) { @@ -826,14 +869,20 @@ struct SRenderContext : public IQt3DSRenderContext } } } + // Reset scissor rect to full viewport size + m_RenderContext->SetScissorRect(GetContextViewport()); + } void RunRenderTasks() override { m_RenderList->RunRenderTasks(); - // Don't (re)setup when rendering stereoscopic second (right) eye - if (m_StereoView != StereoViews::Right) + // Don't (re)setup when rendering stereoscopic second (right) eye. + // Except in progressive mode, where each viewport needs to be cleared separately. + if (m_StereoView != StereoViews::Right + || GetStereoProgressiveEnabled()) { SetupRenderTarget(); + } } // Note this runs before EndFrame diff --git a/src/runtimerender/Qt3DSRenderContextCore.h b/src/runtimerender/Qt3DSRenderContextCore.h index 670becc..8382fc6 100644 --- a/src/runtimerender/Qt3DSRenderContextCore.h +++ b/src/runtimerender/Qt3DSRenderContextCore.h @@ -203,6 +203,8 @@ namespace render { virtual StereoViews::Enum GetStereoView() const = 0; virtual void SetStereoEyeSeparation(double separation) = 0; virtual double GetStereoEyeSeparation() const = 0; + virtual void SetStereoProgressiveEnabled(bool enabled) = 0; + virtual bool GetStereoProgressiveEnabled() const = 0; virtual void SetWireframeMode(bool inEnable) = 0; virtual bool GetWireframeMode() = 0; -- cgit v1.2.3