Merge 'remotes/trunk'
[0ad.git] / source / renderer / PostprocManager.h
blobcf0256bb8545d8bd2dc44d32c221a6e586792a8e
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"
22 #include "ps/CStr.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"
28 #include <array>
29 #include <vector>
31 class CPostprocManager
33 public:
34 CPostprocManager(Renderer::Backend::IDevice* device);
35 ~CPostprocManager();
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.
42 void Initialize();
44 // Update the size of the screen
45 void Resize();
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
72 void ApplyPostproc(
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);
90 private:
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.
110 struct BlurScale
112 struct Step
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.
122 bool m_WhichBuffer;
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;
131 CStr m_SharpName;
132 CShaderTechniquePtr m_SharpTech;
133 float m_Sharpness;
135 CStr m_AAName;
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.
151 void ApplyBlur(
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.
165 void ApplyBlurGauss(
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.
177 void ApplyEffect(
178 Renderer::Backend::IDeviceCommandContext* deviceCommandContext,
179 const CShaderTechniquePtr& shaderTech, int pass);
181 // Delete all allocated buffers/textures from GPU memory.
182 void Cleanup();
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