Index: ps/trunk/source/graphics/GameView.h =================================================================== --- ps/trunk/source/graphics/GameView.h +++ ps/trunk/source/graphics/GameView.h @@ -18,6 +18,7 @@ #ifndef INCLUDED_GAMEVIEW #define INCLUDED_GAMEVIEW +#include "renderer/backend/IDeviceCommandContext.h" #include "renderer/Scene.h" #include "simulation2/system/Entity.h" @@ -37,7 +38,7 @@ NONCOPYABLE(CGameView); public: CGameView(CGame *pGame); - ~CGameView(); + ~CGameView() override; void SetViewport(const SViewPort& vp); @@ -53,7 +54,9 @@ void Update(const float deltaRealTime); void BeginFrame(); - void Render(); + void Prepare(Renderer::Backend::IDeviceCommandContext* deviceCommandContext); + void Render(Renderer::Backend::IDeviceCommandContext* deviceCommandContext); + void RenderOverlays(Renderer::Backend::IDeviceCommandContext* deviceCommandContext); InReaction HandleEvent(const SDL_Event_* ev); Index: ps/trunk/source/graphics/GameView.cpp =================================================================== --- ps/trunk/source/graphics/GameView.cpp +++ ps/trunk/source/graphics/GameView.cpp @@ -233,9 +233,22 @@ m->Game->CachePlayerColors(); } -void CGameView::Render() +void CGameView::Prepare( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) { - g_Renderer.GetSceneRenderer().RenderScene(g_Renderer.GetDeviceCommandContext(), *this); + g_Renderer.GetSceneRenderer().PrepareScene(deviceCommandContext, *this); +} + +void CGameView::Render( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) +{ + g_Renderer.GetSceneRenderer().RenderScene(deviceCommandContext); +} + +void CGameView::RenderOverlays( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) +{ + g_Renderer.GetSceneRenderer().RenderSceneOverlays(deviceCommandContext); } /////////////////////////////////////////////////////////// Index: ps/trunk/source/renderer/Renderer.cpp =================================================================== --- ps/trunk/source/renderer/Renderer.cpp +++ ps/trunk/source/renderer/Renderer.cpp @@ -463,11 +463,52 @@ if (g_Game && g_Game->IsGameStarted()) { - g_Game->GetView()->Render(); - } + g_Game->GetView()->Prepare(m->deviceCommandContext.get()); + + m->deviceCommandContext->SetGraphicsPipelineState( + Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc()); + + CPostprocManager& postprocManager = g_Renderer.GetPostprocManager(); + if (postprocManager.IsEnabled()) + { + // We have to update the post process manager with real near/far planes + // that we use for the scene rendering. + postprocManager.SetDepthBufferClipPlanes( + m->sceneRenderer.GetViewCamera().GetNearPlane(), + m->sceneRenderer.GetViewCamera().GetFarPlane() + ); + postprocManager.Initialize(); + postprocManager.CaptureRenderOutput(m->deviceCommandContext.get()); + } + else + { + m->deviceCommandContext->BeginFramebufferPass( + m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + } - m->deviceCommandContext->BeginFramebufferPass( - m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + g_Game->GetView()->Render(m->deviceCommandContext.get()); + + if (postprocManager.IsEnabled()) + { + m->deviceCommandContext->EndFramebufferPass(); + + if (postprocManager.IsMultisampleEnabled()) + postprocManager.ResolveMultisampleFramebuffer(m->deviceCommandContext.get()); + + postprocManager.ApplyPostproc(m->deviceCommandContext.get()); + postprocManager.ReleaseRenderOutput(m->deviceCommandContext.get()); + + m->deviceCommandContext->BeginFramebufferPass( + m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + } + + g_Game->GetView()->RenderOverlays(m->deviceCommandContext.get()); + } + else + { + m->deviceCommandContext->BeginFramebufferPass( + m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + } // If we're in Atlas game view, render special tools if (g_AtlasGameLoop && g_AtlasGameLoop->view) Index: ps/trunk/source/renderer/SceneRenderer.h =================================================================== --- ps/trunk/source/renderer/SceneRenderer.h +++ ps/trunk/source/renderer/SceneRenderer.h @@ -21,6 +21,7 @@ #include "graphics/Camera.h" #include "graphics/ShaderDefines.h" #include "graphics/ShaderProgramPtr.h" +#include "maths/BoundingBoxAligned.h" #include "ps/Singleton.h" #include "renderer/backend/IDeviceCommandContext.h" #include "renderer/RenderingOptions.h" @@ -94,10 +95,24 @@ void SetSceneCamera(const CCamera& viewCamera, const CCamera& cullCamera); /** - * Render the given scene immediately. - * @param scene a Scene object describing what should be rendered. + * Enumerate and submit all objects of the given scene which should be rendered. + * Must be called before RenderScene. */ - void RenderScene(Renderer::Backend::IDeviceCommandContext* deviceCommandContext, Scene& scene); + void PrepareScene( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, Scene& scene); + + /** + * Render submitted objects of the previously given scene. + */ + void RenderScene( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext); + + /** + * Render overlays of the previously given scene. + * Must be called after RenderScene. + */ + void RenderSceneOverlays( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext); /** * Return the scene that is currently being rendered. @@ -193,6 +208,13 @@ void Submit(SOverlaySphere* overlay) override; void SubmitNonRecursive(CModel* model) override; + /** + * Update and upload all needed data for submitted objects. + */ + void PrepareSubmissions( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + const CBoundingBoxAligned& waterScissor); + // render any batched objects void RenderSubmissions( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, @@ -272,6 +294,8 @@ Scene* m_CurrentScene; int m_CurrentCullGroup; + CBoundingBoxAligned m_WaterScissor; + // current lighting setup CLightEnv* m_LightEnv; Index: ps/trunk/source/renderer/SceneRenderer.cpp =================================================================== --- ps/trunk/source/renderer/SceneRenderer.cpp +++ ps/trunk/source/renderer/SceneRenderer.cpp @@ -51,7 +51,6 @@ #include "renderer/ModelRenderer.h" #include "renderer/OverlayRenderer.h" #include "renderer/ParticleRenderer.h" -#include "renderer/PostprocManager.h" #include "renderer/Renderer.h" #include "renderer/RenderingOptions.h" #include "renderer/RenderModifiers.h" @@ -757,13 +756,12 @@ } } -// RenderSubmissions: force rendering of any batched objects -void CSceneRenderer::RenderSubmissions( +void CSceneRenderer::PrepareSubmissions( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, const CBoundingBoxAligned& waterScissor) { - PROFILE3("render submissions"); - GPU_SCOPED_LABEL(deviceCommandContext, "Render submissions"); + PROFILE3("prepare submissions"); + GPU_SCOPED_LABEL(deviceCommandContext, "Prepare submissions"); m->skyManager.LoadAndUploadSkyTexturesIfNeeded(deviceCommandContext); @@ -774,8 +772,6 @@ CShaderDefines context = m->globalContext; - int cullGroup = CULL_DEFAULT; - // Set the camera g_Renderer.SetViewport(m_ViewCamera.GetViewPort()); @@ -829,29 +825,21 @@ RenderRefractions(deviceCommandContext, context, waterScissor); if (g_RenderingOptions.GetWaterFancyEffects()) - m->terrainRenderer.RenderWaterFoamOccluders(deviceCommandContext, cullGroup); + m->terrainRenderer.RenderWaterFoamOccluders(deviceCommandContext, CULL_DEFAULT); } } +} - deviceCommandContext->SetGraphicsPipelineState( - Renderer::Backend::MakeDefaultGraphicsPipelineStateDesc()); +void CSceneRenderer::RenderSubmissions( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext, + const CBoundingBoxAligned& waterScissor) +{ + PROFILE3("render submissions"); + GPU_SCOPED_LABEL(deviceCommandContext, "Render submissions"); - CPostprocManager& postprocManager = g_Renderer.GetPostprocManager(); - if (postprocManager.IsEnabled()) - { - // We have to update the post process manager with real near/far planes - // that we use for the scene rendering. - postprocManager.SetDepthBufferClipPlanes( - m_ViewCamera.GetNearPlane(), m_ViewCamera.GetFarPlane() - ); - postprocManager.Initialize(); - postprocManager.CaptureRenderOutput(deviceCommandContext); - } - else - { - deviceCommandContext->BeginFramebufferPass( - deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); - } + CShaderDefines context = m->globalContext; + + constexpr int cullGroup = CULL_DEFAULT; { PROFILE3_GPU("clear buffers"); @@ -912,24 +900,6 @@ RenderParticles(deviceCommandContext, cullGroup); } - if (postprocManager.IsEnabled()) - { - deviceCommandContext->EndFramebufferPass(); - - if (g_Renderer.GetPostprocManager().IsMultisampleEnabled()) - g_Renderer.GetPostprocManager().ResolveMultisampleFramebuffer(deviceCommandContext); - - postprocManager.ApplyPostproc(deviceCommandContext); - postprocManager.ReleaseRenderOutput(deviceCommandContext); - deviceCommandContext->BeginFramebufferPass( - deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); - } - - if (g_RenderingOptions.GetSilhouettes()) - { - RenderSilhouettes(deviceCommandContext, context); - } - // render debug lines if (g_RenderingOptions.GetDisplayFrustum()) DisplayFrustum(); @@ -938,12 +908,6 @@ m->shadow.RenderDebugBounds(); m->silhouetteRenderer.RenderDebugBounds(deviceCommandContext); - m->silhouetteRenderer.RenderDebugOverlays(deviceCommandContext); - - // render overlays that should appear on top of all other objects - m->overlayRenderer.RenderForegroundOverlays(deviceCommandContext, m_ViewCamera); - - deviceCommandContext->EndFramebufferPass(); } void CSceneRenderer::EndFrame() @@ -1093,8 +1057,7 @@ } } -// Render the given scene -void CSceneRenderer::RenderScene( +void CSceneRenderer::PrepareScene( Renderer::Backend::IDeviceCommandContext* deviceCommandContext, Scene& scene) { m_CurrentScene = &scene; @@ -1131,19 +1094,18 @@ } } - CBoundingBoxAligned waterScissor; if (m->waterManager.m_RenderWater) { - waterScissor = m->terrainRenderer.ScissorWater(CULL_DEFAULT, m_ViewCamera); + m_WaterScissor = m->terrainRenderer.ScissorWater(CULL_DEFAULT, m_ViewCamera); - if (waterScissor.GetVolume() > 0 && m->waterManager.WillRenderFancyWater()) + if (m_WaterScissor.GetVolume() > 0 && m->waterManager.WillRenderFancyWater()) { if (g_RenderingOptions.GetWaterReflection()) { m_CurrentCullGroup = CULL_REFLECTIONS; CCamera reflectionCamera; - ComputeReflectionCamera(reflectionCamera, waterScissor); + ComputeReflectionCamera(reflectionCamera, m_WaterScissor); scene.EnumerateObjects(reflectionCamera.GetFrustum(), this); } @@ -1153,7 +1115,7 @@ m_CurrentCullGroup = CULL_REFRACTIONS; CCamera refractionCamera; - ComputeRefractionCamera(refractionCamera, waterScissor); + ComputeRefractionCamera(refractionCamera, m_WaterScissor); scene.EnumerateObjects(refractionCamera.GetFrustum(), this); } @@ -1162,12 +1124,35 @@ m->waterManager.RenderWaves(deviceCommandContext, frustum); } } + else + m_WaterScissor = CBoundingBoxAligned{}; m_CurrentCullGroup = -1; - RenderSubmissions(deviceCommandContext, waterScissor); + PrepareSubmissions(deviceCommandContext, m_WaterScissor); +} + +void CSceneRenderer::RenderScene( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) +{ + ENSURE(m_CurrentScene); + RenderSubmissions(deviceCommandContext, m_WaterScissor); +} + +void CSceneRenderer::RenderSceneOverlays( + Renderer::Backend::IDeviceCommandContext* deviceCommandContext) +{ + if (g_RenderingOptions.GetSilhouettes()) + { + RenderSilhouettes(deviceCommandContext, m->globalContext); + } + + m->silhouetteRenderer.RenderDebugOverlays(deviceCommandContext); - m_CurrentScene = NULL; + // Render overlays that should appear on top of all other objects. + m->overlayRenderer.RenderForegroundOverlays(deviceCommandContext, m_ViewCamera); + + m_CurrentScene = nullptr; } Scene& CSceneRenderer::GetScene() Index: ps/trunk/source/tools/atlas/GameInterface/ActorViewer.cpp =================================================================== --- ps/trunk/source/tools/atlas/GameInterface/ActorViewer.cpp +++ ps/trunk/source/tools/atlas/GameInterface/ActorViewer.cpp @@ -44,6 +44,8 @@ #include "ps/GameSetup/Config.h" #include "ps/ProfileViewer.h" #include "ps/VideoMode.h" +#include "renderer/backend/IDevice.h" +#include "renderer/backend/IDeviceCommandContext.h" #include "renderer/Renderer.h" #include "renderer/RenderingOptions.h" #include "renderer/Scene.h" @@ -509,8 +511,10 @@ { // TODO: ActorViewer should reuse CRenderer code and not duplicate it. + CSceneRenderer& sceneRenderer = g_Renderer.GetSceneRenderer(); + // Set simulation context for rendering purposes - g_Renderer.GetSceneRenderer().SetSimulation(&m.Simulation2); + sceneRenderer.SetSimulation(&m.Simulation2); // Find the centre of the interesting region, in the middle of the patch // and half way up the model (assuming there is one) @@ -526,18 +530,29 @@ camera.m_Orientation.Translate(centre.X, centre.Y, centre.Z); camera.UpdateFrustum(); - g_Renderer.GetSceneRenderer().SetSceneCamera(camera, camera); + sceneRenderer.SetSceneCamera(camera, camera); g_Renderer.BeginFrame(); - g_Renderer.GetSceneRenderer().RenderScene(g_Renderer.GetDeviceCommandContext(), m); + Renderer::Backend::IDeviceCommandContext* deviceCommandContext = + g_Renderer.GetDeviceCommandContext(); + + sceneRenderer.PrepareScene(deviceCommandContext, m); + + deviceCommandContext->BeginFramebufferPass( + deviceCommandContext->GetDevice()->GetCurrentBackbuffer()); + + sceneRenderer.RenderScene(deviceCommandContext); + sceneRenderer.RenderSceneOverlays(deviceCommandContext); { - CCanvas2D canvas(g_xres, g_yres, g_VideoMode.GetScale(), g_Renderer.GetDeviceCommandContext()); + CCanvas2D canvas(g_xres, g_yres, g_VideoMode.GetScale(), deviceCommandContext); g_Logger->Render(canvas); g_ProfileViewer.RenderProfile(canvas); } + deviceCommandContext->EndFramebufferPass(); + g_Renderer.EndFrame(); }