forked from 0ad/0ad
Moves post processing out of scene rendering to avoid framebuffer pass duplicate.
Comments By: phosit, Stan Differential Revision: https://code.wildfiregames.com/D4827 This was SVN commit r27232.
This commit is contained in:
parent
87843b5c4e
commit
8e51dfa91a
@ -233,9 +233,22 @@ void CGameView::BeginFrame()
|
||||
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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
@ -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 @@ class CGameView : private Scene
|
||||
NONCOPYABLE(CGameView);
|
||||
public:
|
||||
CGameView(CGame *pGame);
|
||||
~CGameView();
|
||||
~CGameView() override;
|
||||
|
||||
void SetViewport(const SViewPort& vp);
|
||||
|
||||
@ -53,7 +54,9 @@ public:
|
||||
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);
|
||||
|
||||
|
@ -463,11 +463,52 @@ void CRenderer::RenderFrameImpl(const bool renderGUI, const bool renderLogger)
|
||||
|
||||
if (g_Game && g_Game->IsGameStarted())
|
||||
{
|
||||
g_Game->GetView()->Render();
|
||||
}
|
||||
g_Game->GetView()->Prepare(m->deviceCommandContext.get());
|
||||
|
||||
m->deviceCommandContext->BeginFramebufferPass(
|
||||
m->deviceCommandContext->GetDevice()->GetCurrentBackbuffer());
|
||||
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());
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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 @@ void CSceneRenderer::RenderParticles(
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ void CSceneRenderer::RenderSubmissions(
|
||||
|
||||
CShaderDefines context = m->globalContext;
|
||||
|
||||
int cullGroup = CULL_DEFAULT;
|
||||
|
||||
// Set the camera
|
||||
g_Renderer.SetViewport(m_ViewCamera.GetViewPort());
|
||||
|
||||
@ -829,29 +825,21 @@ void CSceneRenderer::RenderSubmissions(
|
||||
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 @@ void CSceneRenderer::RenderSubmissions(
|
||||
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 @@ void CSceneRenderer::RenderSubmissions(
|
||||
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 @@ void CSceneRenderer::SubmitNonRecursive(CModel* model)
|
||||
}
|
||||
}
|
||||
|
||||
// Render the given scene
|
||||
void CSceneRenderer::RenderScene(
|
||||
void CSceneRenderer::PrepareScene(
|
||||
Renderer::Backend::IDeviceCommandContext* deviceCommandContext, Scene& scene)
|
||||
{
|
||||
m_CurrentScene = &scene;
|
||||
@ -1131,19 +1094,18 @@ void CSceneRenderer::RenderScene(
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void CSceneRenderer::RenderScene(
|
||||
m_CurrentCullGroup = CULL_REFRACTIONS;
|
||||
|
||||
CCamera refractionCamera;
|
||||
ComputeRefractionCamera(refractionCamera, waterScissor);
|
||||
ComputeRefractionCamera(refractionCamera, m_WaterScissor);
|
||||
|
||||
scene.EnumerateObjects(refractionCamera.GetFrustum(), this);
|
||||
}
|
||||
@ -1162,12 +1124,35 @@ void CSceneRenderer::RenderScene(
|
||||
m->waterManager.RenderWaves(deviceCommandContext, frustum);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_WaterScissor = CBoundingBoxAligned{};
|
||||
|
||||
m_CurrentCullGroup = -1;
|
||||
|
||||
RenderSubmissions(deviceCommandContext, waterScissor);
|
||||
PrepareSubmissions(deviceCommandContext, m_WaterScissor);
|
||||
}
|
||||
|
||||
m_CurrentScene = NULL;
|
||||
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);
|
||||
|
||||
// Render overlays that should appear on top of all other objects.
|
||||
m->overlayRenderer.RenderForegroundOverlays(deviceCommandContext, m_ViewCamera);
|
||||
|
||||
m_CurrentScene = nullptr;
|
||||
}
|
||||
|
||||
Scene& CSceneRenderer::GetScene()
|
||||
|
@ -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 @@ public:
|
||||
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 @@ protected:
|
||||
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 @@ protected:
|
||||
Scene* m_CurrentScene;
|
||||
int m_CurrentCullGroup;
|
||||
|
||||
CBoundingBoxAligned m_WaterScissor;
|
||||
|
||||
// current lighting setup
|
||||
CLightEnv* m_LightEnv;
|
||||
|
||||
|
@ -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 @@ void ActorViewer::Render()
|
||||
{
|
||||
// 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 @@ void ActorViewer::Render()
|
||||
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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user