1 /* Copyright (C) 2023 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef INCLUDED_POSTPROCMANAGER
19 #define INCLUDED_POSTPROCMANAGER
21 #include "graphics/ShaderTechniquePtr.h"
23 #include "renderer/backend/IFramebuffer.h"
24 #include "renderer/backend/IDeviceCommandContext.h"
25 #include "renderer/backend/IShaderProgram.h"
26 #include "renderer/backend/ITexture.h"
31 class CPostprocManager
34 CPostprocManager(Renderer::Backend::IDevice
* device
);
37 // Returns true if the the manager can be used.
38 bool IsEnabled() const;
40 // Create all buffers/textures in GPU memory and set default effect.
41 // @note Must be called before using in the renderer. May be called multiple times.
44 // Update the size of the screen
47 // Returns a list of xml files found in shaders/effects/postproc.
48 static std::vector
<CStrW
> GetPostEffects();
50 // Returns the name of the current effect.
51 const CStrW
& GetPostEffect() const
53 return m_PostProcEffect
;
56 // Sets the current effect.
57 void SetPostEffect(const CStrW
& name
);
59 // Triggers update of shaders and FBO if needed.
60 void UpdateAntiAliasingTechnique();
61 void UpdateSharpeningTechnique();
62 void UpdateSharpnessFactor();
64 void SetDepthBufferClipPlanes(float nearPlane
, float farPlane
);
66 // @note CPostprocManager must be initialized first
67 Renderer::Backend::IFramebuffer
* PrepareAndGetOutputFramebuffer();
69 // First renders blur textures, then calls ApplyEffect for each effect pass,
70 // ping-ponging the buffers at each step.
71 // @note CPostprocManager must be initialized first
73 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
);
75 // Blits the final postprocessed texture to the system framebuffer. The system
76 // framebuffer is selected as the output buffer. Should be called before
77 // silhouette rendering.
78 // @note CPostprocManager must be initialized first
79 void BlitOutputFramebuffer(
80 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
,
81 Renderer::Backend::IFramebuffer
* destination
);
83 // Returns true if we render main scene in the MSAA framebuffer.
84 bool IsMultisampleEnabled() const;
86 // Resolves the MSAA framebuffer into the regular one.
87 void ResolveMultisampleFramebuffer(
88 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
);
91 void CreateMultisampleBuffer();
92 void DestroyMultisampleBuffer();
94 Renderer::Backend::IDevice
* m_Device
= nullptr;
96 std::unique_ptr
<Renderer::Backend::IFramebuffer
> m_CaptureFramebuffer
;
98 // Two framebuffers, that we flip between at each shader pass.
99 std::unique_ptr
<Renderer::Backend::IFramebuffer
>
100 m_PingFramebuffer
, m_PongFramebuffer
;
102 // Unique color textures for the framebuffers.
103 std::unique_ptr
<Renderer::Backend::ITexture
> m_ColorTex1
, m_ColorTex2
;
105 // The framebuffers share a depth/stencil texture.
106 std::unique_ptr
<Renderer::Backend::ITexture
> m_DepthTex
;
107 float m_NearPlane
, m_FarPlane
;
109 // A framebuffer and textures x2 for each blur level we render.
114 std::unique_ptr
<Renderer::Backend::IFramebuffer
> framebuffer
;
115 std::unique_ptr
<Renderer::Backend::ITexture
> texture
;
117 std::array
<Step
, 2> steps
;
119 std::array
<BlurScale
, 3> m_BlurScales
;
121 // Indicates which of the ping-pong buffers is used for reading and which for drawing.
124 Renderer::Backend::IVertexInputLayout
* m_VertexInputLayout
= nullptr;
126 // The name and shader technique we are using. "default" name means no technique is used
127 // (i.e. while we do allocate the buffers, no effects are rendered).
128 CStrW m_PostProcEffect
;
129 CShaderTechniquePtr m_PostProcTech
;
132 CShaderTechniquePtr m_SharpTech
;
136 CShaderTechniquePtr m_AATech
;
137 bool m_UsingMultisampleBuffer
;
138 std::unique_ptr
<Renderer::Backend::IFramebuffer
> m_MultisampleFramebuffer
;
139 std::unique_ptr
<Renderer::Backend::ITexture
>
140 m_MultisampleColorTex
, m_MultisampleDepthTex
;
141 uint32_t m_MultisampleCount
;
142 std::vector
<uint32_t> m_AllowedSampleCounts
;
144 // The current screen dimensions in pixels.
145 int m_Width
, m_Height
;
147 // Is the postproc manager initialized? Buffers created? Default effect loaded?
148 bool m_IsInitialized
;
150 // Creates blur textures at various scales, for bloom, DOF, etc.
152 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
);
154 // High quality GPU image scaling to half size. outTex must have exactly half the size
155 // of inTex. inWidth and inHeight are the dimensions of inTex in texels.
156 void ApplyBlurDownscale2x(
157 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
,
158 Renderer::Backend::IFramebuffer
* framebuffer
,
159 Renderer::Backend::ITexture
* inTex
,
160 int inWidth
, int inHeight
);
162 // GPU-based Gaussian blur in two passes. inOutTex contains the input image and will be filled
163 // with the blurred image. tempTex must have the same size as inOutTex.
164 // inWidth and inHeight are the dimensions of the images in texels.
166 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
,
167 Renderer::Backend::ITexture
* inTex
,
168 Renderer::Backend::ITexture
* tempTex
,
169 Renderer::Backend::IFramebuffer
* tempFramebuffer
,
170 Renderer::Backend::IFramebuffer
* outFramebuffer
,
171 int inWidth
, int inHeight
);
173 // Applies a pass of a given effect to the entire current framebuffer. The shader is
174 // provided with a number of general-purpose variables, including the rendered screen so far,
175 // the depth buffer, a number of blur textures, the screen size, the zNear/zFar planes and
176 // some other parameters used by the optional bloom/HDR pass.
178 Renderer::Backend::IDeviceCommandContext
* deviceCommandContext
,
179 const CShaderTechniquePtr
& shaderTech
, int pass
);
181 // Delete all allocated buffers/textures from GPU memory.
184 // Delete existing buffers/textures and create them again, using a new screen size if needed.
185 // (the textures are also attached to the framebuffers)
186 void RecreateBuffers();
189 #endif // INCLUDED_POSTPROCMANAGER