diff options
Diffstat (limited to 'src/Runtime/ogl-runtime/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp')
m--------- | src/Runtime/ogl-runtime | 0 | ||||
-rw-r--r-- | src/Runtime/ogl-runtime/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp | 2220 |
2 files changed, 0 insertions, 2220 deletions
diff --git a/src/Runtime/ogl-runtime b/src/Runtime/ogl-runtime new file mode 160000 +Subproject 427fddb50d43aa21a90fc7356ee3cdd8a908df5 diff --git a/src/Runtime/ogl-runtime/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp b/src/Runtime/ogl-runtime/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp deleted file mode 100644 index 362a6027..00000000 --- a/src/Runtime/ogl-runtime/src/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderData.cpp +++ /dev/null @@ -1,2220 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "Qt3DSRender.h" -#include "Qt3DSRenderer.h" -#include "Qt3DSRendererImpl.h" -#include "Qt3DSRenderLayer.h" -#include "Qt3DSRenderEffect.h" -#include "EASTL/sort.h" -#include "Qt3DSRenderLight.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderScene.h" -#include "Qt3DSRenderPresentation.h" -#include "foundation/Qt3DSFoundation.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderResourceManager.h" -#include "Qt3DSTextRenderer.h" -#include "Qt3DSRenderEffectSystem.h" -#include "render/Qt3DSRenderFrameBuffer.h" -#include "render/Qt3DSRenderRenderBuffer.h" -#include "Qt3DSOffscreenRenderKey.h" -#include "Qt3DSRenderPlugin.h" -#include "Qt3DSRenderPluginGraphObject.h" -#include "Qt3DSRenderResourceBufferObjects.h" -#include "foundation/Qt3DSPerfTimer.h" -#include "foundation/AutoDeallocatorAllocator.h" -#include "Qt3DSRenderMaterialHelpers.h" -#include "Qt3DSRenderBufferManager.h" -#include "Qt3DSRenderCustomMaterialSystem.h" -#include "Qt3DSRenderTextTextureCache.h" -#include "Qt3DSRenderTextTextureAtlas.h" -#include "Qt3DSRenderRenderList.h" -#include "Qt3DSRendererUtil.h" - -#ifdef WIN32 -#pragma warning(disable : 4355) -#endif - -#define QT3DS_CACHED_POST_EFFECT -const float QT3DS_DEGREES_TO_RADIANS = 0.0174532925199f; - -namespace qt3ds { -namespace render { - using eastl::reverse; - using eastl::stable_sort; - using qt3ds::render::NVRenderContextScopedProperty; - using qt3ds::QT3DSVec2; - - SLayerRenderData::SLayerRenderData(SLayer &inLayer, Qt3DSRendererImpl &inRenderer) - : SLayerRenderPreparationData(inLayer, inRenderer) - , m_LayerTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_TemporalAATexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerPrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerSsaoTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerMultisampleTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerMultisamplePrepassDepthTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerMultisampleWidgetTexture(inRenderer.GetQt3DSContext().GetResourceManager()) - , m_LayerCachedTexture(NULL) - , m_AdvancedBlendDrawTexture(NULL) - , m_AdvancedBlendBlendTexture(NULL) - , m_AdvancedModeDrawFB(NULL) - , m_AdvancedModeBlendFB(NULL) - , m_ProgressiveAAPassIndex(0) - , m_TemporalAAPassIndex(0) - , m_NonDirtyTemporalAAPassIndex(0) - , m_TextScale(1.0f) - , mRefCount(0) - , m_DepthBufferFormat(NVRenderTextureFormats::Unknown) - { - } - - SLayerRenderData::~SLayerRenderData() - { - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) - theResourceManager.Release(*m_LayerCachedTexture); - if (m_AdvancedModeDrawFB) { - m_AdvancedModeDrawFB->release(); - m_AdvancedModeDrawFB = NULL; - } - if (m_AdvancedModeBlendFB) { - m_AdvancedModeBlendFB->release(); - m_AdvancedModeBlendFB = NULL; - } - if (m_AdvancedBlendBlendTexture) - m_AdvancedBlendBlendTexture = NULL; - if (m_AdvancedBlendDrawTexture) - m_AdvancedBlendDrawTexture = NULL; - } - void SLayerRenderData::PrepareForRender(const QSize &inViewportDimensions) - { - SLayerRenderPreparationData::PrepareForRender(inViewportDimensions); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - // at that time all values shoud be updated - m_Renderer.UpdateCbAoShadow(&m_Layer, m_Camera, m_LayerDepthTexture); - - // Generate all necessary lighting keys - - if (thePrepResult.m_Flags.WasLayerDataDirty()) { - m_ProgressiveAAPassIndex = 0; - } - - // Get rid of the layer texture if we aren't rendering to texture this frame. - if (m_LayerTexture && !thePrepResult.m_Flags.ShouldRenderToTexture()) { - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) { - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; - } - - m_LayerTexture.ReleaseTexture(); - m_LayerDepthTexture.ReleaseTexture(); - m_LayerWidgetTexture.ReleaseTexture(); - m_LayerSsaoTexture.ReleaseTexture(); - m_LayerMultisampleTexture.ReleaseTexture(); - m_LayerMultisamplePrepassDepthTexture.ReleaseTexture(); - m_LayerMultisampleWidgetTexture.ReleaseTexture(); - } - - if (NeedsWidgetTexture() == false) - m_LayerWidgetTexture.ReleaseTexture(); - - if (m_LayerDepthTexture && !thePrepResult.m_Flags.RequiresDepthTexture()) - m_LayerDepthTexture.ReleaseTexture(); - - if (m_LayerSsaoTexture && !thePrepResult.m_Flags.RequiresSsaoPass()) - m_LayerSsaoTexture.ReleaseTexture(); - - m_Renderer.LayerNeedsFrameClear(*this); - - // Clean up the texture cache if layer dimensions changed - if (inViewportDimensions.width() != m_previousDimensions.width() - || inViewportDimensions.height() != m_previousDimensions.height()) { - m_LayerTexture.ReleaseTexture(); - m_LayerDepthTexture.ReleaseTexture(); - m_LayerSsaoTexture.ReleaseTexture(); - m_LayerWidgetTexture.ReleaseTexture(); - m_LayerPrepassDepthTexture.ReleaseTexture(); - m_TemporalAATexture.ReleaseTexture(); - m_LayerMultisampleTexture.ReleaseTexture(); - m_LayerMultisamplePrepassDepthTexture.ReleaseTexture(); - m_LayerMultisampleWidgetTexture.ReleaseTexture(); - - m_previousDimensions.setWidth(inViewportDimensions.width()); - m_previousDimensions.setHeight(inViewportDimensions.height()); - - theResourceManager.DestroyFreeSizedResources(); - - // Effect system uses different resource manager, so clean that up too - m_Renderer.GetQt3DSContext().GetEffectSystem().GetResourceManager() - .DestroyFreeSizedResources(); - } - } - - NVRenderTextureFormats::Enum SLayerRenderData::GetDepthBufferFormat() - { - if (m_DepthBufferFormat == NVRenderTextureFormats::Unknown) { - QT3DSU32 theExistingDepthBits = m_Renderer.GetContext().GetDepthBits(); - QT3DSU32 theExistingStencilBits = m_Renderer.GetContext().GetStencilBits(); - switch (theExistingDepthBits) { - case 32: - m_DepthBufferFormat = NVRenderTextureFormats::Depth32; - break; - case 24: - // check if we have stencil bits - if (theExistingStencilBits > 0) - m_DepthBufferFormat = - NVRenderTextureFormats::Depth24Stencil8; // currently no stencil usage - // should be Depth24Stencil8 in - // this case - else - m_DepthBufferFormat = NVRenderTextureFormats::Depth24; - break; - case 16: - m_DepthBufferFormat = NVRenderTextureFormats::Depth16; - break; - default: - QT3DS_ASSERT(false); - m_DepthBufferFormat = NVRenderTextureFormats::Depth16; - break; - } - } - return m_DepthBufferFormat; - } - - NVRenderFrameBufferAttachments::Enum - SLayerRenderData::GetFramebufferDepthAttachmentFormat(NVRenderTextureFormats::Enum depthFormat) - { - NVRenderFrameBufferAttachments::Enum fmt = NVRenderFrameBufferAttachments::Depth; - - switch (depthFormat) { - case NVRenderTextureFormats::Depth16: - case NVRenderTextureFormats::Depth24: - case NVRenderTextureFormats::Depth32: - fmt = NVRenderFrameBufferAttachments::Depth; - break; - case NVRenderTextureFormats::Depth24Stencil8: - fmt = NVRenderFrameBufferAttachments::DepthStencil; - break; - default: - QT3DS_ASSERT(false); - break; - } - - return fmt; - } - - void SLayerRenderData::RenderAoPass() - { - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theContext(m_Renderer.GetContext()); - SDefaultAoPassShader *shader = m_Renderer.GetDefaultAoPassShader(GetShaderFeatureSet()); - if (shader == NULL) - return; - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - theContext.SetActiveShader(&(shader->m_Shader)); - - // Setup constants - shader->m_CameraDirection.Set(m_CameraDirection); - shader->m_ViewMatrix.Set(m_Camera->m_GlobalTransform); - - shader->m_DepthTexture.Set(m_LayerDepthTexture); - shader->m_DepthSamplerSize.Set(QT3DSVec2(m_LayerDepthTexture->GetTextureDetails().m_Width, - m_LayerDepthTexture->GetTextureDetails().m_Height)); - - // Important uniforms for AO calculations - QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); - shader->m_CameraProperties.Set(theCameraProps); - shader->m_AoShadowParams.Set(); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - m_Renderer.EndLayerDepthPassRender(); - } - - void SLayerRenderData::RenderFakeDepthMapPass(NVRenderTexture2D *theDepthTex, - NVRenderTextureCube *theDepthCube) - { - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theContext(m_Renderer.GetContext()); - SDefaultAoPassShader *shader = theDepthTex - ? m_Renderer.GetFakeDepthShader(GetShaderFeatureSet()) - : m_Renderer.GetFakeCubeDepthShader(GetShaderFeatureSet()); - if (shader == NULL) - return; - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - theContext.SetActiveShader(&(shader->m_Shader)); - - // Setup constants - shader->m_CameraDirection.Set(m_CameraDirection); - shader->m_ViewMatrix.Set(m_Camera->m_GlobalTransform); - - shader->m_DepthTexture.Set(theDepthTex); - shader->m_CubeTexture.Set(theDepthCube); - shader->m_DepthSamplerSize.Set(QT3DSVec2(theDepthTex->GetTextureDetails().m_Width, - theDepthTex->GetTextureDetails().m_Height)); - - // Important uniforms for AO calculations - QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); - shader->m_CameraProperties.Set(theCameraProps); - shader->m_AoShadowParams.Set(); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - } - - namespace { - - void computeFrustumBounds(const SCamera &inCamera, const NVRenderRectF &inViewPort, - QT3DSVec3 &ctrBound, QT3DSVec3 camVerts[8]) - { - QT3DSVec3 camEdges[4]; - - const QT3DSF32 *dataPtr(inCamera.m_GlobalTransform.front()); - QT3DSVec3 camX(dataPtr[0], dataPtr[1], dataPtr[2]); - QT3DSVec3 camY(dataPtr[4], dataPtr[5], dataPtr[6]); - QT3DSVec3 camZ(dataPtr[8], dataPtr[9], dataPtr[10]); - - float tanFOV = tanf(inCamera.verticalFov(inViewPort) * 0.5f); - float asTanFOV = tanFOV * inViewPort.m_Width / inViewPort.m_Height; - camEdges[0] = -asTanFOV * camX + tanFOV * camY + camZ; - camEdges[1] = asTanFOV * camX + tanFOV * camY + camZ; - camEdges[2] = asTanFOV * camX - tanFOV * camY + camZ; - camEdges[3] = -asTanFOV * camX - tanFOV * camY + camZ; - - for (int i = 0; i < 4; ++i) { - camEdges[i].x = -camEdges[i].x; - camEdges[i].y = -camEdges[i].y; - } - - camVerts[0] = inCamera.m_Position + camEdges[0] * inCamera.m_ClipNear; - camVerts[1] = inCamera.m_Position + camEdges[0] * inCamera.m_ClipFar; - camVerts[2] = inCamera.m_Position + camEdges[1] * inCamera.m_ClipNear; - camVerts[3] = inCamera.m_Position + camEdges[1] * inCamera.m_ClipFar; - camVerts[4] = inCamera.m_Position + camEdges[2] * inCamera.m_ClipNear; - camVerts[5] = inCamera.m_Position + camEdges[2] * inCamera.m_ClipFar; - camVerts[6] = inCamera.m_Position + camEdges[3] * inCamera.m_ClipNear; - camVerts[7] = inCamera.m_Position + camEdges[3] * inCamera.m_ClipFar; - - ctrBound = camVerts[0]; - for (int i = 1; i < 8; ++i) { - ctrBound += camVerts[i]; - } - ctrBound *= 0.125f; - } - - void SetupCameraForShadowMap(const QT3DSVec2 &inCameraVec, NVRenderContext & /*inContext*/, - const NVRenderRectF &inViewport, const SCamera &inCamera, - const SLight *inLight, SCamera &theCamera) - { - // setup light matrix - QT3DSU32 mapRes = 1 << inLight->m_ShadowMapRes; - NVRenderRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes); - theCamera.m_ClipNear = 1.0f; - theCamera.m_ClipFar = inLight->m_ShadowMapFar; - // Setup camera projection - QT3DSVec3 inLightPos = inLight->GetGlobalPos(); - QT3DSVec3 inLightDir = inLight->GetDirection(); - - if (inLight->m_Flags.IsLeftHanded()) - inLightPos.z = -inLightPos.z; - - inLightPos -= inLightDir * inCamera.m_ClipNear; - 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 forward = inLightDir; - forward.normalize(); - QT3DSVec3 right = forward.cross(QT3DSVec3(0, 1, 0)); - right.normalize(); - QT3DSVec3 up = right.cross(forward); - 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; - } - - // 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); - } - - theCamera.m_Flags.SetLeftHanded(false); - - theCamera.m_Flags.ClearOrSet(inLight->m_LightType == RenderLightTypes::Directional, - NodeFlagValues::Orthographic); - theCamera.m_Parent = NULL; - theCamera.m_Pivot = inLight->m_Pivot; - - if (inLight->m_LightType != RenderLightTypes::Point) { - theCamera.LookAt(inLightPos, QT3DSVec3(0, 1.0, 0), inLightPos + inLightDir); - } else { - theCamera.LookAt(inLightPos, QT3DSVec3(0, 1.0, 0), QT3DSVec3(0, 0, 0)); - } - - theCamera.CalculateGlobalVariables(theViewport, - QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); - } - } - - void SetupCubeShadowCameras(const SLight *inLight, SCamera inCameras[6]) - { - // setup light matrix - QT3DSU32 mapRes = 1 << inLight->m_ShadowMapRes; - NVRenderRectF theViewport(0.0f, 0.0f, (float)mapRes, (float)mapRes); - QT3DSVec3 rotOfs[6]; - - QT3DS_ASSERT(inLight != NULL); - QT3DS_ASSERT(inLight->m_LightType != RenderLightTypes::Directional); - - QT3DSVec3 inLightPos = inLight->GetGlobalPos(); - if (inLight->m_Flags.IsLeftHanded()) - inLightPos.z = -inLightPos.z; - - rotOfs[0] = QT3DSVec3(0.f, -NVHalfPi, NVPi); - rotOfs[1] = QT3DSVec3(0.f, NVHalfPi, NVPi); - rotOfs[2] = QT3DSVec3(NVHalfPi, 0.f, 0.f); - rotOfs[3] = QT3DSVec3(-NVHalfPi, 0.f, 0.f); - rotOfs[4] = QT3DSVec3(0.f, NVPi, -NVPi); - rotOfs[5] = QT3DSVec3(0.f, 0.f, NVPi); - - for (int i = 0; i < 6; ++i) { - inCameras[i].m_Flags.SetLeftHanded(false); - - inCameras[i].m_Flags.ClearOrSet(false, NodeFlagValues::Orthographic); - inCameras[i].m_Parent = NULL; - inCameras[i].m_Pivot = inLight->m_Pivot; - inCameras[i].m_ClipNear = 1.0f; - inCameras[i].m_ClipFar = NVMax<QT3DSF32>(2.0f, inLight->m_ShadowMapFar); - inCameras[i].m_FOV = inLight->m_ShadowMapFov * QT3DS_DEGREES_TO_RADIANS; - - inCameras[i].m_Position = inLightPos; - inCameras[i].m_Rotation = rotOfs[i]; - inCameras[i].CalculateGlobalVariables( - theViewport, QT3DSVec2(theViewport.m_Width, theViewport.m_Height)); - } - - /* - if ( inLight->m_LightType == RenderLightTypes::Point ) return; - - QT3DSVec3 viewDirs[6]; - QT3DSVec3 viewUp[6]; - QT3DSMat33 theDirMatrix( inLight->m_GlobalTransform.getUpper3x3() ); - - viewDirs[0] = theDirMatrix.transform( QT3DSVec3( 1.f, 0.f, 0.f ) ); - viewDirs[2] = theDirMatrix.transform( QT3DSVec3( 0.f, -1.f, 0.f ) ); - viewDirs[4] = theDirMatrix.transform( QT3DSVec3( 0.f, 0.f, 1.f ) ); - viewDirs[0].normalize(); viewDirs[2].normalize(); viewDirs[4].normalize(); - viewDirs[1] = -viewDirs[0]; - viewDirs[3] = -viewDirs[2]; - viewDirs[5] = -viewDirs[4]; - - viewUp[0] = viewDirs[2]; - viewUp[1] = viewDirs[2]; - viewUp[2] = viewDirs[5]; - viewUp[3] = viewDirs[4]; - viewUp[4] = viewDirs[2]; - viewUp[5] = viewDirs[2]; - - for (int i = 0; i < 6; ++i) - { - inCameras[i].LookAt( inLightPos, viewUp[i], inLightPos + viewDirs[i] ); - inCameras[i].CalculateGlobalVariables( theViewport, QT3DSVec2( theViewport.m_Width, - theViewport.m_Height ) ); - } - */ - } - - inline void RenderRenderableShadowMapPass(SLayerRenderData &inData, SRenderableObject &inObject, - const QT3DSVec2 &inCameraProps, TShaderFeatureSet, - QT3DSU32 lightIndex, const SCamera &inCamera) - { - if (!inObject.m_RenderableFlags.IsShadowCaster()) - return; - - SShadowMapEntry *pEntry = inData.m_ShadowMapManager->GetShadowMapEntry(lightIndex); - - if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - static_cast<SSubsetRenderableBase &>(inObject).RenderShadowMapPass( - inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); - else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { - static_cast<SSubsetRenderableBase &>(inObject).RenderShadowMapPass( - inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); - } else if (inObject.m_RenderableFlags.IsPath()) { - static_cast<SPathRenderable &>(inObject).RenderShadowMapPass( - inCameraProps, inData.m_Lights[lightIndex], inCamera, pEntry); - } - } - - void SLayerRenderData::RenderShadowCubeBlurPass(CResourceFrameBuffer *theFB, - NVRenderTextureCube *target0, - NVRenderTextureCube *target1, QT3DSF32 filterSz, - QT3DSF32 clipFar) - { - NVRenderContext &theContext(m_Renderer.GetContext()); - - SShadowmapPreblurShader *shaderX = m_Renderer.GetCubeShadowBlurXShader(); - SShadowmapPreblurShader *shaderY = m_Renderer.GetCubeShadowBlurYShader(); - - if (shaderX == NULL) - return; - if (shaderY == NULL) - return; - // if ( theShader == NULL ) return; - - // Enable drawing to 6 color attachment buffers for cubemap passes - qt3ds::QT3DSI32 buffers[6] = { 0, 1, 2, 3, 4, 5 }; - qt3ds::foundation::NVConstDataRef<qt3ds::QT3DSI32> bufferList(buffers, 6); - theContext.SetDrawBuffers(bufferList); - - // Attach framebuffer targets - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, *target1, - NVRenderTextureCubeFaces::CubePosX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, *target1, - NVRenderTextureCubeFaces::CubeNegX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, *target1, - NVRenderTextureCubeFaces::CubePosY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, *target1, - NVRenderTextureCubeFaces::CubeNegY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, *target1, - NVRenderTextureCubeFaces::CubePosZ); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, *target1, - NVRenderTextureCubeFaces::CubeNegZ); - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - // theContext.SetColorWritesEnabled(true); - theContext.SetActiveShader(&(shaderX->m_Shader)); - - shaderX->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderX->m_DepthCube.Set(target0); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - theContext.SetActiveShader(&(shaderY->m_Shader)); - - // Lather, Rinse, and Repeat for the Y-blur pass - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, *target0, - NVRenderTextureCubeFaces::CubePosX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, *target0, - NVRenderTextureCubeFaces::CubeNegX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, *target0, - NVRenderTextureCubeFaces::CubePosY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, *target0, - NVRenderTextureCubeFaces::CubeNegY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, *target0, - NVRenderTextureCubeFaces::CubePosZ); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, *target0, - NVRenderTextureCubeFaces::CubeNegZ); - - shaderY->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderY->m_DepthCube.Set(target1); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - theContext.SetDepthWriteEnabled(true); - theContext.SetDepthTestEnabled(true); - // theContext.SetColorWritesEnabled(false); - - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubePosX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color1, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubeNegX); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color2, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubePosY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color3, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubeNegY); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color4, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubePosZ); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color5, NVRenderTextureOrRenderBuffer(), - NVRenderTextureCubeFaces::CubeNegZ); - - theContext.SetDrawBuffers(qt3ds::foundation::toConstDataRef((qt3ds::QT3DSI32)0)); - } - - void SLayerRenderData::RenderShadowMapBlurPass(CResourceFrameBuffer *theFB, - NVRenderTexture2D *target0, - NVRenderTexture2D *target1, QT3DSF32 filterSz, - QT3DSF32 clipFar) - { - NVRenderContext &theContext(m_Renderer.GetContext()); - - SShadowmapPreblurShader *shaderX = m_Renderer.GetOrthoShadowBlurXShader(); - SShadowmapPreblurShader *shaderY = m_Renderer.GetOrthoShadowBlurYShader(); - - if (shaderX == NULL) - return; - if (shaderY == NULL) - return; - - // Attach framebuffer target - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *target1); - //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, *target1 ); - - // Set initial state - theContext.SetBlendingEnabled(false); - theContext.SetDepthWriteEnabled(false); - theContext.SetDepthTestEnabled(false); - theContext.SetColorWritesEnabled(true); - theContext.SetActiveShader(&(shaderX->m_Shader)); - - shaderX->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderX->m_DepthMap.Set(target0); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *target0); - //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, *target0 ); - theContext.SetActiveShader(&(shaderY->m_Shader)); - - shaderY->m_CameraProperties.Set(QT3DSVec2(filterSz, clipFar)); - shaderY->m_DepthMap.Set(target1); - - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - - theContext.SetDepthWriteEnabled(true); - theContext.SetDepthTestEnabled(true); - theContext.SetColorWritesEnabled(false); - - //(*theFB)->Attach( NVRenderFrameBufferAttachments::DepthStencil, - //NVRenderTextureOrRenderBuffer() ); - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); - } - - void SLayerRenderData::RenderShadowMapPass(CResourceFrameBuffer *theFB) - { - SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::RenderShadowMapPass"); - - if (m_Camera == NULL || !GetShadowMapManager()) - return; - - // Check if we have anything to render - if (m_OpaqueObjects.size() == 0 || m_Lights.size() == 0) - return; - - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - - // we may change the viewport - NVRenderContextScopedProperty<NVRenderRect> __viewport( - theRenderContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - - // disable color writes - // theRenderContext.SetColorWritesEnabled( false ); - theRenderContext.SetColorWritesEnabled(true); - theRenderContext.SetDepthWriteEnabled(true); - theRenderContext.SetCullingEnabled(false); - theRenderContext.SetClearColor(QT3DSVec4(1.0f)); - - // we render the shadow map with a slight offset to prevent shadow acne and cull the front - // faces - NVScopedRefCounted<qt3ds::render::NVRenderRasterizerState> rsdefaultstate = - theRenderContext.CreateRasterizerState(0.0, 0.0, qt3ds::render::NVRenderFaces::Back); - NVScopedRefCounted<qt3ds::render::NVRenderRasterizerState> rsstate = - theRenderContext.CreateRasterizerState(1.5, 2.0, qt3ds::render::NVRenderFaces::Front); - theRenderContext.SetRasterizerState(rsstate); - - qt3ds::render::NVRenderClearFlags clearFlags(qt3ds::render::NVRenderClearValues::Depth - | qt3ds::render::NVRenderClearValues::Stencil - | qt3ds::render::NVRenderClearValues::Color); - - for (QT3DSU32 i = 0; i < m_Lights.size(); i++) { - // don't render shadows when not casting - if (m_Lights[i]->m_CastShadow == false) - continue; - SShadowMapEntry *pEntry = m_ShadowMapManager->GetShadowMapEntry(i); - if (pEntry && pEntry->m_DepthMap && pEntry->m_DepthCopy && pEntry->m_DepthRender) { - SCamera theCamera; - - 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); - // we need this matrix for the final rendering - theCamera.CalculateViewProjectionMatrix(pEntry->m_LightVP); - pEntry->m_LightView = theCamera.m_GlobalTransform.getInverse(); - - STextureDetails theDetails(pEntry->m_DepthMap->GetTextureDetails()); - theRenderContext.SetViewport( - NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); - - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, *pEntry->m_DepthMap); - (*theFB)->Attach(NVRenderFrameBufferAttachments::DepthStencil, - *pEntry->m_DepthRender); - theRenderContext.Clear(clearFlags); - - RunRenderPass(RenderRenderableShadowMapPass, false, true, true, i, theCamera); - RenderShadowMapBlurPass(theFB, pEntry->m_DepthMap, pEntry->m_DepthCopy, - m_Lights[i]->m_ShadowFilter, m_Lights[i]->m_ShadowMapFar); - } else if (pEntry && pEntry->m_DepthCube && pEntry->m_CubeCopy - && pEntry->m_DepthRender) { - SCamera theCameras[6]; - - SetupCubeShadowCameras(m_Lights[i], theCameras); - - // pEntry->m_LightView = m_Lights[i]->m_LightType == RenderLightTypes::Point ? - // QT3DSMat44::createIdentity() - // : m_Lights[i]->m_GlobalTransform; - pEntry->m_LightView = QT3DSMat44::createIdentity(); - - STextureDetails theDetails(pEntry->m_DepthCube->GetTextureDetails()); - theRenderContext.SetViewport( - NVRenderRect(0, 0, (QT3DSU32)theDetails.m_Width, (QT3DSU32)theDetails.m_Height)); - - // int passes = m_Lights[i]->m_LightType == RenderLightTypes::Point ? 6 : 5; - int passes = 6; - for (int k = 0; k < passes; ++k) { - // theCameras[k].CalculateViewProjectionMatrix( pEntry->m_LightCubeVP[k] ); - pEntry->m_LightCubeView[k] = theCameras[k].m_GlobalTransform.getInverse(); - theCameras[k].CalculateViewProjectionMatrix(pEntry->m_LightVP); - - // Geometry shader multiplication really doesn't work unless you have a - // 6-layered 3D depth texture... - // Otherwise, you have no way to depth test while rendering... - // which more or less completely defeats the purpose of having a cubemap render - // target. - NVRenderTextureCubeFaces::Enum curFace = - (NVRenderTextureCubeFaces::Enum)(k + 1); - //(*theFB)->AttachFace( NVRenderFrameBufferAttachments::DepthStencil, - //*pEntry->m_DepthCube, curFace ); - (*theFB)->Attach(NVRenderFrameBufferAttachments::DepthStencil, - *pEntry->m_DepthRender); - (*theFB)->AttachFace(NVRenderFrameBufferAttachments::Color0, - *pEntry->m_DepthCube, curFace); - (*theFB)->IsComplete(); - theRenderContext.Clear(clearFlags); - - RunRenderPass(RenderRenderableShadowMapPass, false, true, true, i, - theCameras[k]); - } - - RenderShadowCubeBlurPass(theFB, pEntry->m_DepthCube, pEntry->m_CubeCopy, - m_Lights[i]->m_ShadowFilter, m_Lights[i]->m_ShadowMapFar); - } - } - - (*theFB)->Attach(NVRenderFrameBufferAttachments::Depth, NVRenderTextureOrRenderBuffer()); - (*theFB)->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); - - // enable color writes - theRenderContext.SetColorWritesEnabled(true); - theRenderContext.SetCullingEnabled(true); - theRenderContext.SetClearColor(QT3DSVec4(0.0f)); - // reset rasterizer state - theRenderContext.SetRasterizerState(rsdefaultstate); - - m_Renderer.EndLayerDepthPassRender(); - } - - inline void RenderRenderableDepthPass(SLayerRenderData &inData, SRenderableObject &inObject, - const QT3DSVec2 &inCameraProps, TShaderFeatureSet, QT3DSU32, - const SCamera &inCamera) - { - if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) { - static_cast<SSubsetRenderable &>(inObject).RenderDepthPass(inCameraProps); - } else if (inObject.m_RenderableFlags.IsText()) { - static_cast<STextRenderable &>(inObject).RenderDepthPass(inCameraProps); -#if QT_VERSION >= QT_VERSION_CHECK(5,12,2) - } else if (inObject.m_RenderableFlags.isDistanceField()) { - static_cast<SDistanceFieldRenderable &>(inObject).RenderDepthPass(inCameraProps); -#endif - } else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { - static_cast<SCustomMaterialRenderable &>(inObject).RenderDepthPass( - inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, NULL); - } else if (inObject.m_RenderableFlags.IsPath()) { - static_cast<SPathRenderable &>(inObject).RenderDepthPass( - inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, NULL); - } else { - QT3DS_ASSERT(false); - } - } - - void SLayerRenderData::RenderDepthPass(bool inEnableTransparentDepthWrite) - { - SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::RenderDepthPass"); - if (m_Camera == NULL) - return; - - // Avoid running this method if possible. - if ((inEnableTransparentDepthWrite == false - && (m_OpaqueObjects.size() == 0 - || m_Layer.m_Flags.IsLayerEnableDepthPrepass() == false)) - || m_Layer.m_Flags.IsLayerEnableDepthTest() == false) - return; - - m_Renderer.BeginLayerDepthPassRender(*this); - - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - - // disable color writes - theRenderContext.SetColorWritesEnabled(false); - theRenderContext.SetDepthWriteEnabled(true); - - qt3ds::render::NVRenderClearFlags clearFlags(qt3ds::render::NVRenderClearValues::Stencil - | qt3ds::render::NVRenderClearValues::Depth); - theRenderContext.Clear(clearFlags); - - RunRenderPass(RenderRenderableDepthPass, false, true, inEnableTransparentDepthWrite, 0, - *m_Camera); - - // enable color writes - theRenderContext.SetColorWritesEnabled(true); - - m_Renderer.EndLayerDepthPassRender(); - } - - inline void RenderRenderable(SLayerRenderData &inData, SRenderableObject &inObject, - const QT3DSVec2 &inCameraProps, TShaderFeatureSet inFeatureSet, QT3DSU32, - const SCamera &inCamera) - { - if (inObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - static_cast<SSubsetRenderable &>(inObject).Render(inCameraProps, inFeatureSet); - else if (inObject.m_RenderableFlags.IsText()) - static_cast<STextRenderable &>(inObject).Render(inCameraProps); -#if QT_VERSION >= QT_VERSION_CHECK(5,12,2) - else if (inObject.m_RenderableFlags.isDistanceField()) - static_cast<SDistanceFieldRenderable &>(inObject).Render(inCameraProps); -#endif - else if (inObject.m_RenderableFlags.IsCustomMaterialMeshSubset()) { - // PKC : Need a better place to do this. - SCustomMaterialRenderable &theObject = - static_cast<SCustomMaterialRenderable &>(inObject); - if (!inData.m_Layer.m_LightProbe && theObject.m_Material.m_IblProbe) - inData.SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", - theObject.m_Material.m_IblProbe->m_TextureData.m_Texture - != NULL); - else if (inData.m_Layer.m_LightProbe) - inData.SetShaderFeature("QT3DS_ENABLE_LIGHT_PROBE", - inData.m_Layer.m_LightProbe->m_TextureData.m_Texture - != NULL); - - static_cast<SCustomMaterialRenderable &>(inObject).Render( - inCameraProps, inData, inData.m_Layer, inData.m_Lights, inCamera, - inData.m_LayerDepthTexture, inData.m_LayerSsaoTexture, inFeatureSet); - } else if (inObject.m_RenderableFlags.IsPath()) { - static_cast<SPathRenderable &>(inObject).Render( - inCameraProps, inData.m_Layer, inData.m_Lights, inCamera, - inData.m_LayerDepthTexture, inData.m_LayerSsaoTexture, inFeatureSet); - } else { - QT3DS_ASSERT(false); - } - } - - void SLayerRenderData::RunRenderPass(TRenderRenderableFunction inRenderFn, - bool inEnableBlending, bool inEnableDepthWrite, - bool inEnableTransparentDepthWrite, QT3DSU32 indexLight, - const SCamera &inCamera, CResourceFrameBuffer *theFB) - { - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - theRenderContext.SetDepthFunction(qt3ds::render::NVRenderBoolOp::LessThanOrEqual); - theRenderContext.SetBlendingEnabled(false); - QT3DSVec2 theCameraProps = QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar); - NVDataRef<SRenderableObject *> theOpaqueObjects = GetOpaqueRenderableObjects(); - bool usingDepthBuffer = - m_Layer.m_Flags.IsLayerEnableDepthTest() && theOpaqueObjects.size() > 0; - - if (usingDepthBuffer) { - theRenderContext.SetDepthTestEnabled(true); - theRenderContext.SetDepthWriteEnabled(inEnableDepthWrite); - } else { - theRenderContext.SetDepthWriteEnabled(false); - theRenderContext.SetDepthTestEnabled(false); - } - - for (QT3DSU32 idx = 0, end = theOpaqueObjects.size(); idx < end; ++idx) { - SRenderableObject &theObject(*theOpaqueObjects[idx]); - SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, m_SourceLightDirections, - theObject.m_ScopedLights); - SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); - inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), indexLight, - inCamera); - } - - // transparent objects - if (inEnableBlending || m_Layer.m_Flags.IsLayerEnableDepthTest() == false) { - theRenderContext.SetBlendingEnabled(true && inEnableBlending); - theRenderContext.SetDepthWriteEnabled(inEnableTransparentDepthWrite); - - NVDataRef<SRenderableObject *> theTransparentObjects = GetTransparentRenderableObjects(); - // Assume all objects have transparency if the layer's depth test enabled flag is true. - if (m_Layer.m_Flags.IsLayerEnableDepthTest() == true) { - for (QT3DSU32 idx = 0, end = theTransparentObjects.size(); idx < end; ++idx) { - SRenderableObject &theObject(*theTransparentObjects[idx]); - if (!(theObject.m_RenderableFlags.IsCompletelyTransparent())) { -#ifdef ADVANCED_BLEND_SW_FALLBACK - // SW fallback for advanced blend modes. - // Renders transparent objects to a separate FBO and blends them in shader - // with the opaque items and background. - DefaultMaterialBlendMode::Enum blendMode - = DefaultMaterialBlendMode::Enum::Normal; - if (theObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - blendMode = static_cast<SSubsetRenderable &>(theObject).getBlendingMode(); - bool useBlendFallback = (blendMode == DefaultMaterialBlendMode::Overlay || - blendMode == DefaultMaterialBlendMode::ColorBurn || - blendMode == DefaultMaterialBlendMode::ColorDodge) && - !theRenderContext.IsAdvancedBlendHwSupported() && - !theRenderContext.IsAdvancedBlendHwSupportedKHR() && - m_LayerPrepassDepthTexture; - if (useBlendFallback) - SetupDrawFB(true); -#endif - SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, - m_SourceLightDirections, - theObject.m_ScopedLights); - SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); - - inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), - indexLight, inCamera); -#ifdef ADVANCED_BLEND_SW_FALLBACK - // SW fallback for advanced blend modes. - // Continue blending after transparent objects have been rendered to a FBO - if (useBlendFallback) { - BlendAdvancedToFB(blendMode, true, theFB); - // restore blending status - theRenderContext.SetBlendingEnabled(inEnableBlending); - // restore depth test status - theRenderContext.SetDepthTestEnabled(usingDepthBuffer); - theRenderContext.SetDepthWriteEnabled(inEnableTransparentDepthWrite); - } -#endif - } - } - } - // If the layer doesn't have depth enabled then we have to render via an alternate route - // where the transparent objects vector could have both opaque and transparent objects. - else { - for (QT3DSU32 idx = 0, end = theTransparentObjects.size(); idx < end; ++idx) { - SRenderableObject &theObject(*theTransparentObjects[idx]); - if (!(theObject.m_RenderableFlags.IsCompletelyTransparent())) { -#ifdef ADVANCED_BLEND_SW_FALLBACK - DefaultMaterialBlendMode::Enum blendMode - = DefaultMaterialBlendMode::Enum::Normal; - if (theObject.m_RenderableFlags.IsDefaultMaterialMeshSubset()) - blendMode = static_cast<SSubsetRenderable &>(theObject).getBlendingMode(); - bool useBlendFallback = (blendMode == DefaultMaterialBlendMode::Overlay || - blendMode == DefaultMaterialBlendMode::ColorBurn || - blendMode == DefaultMaterialBlendMode::ColorDodge) && - !theRenderContext.IsAdvancedBlendHwSupported() && - !theRenderContext.IsAdvancedBlendHwSupportedKHR(); - - if (theObject.m_RenderableFlags.HasTransparency()) { - theRenderContext.SetBlendingEnabled(true && inEnableBlending); - // If we have SW fallback for blend mode, render to a FBO and blend back. - // Slow as this must be done per-object (transparent and opaque items - // are mixed, not batched) - if (useBlendFallback) - SetupDrawFB(false); - } -#endif - SScopedLightsListScope lightsScope(m_Lights, m_LightDirections, - m_SourceLightDirections, - theObject.m_ScopedLights); - SetShaderFeature(m_CGLightingFeatureName, m_Lights.empty() == false); - inRenderFn(*this, theObject, theCameraProps, GetShaderFeatureSet(), - indexLight, inCamera); -#ifdef ADVANCED_BLEND_SW_FALLBACK - if (useBlendFallback) { - BlendAdvancedToFB(blendMode, false, theFB); - // restore blending status - theRenderContext.SetBlendingEnabled(inEnableBlending); - - } -#endif - } - } - } - } - } - - void SLayerRenderData::Render(CResourceFrameBuffer *theFB) - { - SStackPerfTimer ___timer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::Render"); - if (m_Camera == NULL) - return; - - m_Renderer.BeginLayerRender(*this); - RunRenderPass(RenderRenderable, true, !m_Layer.m_Flags.IsLayerEnableDepthPrepass(), false, - 0, *m_Camera, theFB); - m_Renderer.EndLayerRender(); - } - - void SLayerRenderData::CreateGpuProfiler() - { - if (m_Renderer.GetContext().IsTimerQuerySupported()) { - m_LayerProfilerGpu = IRenderProfiler::CreateGpuProfiler( - m_Renderer.GetContext().GetFoundation(), m_Renderer.GetQt3DSContext(), - m_Renderer.GetContext()); - } - } - - void SLayerRenderData::StartProfiling(CRegisteredString &nameID, bool sync) - { - if (m_LayerProfilerGpu.mPtr) { - m_LayerProfilerGpu->StartTimer(nameID, false, sync); - } - } - - void SLayerRenderData::EndProfiling(CRegisteredString &nameID) - { - if (m_LayerProfilerGpu.mPtr) { - m_LayerProfilerGpu->EndTimer(nameID); - } - } - - void SLayerRenderData::StartProfiling(const char *nameID, bool sync) - { - if (m_LayerProfilerGpu.mPtr) { - CRegisteredString theStr( - m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(nameID)); - m_LayerProfilerGpu->StartTimer(theStr, false, sync); - } - } - - void SLayerRenderData::EndProfiling(const char *nameID) - { - if (m_LayerProfilerGpu.mPtr) { - CRegisteredString theStr( - m_Renderer.GetQt3DSContext().GetStringTable().RegisterStr(nameID)); - m_LayerProfilerGpu->EndTimer(theStr); - } - } - - void SLayerRenderData::AddVertexCount(QT3DSU32 count) - { - if (m_LayerProfilerGpu.mPtr) { - m_LayerProfilerGpu->AddVertexCount(count); - } - } - - // Assumes the viewport is setup appropriately to render the widget. - void SLayerRenderData::RenderRenderWidgets() - { - if (m_Camera) { - NVRenderContext &theContext(m_Renderer.GetContext()); - for (QT3DSU32 idx = 0, end = m_IRenderWidgets.size(); idx < end; ++idx) { - IRenderWidget &theWidget = *m_IRenderWidgets[idx]; - theWidget.Render(m_Renderer, theContext); - } - } - } - -#ifdef ADVANCED_BLEND_SW_FALLBACK - void SLayerRenderData::BlendAdvancedEquationSwFallback(NVRenderTexture2D *drawTexture, - NVRenderTexture2D *layerTexture, - AdvancedBlendModes::Enum blendMode) - { - NVRenderContext &theContext(m_Renderer.GetContext()); - SAdvancedModeBlendShader *shader = m_Renderer.GetAdvancedBlendModeShader(blendMode); - if (shader == NULL) - return; - - theContext.SetActiveShader(&(shader->m_Shader)); - - shader->m_baseLayer.Set(layerTexture); - shader->m_blendLayer.Set(drawTexture); - // Draw a fullscreen quad - m_Renderer.RenderQuad(); - } - - void SLayerRenderData::SetupDrawFB(bool depthEnabled) - { - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - // create drawing FBO and texture, if not existing - if (!m_AdvancedModeDrawFB) - m_AdvancedModeDrawFB = theRenderContext.CreateFrameBuffer(); - if (!m_AdvancedBlendDrawTexture) { - m_AdvancedBlendDrawTexture = theRenderContext.CreateTexture2D(); - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - m_AdvancedBlendDrawTexture->SetTextureData(NVDataRef<QT3DSU8>(), 0, - theViewport.m_Width, - theViewport.m_Height, - NVRenderTextureFormats::RGBA8); - m_AdvancedModeDrawFB->Attach(NVRenderFrameBufferAttachments::Color0, - *m_AdvancedBlendDrawTexture); - // Use existing depth prepass information when rendering transparent objects to a FBO - if (depthEnabled) - m_AdvancedModeDrawFB->Attach(NVRenderFrameBufferAttachments::Depth, - *m_LayerPrepassDepthTexture); - } - theRenderContext.SetRenderTarget(m_AdvancedModeDrawFB); - // make sure that depth testing is on in order to render just the - // depth-passed objects (=transparent objects) and leave background intact - if (depthEnabled) - theRenderContext.SetDepthTestEnabled(true); - theRenderContext.SetBlendingEnabled(false); - // clear color commonly is the layer background, make sure that it is all-zero here - QT3DSVec4 originalClrColor = theRenderContext.GetClearColor(); - theRenderContext.SetClearColor(QT3DSVec4(0.0)); - theRenderContext.Clear(NVRenderClearValues::Color); - theRenderContext.SetClearColor(originalClrColor); - - } - void SLayerRenderData::BlendAdvancedToFB(DefaultMaterialBlendMode::Enum blendMode, - bool depthEnabled, CResourceFrameBuffer *theFB) - { - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - AdvancedBlendModes::Enum advancedMode; - - switch (blendMode) { - case DefaultMaterialBlendMode::Overlay: - advancedMode = AdvancedBlendModes::Overlay; - break; - case DefaultMaterialBlendMode::ColorBurn: - advancedMode = AdvancedBlendModes::ColorBurn; - break; - case DefaultMaterialBlendMode::ColorDodge: - advancedMode = AdvancedBlendModes::ColorDodge; - break; - default: - Q_UNREACHABLE(); - } - // create blending FBO and texture if not existing - if (!m_AdvancedModeBlendFB) - m_AdvancedModeBlendFB = theRenderContext.CreateFrameBuffer(); - if (!m_AdvancedBlendBlendTexture) { - m_AdvancedBlendBlendTexture = theRenderContext.CreateTexture2D(); - m_AdvancedBlendBlendTexture->SetTextureData(NVDataRef<QT3DSU8>(), 0, - theViewport.m_Width, - theViewport.m_Height, - NVRenderTextureFormats::RGBA8); - m_AdvancedModeBlendFB->Attach(NVRenderFrameBufferAttachments::Color0, - *m_AdvancedBlendBlendTexture); - } - theRenderContext.SetRenderTarget(m_AdvancedModeBlendFB); - - // Blend transparent objects with SW fallback shaders. - // Disable depth testing as transparent objects have already been - // depth-checked; here we want to run shader for all layer pixels - if (depthEnabled) - { - theRenderContext.SetDepthTestEnabled(false); - theRenderContext.SetDepthWriteEnabled(false); - } - BlendAdvancedEquationSwFallback(m_AdvancedBlendDrawTexture, m_LayerTexture, advancedMode); - theRenderContext.SetRenderTarget(*theFB); - // setup read target - theRenderContext.SetReadTarget(m_AdvancedModeBlendFB); - theRenderContext.SetReadBuffer(NVReadFaces::Color0); - theRenderContext.BlitFramebuffer(0, 0, theViewport.m_Width, theViewport.m_Height, - 0, 0, theViewport.m_Width, theViewport.m_Height, - NVRenderClearValues::Color, - NVRenderTextureMagnifyingOp::Nearest); - } -#endif - - void SLayerRenderData::RenderToViewport() - { - if (m_LayerPrepResult->IsLayerVisible()) { - if (GetOffscreenRenderer()) { - if (m_Layer.m_Background == LayerBackground::Color) { - m_LastFrameOffscreenRenderer->RenderWithClear( - CreateOffscreenRenderEnvironment(), m_Renderer.GetContext(), - m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), - SScene::AlwaysClear, m_Layer.m_ClearColor, &m_Layer); - } else { - m_LastFrameOffscreenRenderer->Render( - CreateOffscreenRenderEnvironment(), m_Renderer.GetContext(), - m_Renderer.GetQt3DSContext().GetPresentationScaleFactor(), - SScene::ClearIsOptional, &m_Layer); - } - } else { - RenderDepthPass(false); - Render(); - RenderRenderWidgets(); - } - } - } - // These are meant to be pixel offsets, so you need to divide them by the width/height - // of the layer respectively. - const QT3DSVec2 s_VertexOffsets[SLayerRenderPreparationData::MAX_AA_LEVELS] = { - QT3DSVec2(-0.170840f, -0.553840f), // 1x - QT3DSVec2(0.162960f, -0.319340f), // 2x - QT3DSVec2(0.360260f, -0.245840f), // 3x - QT3DSVec2(-0.561340f, -0.149540f), // 4x - QT3DSVec2(0.249460f, 0.453460f), // 5x - QT3DSVec2(-0.336340f, 0.378260f), // 6x - QT3DSVec2(0.340000f, 0.166260f), // 7x - QT3DSVec2(0.235760f, 0.527760f), // 8x - }; - - // Blend factors are in the form of (frame blend factor, accumulator blend factor) - const QT3DSVec2 s_BlendFactors[SLayerRenderPreparationData::MAX_AA_LEVELS] = { - QT3DSVec2(0.500000f, 0.500000f), // 1x - QT3DSVec2(0.333333f, 0.666667f), // 2x - QT3DSVec2(0.250000f, 0.750000f), // 3x - QT3DSVec2(0.200000f, 0.800000f), // 4x - QT3DSVec2(0.166667f, 0.833333f), // 5x - QT3DSVec2(0.142857f, 0.857143f), // 6x - QT3DSVec2(0.125000f, 0.875000f), // 7x - QT3DSVec2(0.111111f, 0.888889f), // 8x - }; - - const QT3DSVec2 s_TemporalVertexOffsets[SLayerRenderPreparationData::MAX_TEMPORAL_AA_LEVELS] = { - QT3DSVec2(.3f, .3f), QT3DSVec2(-.3f, -.3f) - }; - - static inline void OffsetProjectionMatrix(QT3DSMat44 &inProjectionMatrix, QT3DSVec2 inVertexOffsets) - { - inProjectionMatrix.column3.x = - inProjectionMatrix.column3.x + inProjectionMatrix.column3.w * inVertexOffsets.x; - inProjectionMatrix.column3.y = - inProjectionMatrix.column3.y + inProjectionMatrix.column3.w * inVertexOffsets.y; - } - - CRegisteredString depthPassStr; - - // Render this layer's data to a texture. Required if we have any effects, - // prog AA, or if forced. - void SLayerRenderData::RenderToTexture() - { - QT3DS_ASSERT(m_LayerPrepResult->m_Flags.ShouldRenderToTexture()); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - NVRenderContext &theRenderContext(m_Renderer.GetContext()); - QSize theLayerTextureDimensions = thePrepResult.GetTextureDimensions(); - QSize theLayerOriginalTextureDimensions = theLayerTextureDimensions; - NVRenderTextureFormats::Enum DepthTextureFormat = NVRenderTextureFormats::Depth24Stencil8; - NVRenderTextureFormats::Enum ColorTextureFormat = NVRenderTextureFormats::RGBA8; - if (thePrepResult.m_LastEffect - && theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) { - if (m_Layer.m_Background != LayerBackground::Transparent) - ColorTextureFormat = NVRenderTextureFormats::R11G11B10; - else - ColorTextureFormat = NVRenderTextureFormats::RGBA16F; - } - NVRenderTextureFormats::Enum ColorSSAOTextureFormat = NVRenderTextureFormats::RGBA8; - - bool needsRender = false; - QT3DSU32 sampleCount = 1; - // check multsample mode and MSAA texture support - if (m_Layer.m_MultisampleAAMode != AAModeValues::NoAA - && theRenderContext.AreMultisampleTexturesSupported()) - sampleCount = (QT3DSU32)m_Layer.m_MultisampleAAMode; - - bool isMultisamplePass = false; - if (theRenderContext.GetRenderContextType() != NVRenderContextValues::GLES2) - isMultisamplePass = - (sampleCount > 1) || (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA); - - qt3ds::render::NVRenderTextureTargetType::Enum thFboAttachTarget = - qt3ds::render::NVRenderTextureTargetType::Texture2D; - - // If the user has disabled all layer caching this has the side effect of disabling the - // progressive AA algorithm. - if (thePrepResult.m_Flags.WasLayerDataDirty() - || thePrepResult.m_Flags.WasDirty() - || m_Renderer.IsLayerCachingEnabled() == false - || thePrepResult.m_Flags.ShouldRenderToTexture()) { - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - needsRender = true; - } - - CResourceTexture2D *renderColorTexture = &m_LayerTexture; - CResourceTexture2D *renderPrepassDepthTexture = &m_LayerPrepassDepthTexture; - CResourceTexture2D *renderWidgetTexture = &m_LayerWidgetTexture; - NVRenderContextScopedProperty<bool> __multisampleEnabled( - theRenderContext, &NVRenderContext::IsMultisampleEnabled, - &NVRenderContext::SetMultisampleEnabled); - theRenderContext.SetMultisampleEnabled(false); - if (isMultisamplePass) { - renderColorTexture = &m_LayerMultisampleTexture; - renderPrepassDepthTexture = &m_LayerMultisamplePrepassDepthTexture; - renderWidgetTexture = &m_LayerMultisampleWidgetTexture; - // for SSAA we don't use MS textures - if (m_Layer.m_MultisampleAAMode != AAModeValues::SSAA) - thFboAttachTarget = qt3ds::render::NVRenderTextureTargetType::Texture2D_MS; - } - QT3DSU32 maxTemporalPassIndex = m_Layer.m_TemporalAAEnabled ? 2 : 0; - - // If all the dimensions match then we do not have to re-render the layer. - if (m_LayerTexture.TextureMatches(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), ColorTextureFormat) - && (!thePrepResult.m_Flags.RequiresDepthTexture() - || m_LayerDepthTexture.TextureMatches(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - DepthTextureFormat)) - && m_ProgressiveAAPassIndex >= thePrepResult.m_MaxAAPassIndex - && m_NonDirtyTemporalAAPassIndex >= maxTemporalPassIndex && needsRender == false) { - return; - } - - // adjust render size for SSAA - if (m_Layer.m_MultisampleAAMode == AAModeValues::SSAA) { - QT3DSU32 ow, oh; - CRendererUtil::GetSSAARenderSize(theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), - ow, oh); - theLayerTextureDimensions = QSize(ow, oh); - } - - // If our pass index == thePreResult.m_MaxAAPassIndex then - // we shouldn't get into here. - - IResourceManager &theResourceManager = m_Renderer.GetQt3DSContext().GetResourceManager(); - bool hadLayerTexture = true; - - if (renderColorTexture->EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - ColorTextureFormat, sampleCount)) { - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - hadLayerTexture = false; - } - - if (thePrepResult.m_Flags.RequiresDepthTexture()) { - // The depth texture doesn't need to be multisample, the prepass depth does. - if (m_LayerDepthTexture.EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - DepthTextureFormat)) { - // Depth textures are generally not bilinear filtered. - m_LayerDepthTexture->SetMinFilter(NVRenderTextureMinifyingOp::Nearest); - m_LayerDepthTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Nearest); - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - } - } - - if (thePrepResult.m_Flags.RequiresSsaoPass()) { - if (m_LayerSsaoTexture.EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - ColorSSAOTextureFormat)) { - m_LayerSsaoTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - m_LayerSsaoTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - m_ProgressiveAAPassIndex = 0; - m_NonDirtyTemporalAAPassIndex = 0; - } - } - - QT3DS_ASSERT(!thePrepResult.m_Flags.RequiresDepthTexture() || m_LayerDepthTexture); - QT3DS_ASSERT(!thePrepResult.m_Flags.RequiresSsaoPass() || m_LayerSsaoTexture); - - CResourceTexture2D theLastLayerTexture(theResourceManager); - SLayerProgAABlendShader *theBlendShader = NULL; - QT3DSU32 aaFactorIndex = 0; - bool isProgressiveAABlendPass = - m_ProgressiveAAPassIndex && m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex; - bool isTemporalAABlendPass = m_Layer.m_TemporalAAEnabled && m_ProgressiveAAPassIndex == 0; - - if (isProgressiveAABlendPass || isTemporalAABlendPass) { - theBlendShader = m_Renderer.GetLayerProgAABlendShader(); - if (theBlendShader) { - m_LayerTexture.EnsureTexture(theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), - ColorTextureFormat); - QT3DSVec2 theVertexOffsets; - if (isProgressiveAABlendPass) { - theLastLayerTexture.StealTexture(m_LayerTexture); - aaFactorIndex = (m_ProgressiveAAPassIndex - 1); - theVertexOffsets = s_VertexOffsets[aaFactorIndex]; - } else { - if (m_TemporalAATexture.GetTexture()) - theLastLayerTexture.StealTexture(m_TemporalAATexture); - else { - if (hadLayerTexture) { - theLastLayerTexture.StealTexture(m_LayerTexture); - } - } - theVertexOffsets = s_TemporalVertexOffsets[m_TemporalAAPassIndex]; - ++m_TemporalAAPassIndex; - ++m_NonDirtyTemporalAAPassIndex; - m_TemporalAAPassIndex = m_TemporalAAPassIndex % MAX_TEMPORAL_AA_LEVELS; - } - if (theLastLayerTexture.GetTexture()) { - theVertexOffsets.x = - theVertexOffsets.x / (theLayerOriginalTextureDimensions.width() / 2.0f); - theVertexOffsets.y = - theVertexOffsets.y / (theLayerOriginalTextureDimensions.height() / 2.0f); - // Run through all models and update MVP. - // run through all texts and update MVP. - // run through all path and update MVP. - - // TODO - optimize this exact matrix operation. - for (QT3DSU32 idx = 0, end = m_ModelContexts.size(); idx < end; ++idx) { - QT3DSMat44 &originalProjection(m_ModelContexts[idx]->m_ModelViewProjection); - OffsetProjectionMatrix(originalProjection, theVertexOffsets); - } - for (QT3DSU32 idx = 0, end = m_OpaqueObjects.size(); idx < end; ++idx) { - if (m_OpaqueObjects[idx]->m_RenderableFlags.IsPath()) { - SPathRenderable &theRenderable = - static_cast<SPathRenderable &>(*m_OpaqueObjects[idx]); - OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, - theVertexOffsets); - } - } - for (QT3DSU32 idx = 0, end = m_TransparentObjects.size(); idx < end; ++idx) { - if (m_TransparentObjects[idx]->m_RenderableFlags.IsText()) { - STextRenderable &theRenderable = - static_cast<STextRenderable &>(*m_TransparentObjects[idx]); - OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, - theVertexOffsets); -#if QT_VERSION >= QT_VERSION_CHECK(5,12,2) - } else if (m_TransparentObjects[idx]->m_RenderableFlags - .isDistanceField()) { - SDistanceFieldRenderable &theRenderable - = static_cast<SDistanceFieldRenderable &>( - *m_TransparentObjects[idx]); - OffsetProjectionMatrix(theRenderable.m_mvp, - theVertexOffsets); -#endif - } else if (m_TransparentObjects[idx]->m_RenderableFlags.IsPath()) { - SPathRenderable &theRenderable = - static_cast<SPathRenderable &>(*m_TransparentObjects[idx]); - OffsetProjectionMatrix(theRenderable.m_ModelViewProjection, - theVertexOffsets); - } - } - } - } - } - if (theLastLayerTexture.GetTexture() == NULL) { - isProgressiveAABlendPass = false; - isTemporalAABlendPass = false; - } - // Sometimes we will have stolen the render texture. - renderColorTexture->EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), ColorTextureFormat, - sampleCount); - - if (!isTemporalAABlendPass) - m_TemporalAATexture.ReleaseTexture(); - - // Allocating a frame buffer can cause it to be bound, so we need to save state before this - // happens. - NVRenderContextScopedProperty<NVRenderFrameBuffer *> __framebuf( - theRenderContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - // Match the bit depth of the current render target to avoid popping when we switch from aa - // to non aa layers - // We have to all this here in because once we change the FB by allocating an FB we are - // screwed. - NVRenderTextureFormats::Enum theDepthFormat(GetDepthBufferFormat()); - NVRenderFrameBufferAttachments::Enum theDepthAttachmentFormat( - GetFramebufferDepthAttachmentFormat(theDepthFormat)); - - // Definitely disable the scissor rect if it is running right now. - NVRenderContextScopedProperty<bool> __scissorEnabled( - theRenderContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled, false); - CResourceFrameBuffer theFB(theResourceManager); - // Allocates the frame buffer which has the side effect of setting the current render target - // to that frame buffer. - theFB.EnsureFrameBuffer(); - - bool hasDepthObjects = m_OpaqueObjects.size() > 0; - bool requiresDepthStencilBuffer = - hasDepthObjects || thePrepResult.m_Flags.RequiresStencilBuffer(); - NVRenderRect theNewViewport(0, 0, theLayerTextureDimensions.width(), - theLayerTextureDimensions.height()); - { - theRenderContext.SetRenderTarget(theFB); - NVRenderContextScopedProperty<NVRenderRect> __viewport( - theRenderContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport, - theNewViewport); - QT3DSVec4 clearColor(0.0f); - if (m_Layer.m_Background == LayerBackground::Color) - clearColor = m_Layer.m_ClearColor; - - NVRenderContextScopedProperty<QT3DSVec4> __clearColor( - theRenderContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, - clearColor); - if (requiresDepthStencilBuffer) { - if (renderPrepassDepthTexture->EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - theDepthFormat, sampleCount)) { - (*renderPrepassDepthTexture)->SetMinFilter(NVRenderTextureMinifyingOp::Nearest); - (*renderPrepassDepthTexture) - ->SetMagFilter(NVRenderTextureMagnifyingOp::Nearest); - } - } - - if (thePrepResult.m_Flags.RequiresDepthTexture() && m_ProgressiveAAPassIndex == 0) { - // Setup FBO with single depth buffer target. - // Note this does not use multisample. - NVRenderFrameBufferAttachments::Enum theAttachment = - GetFramebufferDepthAttachmentFormat(DepthTextureFormat); - theFB->Attach(theAttachment, *m_LayerDepthTexture); - - // In this case transparent objects also may write their depth. - RenderDepthPass(true); - theFB->Attach(theAttachment, NVRenderTextureOrRenderBuffer()); - } - - if (thePrepResult.m_Flags.RequiresSsaoPass() && m_ProgressiveAAPassIndex == 0 - && m_Camera != nullptr) { - StartProfiling("AO pass", false); - // Setup FBO with single color buffer target - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerSsaoTexture); - theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); - RenderAoPass(); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer()); - EndProfiling("AO pass"); - } - - if (thePrepResult.m_Flags.RequiresShadowMapPass() && m_ProgressiveAAPassIndex == 0) { - // shadow map path - RenderShadowMapPass(&theFB); - } - - if (sampleCount > 1) { - theRenderContext.SetMultisampleEnabled(true); - } - - qt3ds::render::NVRenderClearFlags clearFlags = qt3ds::render::NVRenderClearValues::Color; - - // render depth prepass - if ((*renderPrepassDepthTexture)) { - theFB->Attach(theDepthAttachmentFormat, **renderPrepassDepthTexture, - thFboAttachTarget); - - if (m_Layer.m_Flags.IsLayerEnableDepthPrepass()) { - StartProfiling("Depth pass", false); - RenderDepthPass(false); - EndProfiling("Depth pass"); - } else { - clearFlags |= (qt3ds::render::NVRenderClearValues::Depth); - clearFlags |= (qt3ds::render::NVRenderClearValues::Stencil); - // enable depth write for the clear below - theRenderContext.SetDepthWriteEnabled(true); - } - } - - theFB->Attach(NVRenderFrameBufferAttachments::Color0, **renderColorTexture, - thFboAttachTarget); - if (m_Layer.m_Background != LayerBackground::Unspecified) - theRenderContext.Clear(clearFlags); - - // We don't clear the depth buffer because the layer render code we are about to call - // will do this. - StartProfiling("Render pass", false); - Render(&theFB); - // Debug measure to view the depth map to ensure we're rendering it correctly. - //if (m_Layer.m_TemporalAAEnabled) { - // RenderFakeDepthMapPass(m_ShadowMapManager->GetShadowMapEntry(0)->m_DepthMap, - // m_ShadowMapManager->GetShadowMapEntry(0)->m_DepthCube); - //} - EndProfiling("Render pass"); - - // Now before going further, we downsample and resolve the multisample information. - // This allows all algorithms running after - // this point to run unchanged. - if (isMultisamplePass) { - if (m_Layer.m_MultisampleAAMode != AAModeValues::SSAA) { - // Resolve the FBO to the layer texture - CRendererUtil::ResolveMutisampleFBOColorOnly( - theResourceManager, m_LayerTexture, theRenderContext, - theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), - ColorTextureFormat, *theFB); - - theRenderContext.SetMultisampleEnabled(false); - } else { - // Resolve the FBO to the layer texture - CRendererUtil::ResolveSSAAFBOColorOnly( - theResourceManager, m_LayerTexture, - theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), theRenderContext, - theLayerTextureDimensions.width(), theLayerTextureDimensions.height(), - ColorTextureFormat, *theFB); - } - } - - // CN - when I tried to get anti-aliased widgets I lost all transparency on the widget - // layer which made it overwrite the object you were - // manipulating. When I tried to use parallel nsight on it the entire studio - // application crashed on startup. - if (NeedsWidgetTexture()) { - m_LayerWidgetTexture.EnsureTexture(theLayerTextureDimensions.width(), - theLayerTextureDimensions.height(), - NVRenderTextureFormats::RGBA8); - theRenderContext.SetRenderTarget(theFB); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *m_LayerWidgetTexture); - theFB->Attach(GetFramebufferDepthAttachmentFormat(DepthTextureFormat), - *m_LayerDepthTexture); - theRenderContext.SetClearColor(QT3DSVec4(0.0f)); - theRenderContext.Clear(qt3ds::render::NVRenderClearValues::Color); - // We should already have the viewport and everything setup for this. - RenderRenderWidgets(); - } - - if (theLastLayerTexture.GetTexture() != NULL - && (isProgressiveAABlendPass || isTemporalAABlendPass)) { - theRenderContext.SetViewport( - NVRenderRect(0, 0, theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height())); - CResourceTexture2D targetTexture( - theResourceManager, theLayerOriginalTextureDimensions.width(), - theLayerOriginalTextureDimensions.height(), ColorTextureFormat); - theFB->Attach(theDepthAttachmentFormat, - NVRenderTextureOrRenderBuffer()); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, *targetTexture); - QT3DSVec2 theBlendFactors; - if (isProgressiveAABlendPass) - theBlendFactors = s_BlendFactors[aaFactorIndex]; - else - theBlendFactors = QT3DSVec2(.5f, .5f); - - theRenderContext.SetDepthTestEnabled(false); - theRenderContext.SetBlendingEnabled(false); - theRenderContext.SetCullingEnabled(false); - theRenderContext.SetActiveShader(theBlendShader->m_Shader); - theBlendShader->m_AccumSampler.Set(theLastLayerTexture); - theBlendShader->m_LastFrame.Set(m_LayerTexture); - theBlendShader->m_BlendFactors.Set(theBlendFactors); - m_Renderer.RenderQuad(); - theFB->Attach(NVRenderFrameBufferAttachments::Color0, - qt3ds::render::NVRenderTextureOrRenderBuffer()); - if (isTemporalAABlendPass) - m_TemporalAATexture.StealTexture(m_LayerTexture); - m_LayerTexture.StealTexture(targetTexture); - } - - m_LayerTexture->SetMinFilter(NVRenderTextureMinifyingOp::Linear); - m_LayerTexture->SetMagFilter(NVRenderTextureMagnifyingOp::Linear); - - // Don't remember why needs widget texture is false here. - // Should have commented why progAA plus widgets is a fail. - if (m_ProgressiveAAPassIndex < thePrepResult.m_MaxAAPassIndex - && NeedsWidgetTexture() == false) - ++m_ProgressiveAAPassIndex; - -// now we render all post effects -#ifdef QT3DS_CACHED_POST_EFFECT - ApplyLayerPostEffects(); -#endif - - if (m_LayerPrepassDepthTexture) { - // Detach any depth buffers. - theFB->Attach(theDepthAttachmentFormat, qt3ds::render::NVRenderTextureOrRenderBuffer(), - thFboAttachTarget); - } - - theFB->Attach(NVRenderFrameBufferAttachments::Color0, - qt3ds::render::NVRenderTextureOrRenderBuffer(), thFboAttachTarget); - // Let natural scoping rules destroy the other stuff. - } - } - - void SLayerRenderData::ApplyLayerPostEffects() - { - if (m_Layer.m_FirstEffect == NULL) { - if (m_LayerCachedTexture) { - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; - } - return; - } - - IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - // we use the non MSAA buffer for the effect - NVRenderTexture2D *theLayerColorTexture = m_LayerTexture; - NVRenderTexture2D *theLayerDepthTexture = m_LayerDepthTexture; - - NVRenderTexture2D *theCurrentTexture = theLayerColorTexture; - for (SEffect *theEffect = m_Layer.m_FirstEffect; theEffect; - theEffect = theEffect->m_NextEffect) { - if (theEffect->m_Flags.IsActive() && m_Camera) { - StartProfiling(theEffect->m_ClassName, false); - - NVRenderTexture2D *theRenderedEffect = theEffectSystem.RenderEffect( - SEffectRenderArgument(*theEffect, *theCurrentTexture, - QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), - theLayerDepthTexture, m_LayerPrepassDepthTexture)); - - EndProfiling(theEffect->m_ClassName); - - // If the texture came from rendering a chain of effects, then we don't need it - // after this. - if (theCurrentTexture != theLayerColorTexture) - theResourceManager.Release(*theCurrentTexture); - - theCurrentTexture = theRenderedEffect; - - if (!theRenderedEffect) { - QString errorMsg = QObject::tr("Failed to compile \"%1\" effect.\nConsider" - " removing it from the presentation.") - .arg(theEffect->m_ClassName.c_str()); - QT3DS_ALWAYS_ASSERT_MESSAGE(errorMsg.toUtf8()); - break; - } - } - } - - if (m_LayerCachedTexture && m_LayerCachedTexture != m_LayerTexture) { - theResourceManager.Release(*m_LayerCachedTexture); - m_LayerCachedTexture = NULL; - } - - if (theCurrentTexture != m_LayerTexture) - m_LayerCachedTexture = theCurrentTexture; - } - - inline bool AnyCompletelyNonTransparentObjects(TRenderableObjectList &inObjects) - { - for (QT3DSU32 idx = 0, end = inObjects.size(); idx < end; ++idx) { - if (inObjects[idx]->m_RenderableFlags.IsCompletelyTransparent() == false) - return true; - } - return false; - } - - void SLayerRenderData::RunnableRenderToViewport(qt3ds::render::NVRenderFrameBuffer *theFB) - { - // If we have an effect, an opaque object, or any transparent objects that aren't completely - // transparent - // or an offscreen renderer or a layer widget texture - // Then we can't possible affect the resulting render target. - bool needsToRender = m_Layer.m_FirstEffect != NULL || m_OpaqueObjects.empty() == false - || AnyCompletelyNonTransparentObjects(m_TransparentObjects) || GetOffscreenRenderer() - || m_LayerWidgetTexture || m_BoundingRectColor.hasValue() - || m_Layer.m_Background == LayerBackground::Color; - - if (needsToRender == false) - return; - - NVRenderContext &theContext(m_Renderer.GetContext()); - theContext.resetStates(); - - NVRenderContextScopedProperty<NVRenderFrameBuffer *> __fbo( - theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); - qt3ds::render::NVRenderRect theCurrentViewport = theContext.GetViewport(); - NVRenderContextScopedProperty<NVRenderRect> __viewport( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - NVRenderContextScopedProperty<bool> theScissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled); - NVRenderContextScopedProperty<qt3ds::render::NVRenderRect> theScissorRect( - theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - NVRenderRectF theScreenRect(thePrepResult.GetLayerToPresentationViewport()); - - bool blendingEnabled = m_Layer.m_Background != LayerBackground::Unspecified; - if (!thePrepResult.m_Flags.ShouldRenderToTexture()) { - theContext.SetViewport( - m_LayerPrepResult->GetLayerToPresentationViewport().ToIntegerRect()); - theContext.SetScissorTestEnabled(true); - theContext.SetScissorRect( - m_LayerPrepResult->GetLayerToPresentationScissorRect().ToIntegerRect()); - if (m_Layer.m_Background == LayerBackground::Color) { - NVRenderContextScopedProperty<QT3DSVec4> __clearColor( - theContext, &NVRenderContext::GetClearColor, &NVRenderContext::SetClearColor, - m_Layer.m_ClearColor); - theContext.Clear(NVRenderClearValues::Color); - } - RenderToViewport(); - } else { -// First, render the layer along with whatever progressive AA is appropriate. -// The render graph should have taken care of the render to texture step. -#ifdef QT3DS_CACHED_POST_EFFECT - NVRenderTexture2D *theLayerColorTexture = - (m_LayerCachedTexture) ? m_LayerCachedTexture : m_LayerTexture; -#else - // Then render all but the last effect - IEffectSystem &theEffectSystem(m_Renderer.GetQt3DSContext().GetEffectSystem()); - IResourceManager &theResourceManager(m_Renderer.GetQt3DSContext().GetResourceManager()); - // we use the non MSAA buffer for the effect - NVRenderTexture2D *theLayerColorTexture = m_LayerTexture; - NVRenderTexture2D *theLayerDepthTexture = m_LayerDepthTexture; - - NVRenderTexture2D *theCurrentTexture = theLayerColorTexture; - for (SEffect *theEffect = m_Layer.m_FirstEffect; - theEffect && theEffect != thePrepResult.m_LastEffect; - theEffect = theEffect->m_NextEffect) { - if (theEffect->m_Flags.IsActive() && m_Camera) { - StartProfiling(theEffect->m_ClassName, false); - - NVRenderTexture2D *theRenderedEffect = theEffectSystem.RenderEffect( - SEffectRenderArgument(*theEffect, *theCurrentTexture, - QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), - theLayerDepthTexture, m_LayerPrepassDepthTexture)); - - EndProfiling(theEffect->m_ClassName); - - // If the texture came from rendering a chain of effects, then we don't need it - // after this. - if (theCurrentTexture != theLayerColorTexture) - theResourceManager.Release(*theCurrentTexture); - - theCurrentTexture = theRenderedEffect; - } - } -#endif - // Now the last effect or straight to the scene if we have no last effect - // There are two cases we need to consider here. The first is when we shouldn't - // transform - // the result and thus we need to setup an MVP that just maps to the viewport width and - // height. - // The second is when we are expected to render to the scene using some global - // transform. - QT3DSMat44 theFinalMVP(QT3DSMat44::createIdentity()); - SCamera theTempCamera; - NVRenderRect theLayerViewport( - thePrepResult.GetLayerToPresentationViewport().ToIntegerRect()); - NVRenderRect theLayerClip( - thePrepResult.GetLayerToPresentationScissorRect().ToIntegerRect()); - - { - QT3DSMat33 ignored; - QT3DSMat44 theViewProjection; - // We could cache these variables - theTempCamera.m_Flags.SetOrthographic(true); - theTempCamera.MarkDirty(NodeTransformDirtyFlag::TransformIsDirty); - // Move the camera back far enough that we can see everything - QT3DSF32 theCameraSetback(10); - // Attempt to ensure the layer can never be clipped. - theTempCamera.m_Position.z = -theCameraSetback; - theTempCamera.m_ClipFar = 2.0f * theCameraSetback; - // Render the layer texture to the entire viewport. - SCameraGlobalCalculationResult theResult = theTempCamera.CalculateGlobalVariables( - theLayerViewport, - QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, (QT3DSF32)theLayerViewport.m_Height)); - theTempCamera.CalculateViewProjectionMatrix(theViewProjection); - SNode theTempNode; - theFinalMVP = theViewProjection; - qt3ds::render::NVRenderBlendFunctionArgument blendFunc; - qt3ds::render::NVRenderBlendEquationArgument blendEqu; - - switch (m_Layer.m_BlendType) { - case LayerBlendTypes::Screen: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - case LayerBlendTypes::Multiply: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::DstColor, NVRenderDstBlendFunc::Zero, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - case LayerBlendTypes::Add: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - case LayerBlendTypes::Subtract: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ReverseSubtract, - NVRenderBlendEquation::ReverseSubtract); - break; - case LayerBlendTypes::Overlay: - // SW fallback doesn't use blend equation - // note blend func is not used here anymore - if (theContext.IsAdvancedBlendHwSupported() || - theContext.IsAdvancedBlendHwSupportedKHR()) - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Overlay, NVRenderBlendEquation::Overlay); - break; - case LayerBlendTypes::ColorBurn: - // SW fallback doesn't use blend equation - // note blend func is not used here anymore - if (theContext.IsAdvancedBlendHwSupported() || - theContext.IsAdvancedBlendHwSupportedKHR()) - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorBurn, NVRenderBlendEquation::ColorBurn); - break; - case LayerBlendTypes::ColorDodge: - // SW fallback doesn't use blend equation - // note blend func is not used here anymore - if (theContext.IsAdvancedBlendHwSupported() || - theContext.IsAdvancedBlendHwSupportedKHR()) - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorDodge, NVRenderBlendEquation::ColorDodge); - break; - default: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); - blendEqu = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add); - break; - } - theContext.SetBlendFunction(blendFunc); - theContext.SetBlendEquation(blendEqu); - theContext.SetBlendingEnabled(blendingEnabled); - theContext.SetDepthTestEnabled(false); - } - - { - theContext.SetScissorTestEnabled(true); - theContext.SetViewport(theLayerViewport); - theContext.SetScissorRect(theLayerClip); - - // Remember the camera we used so we can get a valid pick ray - m_SceneCamera = theTempCamera; - theContext.SetDepthTestEnabled(false); -#ifndef QT3DS_CACHED_POST_EFFECT - if (thePrepResult.m_LastEffect && m_Camera) { - StartProfiling(thePrepResult.m_LastEffect->m_ClassName, false); - // inUseLayerMPV is true then we are rendering directly to the scene and thus we - // should enable blending - // for the final render pass. Else we should leave it. - theEffectSystem.RenderEffect( - SEffectRenderArgument(*thePrepResult.m_LastEffect, *theCurrentTexture, - QT3DSVec2(m_Camera->m_ClipNear, m_Camera->m_ClipFar), - theLayerDepthTexture, m_LayerPrepassDepthTexture), - theFinalMVP, blendingEnabled); - EndProfiling(thePrepResult.m_LastEffect->m_ClassName); - // If the texture came from rendering a chain of effects, then we don't need it - // after this. - if (theCurrentTexture != theLayerColorTexture) - theResourceManager.Release(*theCurrentTexture); - } else -#endif - { - theContext.SetCullingEnabled(false); - theContext.SetBlendingEnabled(blendingEnabled); - theContext.SetDepthTestEnabled(false); -#ifdef ADVANCED_BLEND_SW_FALLBACK - NVScopedRefCounted<NVRenderTexture2D> screenTexture = - m_Renderer.GetLayerBlendTexture(); - NVScopedRefCounted<NVRenderFrameBuffer> blendFB = m_Renderer.GetBlendFB(); - - // Layer blending for advanced blending modes if SW fallback is needed - // rendering to FBO and blending with separate shader - if (screenTexture) { - // Blending is enabled only if layer background has been chosen transparent - // Layers with advanced blending modes - if (blendingEnabled && (m_Layer.m_BlendType == LayerBlendTypes::Overlay || - m_Layer.m_BlendType == LayerBlendTypes::ColorBurn || - m_Layer.m_BlendType == LayerBlendTypes::ColorDodge)) { - theContext.SetScissorTestEnabled(false); - theContext.SetBlendingEnabled(false); - - // Get part matching to layer from screen texture and - // use that for blending - qt3ds::render::NVRenderTexture2D *blendBlitTexture; - blendBlitTexture = theContext.CreateTexture2D(); - blendBlitTexture->SetTextureData(NVDataRef<QT3DSU8>(), 0, - theLayerViewport.m_Width, - theLayerViewport.m_Height, - NVRenderTextureFormats::RGBA8); - qt3ds::render::NVRenderFrameBuffer *blitFB; - blitFB = theContext.CreateFrameBuffer(); - blitFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(*blendBlitTexture)); - blendFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(*screenTexture)); - theContext.SetRenderTarget(blitFB); - theContext.SetReadTarget(blendFB); - theContext.SetReadBuffer(NVReadFaces::Color0); - theContext.BlitFramebuffer(theLayerViewport.m_X, theLayerViewport.m_Y, - theLayerViewport.m_Width + - theLayerViewport.m_X, - theLayerViewport.m_Height + - theLayerViewport.m_Y, - 0, 0, - theLayerViewport.m_Width, - theLayerViewport.m_Height, - NVRenderClearValues::Color, - NVRenderTextureMagnifyingOp::Nearest); - - qt3ds::render::NVRenderTexture2D *blendResultTexture; - blendResultTexture = theContext.CreateTexture2D(); - blendResultTexture->SetTextureData(NVDataRef<QT3DSU8>(), 0, - theLayerViewport.m_Width, - theLayerViewport.m_Height, - NVRenderTextureFormats::RGBA8); - qt3ds::render::NVRenderFrameBuffer *resultFB; - resultFB = theContext.CreateFrameBuffer(); - resultFB->Attach(NVRenderFrameBufferAttachments::Color0, - NVRenderTextureOrRenderBuffer(*blendResultTexture)); - theContext.SetRenderTarget(resultFB); - - AdvancedBlendModes::Enum advancedMode; - switch (m_Layer.m_BlendType) { - case LayerBlendTypes::Overlay: - advancedMode = AdvancedBlendModes::Overlay; - break; - case LayerBlendTypes::ColorBurn: - advancedMode = AdvancedBlendModes::ColorBurn; - break; - case LayerBlendTypes::ColorDodge: - advancedMode = AdvancedBlendModes::ColorDodge; - break; - default: - advancedMode = AdvancedBlendModes::None; - break; - } - - theContext.SetViewport(NVRenderRect(0, 0, theLayerViewport.m_Width, - theLayerViewport.m_Height)); - BlendAdvancedEquationSwFallback(theLayerColorTexture, blendBlitTexture, - advancedMode); - blitFB->release(); - // save blending result to screen texture for use with other layers - theContext.SetViewport(theLayerViewport); - theContext.SetRenderTarget(blendFB); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *blendResultTexture); - // render the blended result - theContext.SetRenderTarget(theFB); - theContext.SetScissorTestEnabled(true); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *blendResultTexture); - resultFB->release(); - } else { - // Layers with normal blending modes - // save result for future use - theContext.SetViewport(theLayerViewport); - theContext.SetScissorTestEnabled(false); - theContext.SetBlendingEnabled(true); - theContext.SetRenderTarget(blendFB); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); - theContext.SetRenderTarget(theFB); - theContext.SetScissorTestEnabled(true); - theContext.SetViewport(theCurrentViewport); - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); - } - } else { - // No advanced blending SW fallback needed - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); - } -#else - m_Renderer.RenderQuad(QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, - (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *theLayerColorTexture); -#endif - } - if (m_LayerWidgetTexture) { - theContext.SetBlendingEnabled(false); - m_Renderer.SetupWidgetLayer(); - SLayerRenderPreparationResult &thePrepResult(*m_LayerPrepResult); - NVRenderRectF thePresRect(thePrepResult.GetPresentationViewport()); - NVRenderRectF theLayerRect(thePrepResult.GetLayerToPresentationViewport()); - - // Ensure we remove any offsetting in the layer rect that was caused simply by - // the - // presentation rect offsetting but then use a new rect. - NVRenderRectF theWidgetLayerRect(theLayerRect.m_X - thePresRect.m_X, - theLayerRect.m_Y - thePresRect.m_Y, - theLayerRect.m_Width, theLayerRect.m_Height); - theContext.SetScissorTestEnabled(false); - theContext.SetViewport(theWidgetLayerRect.ToIntegerRect()); - m_Renderer.RenderQuad( - QT3DSVec2((QT3DSF32)theLayerViewport.m_Width, (QT3DSF32)theLayerViewport.m_Height), - theFinalMVP, *m_LayerWidgetTexture); - } - } - } // End offscreen render code. - - if (m_BoundingRectColor.hasValue()) { - NVRenderContextScopedProperty<NVRenderRect> __viewport( - theContext, &NVRenderContext::GetViewport, &NVRenderContext::SetViewport); - NVRenderContextScopedProperty<bool> theScissorEnabled( - theContext, &NVRenderContext::IsScissorTestEnabled, - &NVRenderContext::SetScissorTestEnabled); - NVRenderContextScopedProperty<qt3ds::render::NVRenderRect> theScissorRect( - theContext, &NVRenderContext::GetScissorRect, &NVRenderContext::SetScissorRect); - m_Renderer.SetupWidgetLayer(); - // Setup a simple viewport to render to the entire presentation viewport. - theContext.SetViewport( - NVRenderRect(0, 0, (QT3DSU32)thePrepResult.GetPresentationViewport().m_Width, - (QT3DSU32)thePrepResult.GetPresentationViewport().m_Height)); - - NVRenderRectF thePresRect(thePrepResult.GetPresentationViewport()); - - // Remove any offsetting from the presentation rect since the widget layer is a - // stand-alone fbo. - NVRenderRectF theWidgetScreenRect(theScreenRect.m_X - thePresRect.m_X, - theScreenRect.m_Y - thePresRect.m_Y, - theScreenRect.m_Width, theScreenRect.m_Height); - theContext.SetScissorTestEnabled(false); - m_Renderer.DrawScreenRect(theWidgetScreenRect, *m_BoundingRectColor); - } - theContext.SetBlendFunction(qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha)); - theContext.SetBlendEquation(qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Add, NVRenderBlendEquation::Add)); - } - -#define RENDER_FRAME_NEW(type) QT3DS_NEW(m_Renderer.GetPerFrameAllocator(), type) - - void SLayerRenderData::AddLayerRenderStep() - { - SStackPerfTimer __perfTimer(m_Renderer.GetQt3DSContext().GetPerfTimer(), - "SLayerRenderData::AddLayerRenderStep"); - QT3DS_ASSERT(m_Camera); - if (!m_Camera) - return; - - IRenderList &theGraph(m_Renderer.GetQt3DSContext().GetRenderList()); - - qt3ds::render::NVRenderRect theCurrentViewport = theGraph.GetViewport(); - if (!m_LayerPrepResult.hasValue()) - PrepareForRender( - QSize(theCurrentViewport.m_Width, theCurrentViewport.m_Height)); - } - - void SLayerRenderData::PrepareForRender() - { - // When we render to the scene itself (as opposed to an offscreen buffer somewhere) - // then we use the MVP of the layer somewhat. - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - PrepareForRender( - QSize((QT3DSU32)theViewport.m_Width, (QT3DSU32)theViewport.m_Height)); - } - - void SLayerRenderData::ResetForFrame() - { - SLayerRenderPreparationData::ResetForFrame(); - m_BoundingRectColor.setEmpty(); - } - - void SLayerRenderData::PrepareAndRender(const QT3DSMat44 &inViewProjection) - { - TRenderableObjectList theTransparentObjects(m_TransparentObjects); - TRenderableObjectList theOpaqueObjects(m_OpaqueObjects); - theTransparentObjects.clear(); - theOpaqueObjects.clear(); - m_ModelContexts.clear(); - SLayerRenderPreparationResultFlags theFlags; - PrepareRenderablesForRender(inViewProjection, Empty(), 1.0, theFlags); - RenderDepthPass(false); - Render(); - } - - struct SLayerRenderToTextureRunnable : public IRenderTask - { - SLayerRenderData &m_Data; - SLayerRenderToTextureRunnable(SLayerRenderData &d) - : m_Data(d) - { - } - - void Run() override { m_Data.RenderToTexture(); } - }; - - static inline OffscreenRendererDepthValues::Enum - GetOffscreenRendererDepthValue(NVRenderTextureFormats::Enum inBufferFormat) - { - switch (inBufferFormat) { - case NVRenderTextureFormats::Depth32: - return OffscreenRendererDepthValues::Depth32; - case NVRenderTextureFormats::Depth24: - return OffscreenRendererDepthValues::Depth24; - case NVRenderTextureFormats::Depth24Stencil8: - return OffscreenRendererDepthValues::Depth24; - default: - QT3DS_ASSERT(false); // fallthrough intentional - case NVRenderTextureFormats::Depth16: - return OffscreenRendererDepthValues::Depth16; - } - } - - SOffscreenRendererEnvironment SLayerRenderData::CreateOffscreenRenderEnvironment() - { - OffscreenRendererDepthValues::Enum theOffscreenDepth( - GetOffscreenRendererDepthValue(GetDepthBufferFormat())); - NVRenderRect theViewport = m_Renderer.GetQt3DSContext().GetRenderList().GetViewport(); - return SOffscreenRendererEnvironment(theViewport.m_Width, theViewport.m_Height, - NVRenderTextureFormats::RGBA8, theOffscreenDepth, - false, AAModeValues::NoAA); - } - - IRenderTask &SLayerRenderData::CreateRenderToTextureRunnable() - { - return *RENDER_FRAME_NEW(SLayerRenderToTextureRunnable)(*this); - } - - void SLayerRenderData::addRef() { atomicIncrement(&mRefCount); } - - void SLayerRenderData::release() { QT3DS_IMPLEMENT_REF_COUNT_RELEASE(m_Allocator); } -} -} |