Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
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.
8 : *
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.
13 : *
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/>.
16 : */
17 :
18 : #ifndef INCLUDED_POSTPROCMANAGER
19 : #define INCLUDED_POSTPROCMANAGER
20 :
21 : #include "graphics/ShaderTechniquePtr.h"
22 : #include "ps/CStr.h"
23 : #include "renderer/backend/gl/Framebuffer.h"
24 : #include "renderer/backend/gl/DeviceCommandContext.h"
25 : #include "renderer/backend/gl/Texture.h"
26 :
27 : #include <array>
28 : #include <vector>
29 :
30 : class CPostprocManager
31 : {
32 : public:
33 : CPostprocManager();
34 : ~CPostprocManager();
35 :
36 : // Returns true if the the manager can be used.
37 : bool IsEnabled() const;
38 :
39 : // Create all buffers/textures in GPU memory and set default effect.
40 : // @note Must be called before using in the renderer. May be called multiple times.
41 : void Initialize();
42 :
43 : // Update the size of the screen
44 : void Resize();
45 :
46 : // Returns a list of xml files found in shaders/effects/postproc.
47 : static std::vector<CStrW> GetPostEffects();
48 :
49 : // Returns the name of the current effect.
50 : const CStrW& GetPostEffect() const
51 : {
52 0 : return m_PostProcEffect;
53 : }
54 :
55 : // Sets the current effect.
56 : void SetPostEffect(const CStrW& name);
57 :
58 : // Triggers update of shaders and FBO if needed.
59 : void UpdateAntiAliasingTechnique();
60 : void UpdateSharpeningTechnique();
61 : void UpdateSharpnessFactor();
62 :
63 : void SetDepthBufferClipPlanes(float nearPlane, float farPlane);
64 :
65 : // Clears the two color buffers and depth buffer, and redirects all rendering
66 : // to our textures instead of directly to the system framebuffer.
67 : // @note CPostprocManager must be initialized first
68 : void CaptureRenderOutput(
69 : Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
70 :
71 : // First renders blur textures, then calls ApplyEffect for each effect pass,
72 : // ping-ponging the buffers at each step.
73 : // @note CPostprocManager must be initialized first
74 : void ApplyPostproc(
75 : Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
76 :
77 : // Blits the final postprocessed texture to the system framebuffer. The system framebuffer
78 : // is selected as the output buffer. Should be called before silhouette rendering.
79 : // @note CPostprocManager must be initialized first
80 : void ReleaseRenderOutput(Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
81 :
82 : // Returns true if we render main scene in the MSAA framebuffer.
83 : bool IsMultisampleEnabled() const;
84 :
85 : // Resolves the MSAA framebuffer into the regular one.
86 : void ResolveMultisampleFramebuffer(
87 : Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
88 :
89 : private:
90 : void CreateMultisampleBuffer();
91 : void DestroyMultisampleBuffer();
92 :
93 : // Two framebuffers, that we flip between at each shader pass.
94 : std::unique_ptr<Renderer::Backend::GL::CFramebuffer>
95 : m_CaptureFramebuffer, m_PingFramebuffer, m_PongFramebuffer;
96 :
97 : // Unique color textures for the framebuffers.
98 : std::unique_ptr<Renderer::Backend::GL::CTexture> m_ColorTex1, m_ColorTex2;
99 :
100 : // The framebuffers share a depth/stencil texture.
101 : std::unique_ptr<Renderer::Backend::GL::CTexture> m_DepthTex;
102 : float m_NearPlane, m_FarPlane;
103 :
104 : // A framebuffer and textures x2 for each blur level we render.
105 0 : struct BlurScale
106 : {
107 : struct Step
108 : {
109 : std::unique_ptr<Renderer::Backend::GL::CFramebuffer> framebuffer;
110 : std::unique_ptr<Renderer::Backend::GL::CTexture> texture;
111 : };
112 : std::array<Step, 2> steps;
113 : };
114 : std::array<BlurScale, 3> m_BlurScales;
115 :
116 : // Indicates which of the ping-pong buffers is used for reading and which for drawing.
117 : bool m_WhichBuffer;
118 :
119 : // The name and shader technique we are using. "default" name means no technique is used
120 : // (i.e. while we do allocate the buffers, no effects are rendered).
121 : CStrW m_PostProcEffect;
122 : CShaderTechniquePtr m_PostProcTech;
123 :
124 : CStr m_SharpName;
125 : CShaderTechniquePtr m_SharpTech;
126 : float m_Sharpness;
127 :
128 : CStr m_AAName;
129 : CShaderTechniquePtr m_AATech;
130 : bool m_UsingMultisampleBuffer;
131 : std::unique_ptr<Renderer::Backend::GL::CFramebuffer> m_MultisampleFramebuffer;
132 : std::unique_ptr<Renderer::Backend::GL::CTexture>
133 : m_MultisampleColorTex, m_MultisampleDepthTex;
134 : uint32_t m_MultisampleCount;
135 : std::vector<uint32_t> m_AllowedSampleCounts;
136 :
137 : // The current screen dimensions in pixels.
138 : int m_Width, m_Height;
139 :
140 : // Is the postproc manager initialized? Buffers created? Default effect loaded?
141 : bool m_IsInitialized;
142 :
143 : // Creates blur textures at various scales, for bloom, DOF, etc.
144 : void ApplyBlur(
145 : Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext);
146 :
147 : // High quality GPU image scaling to half size. outTex must have exactly half the size
148 : // of inTex. inWidth and inHeight are the dimensions of inTex in texels.
149 : void ApplyBlurDownscale2x(
150 : Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
151 : Renderer::Backend::GL::CFramebuffer* framebuffer,
152 : Renderer::Backend::GL::CTexture* inTex,
153 : int inWidth, int inHeight);
154 :
155 : // GPU-based Gaussian blur in two passes. inOutTex contains the input image and will be filled
156 : // with the blurred image. tempTex must have the same size as inOutTex.
157 : // inWidth and inHeight are the dimensions of the images in texels.
158 : void ApplyBlurGauss(
159 : Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
160 : Renderer::Backend::GL::CTexture* inTex,
161 : Renderer::Backend::GL::CTexture* tempTex,
162 : Renderer::Backend::GL::CFramebuffer* tempFramebuffer,
163 : Renderer::Backend::GL::CFramebuffer* outFramebuffer,
164 : int inWidth, int inHeight);
165 :
166 : // Applies a pass of a given effect to the entire current framebuffer. The shader is
167 : // provided with a number of general-purpose variables, including the rendered screen so far,
168 : // the depth buffer, a number of blur textures, the screen size, the zNear/zFar planes and
169 : // some other parameters used by the optional bloom/HDR pass.
170 : void ApplyEffect(
171 : Renderer::Backend::GL::CDeviceCommandContext* deviceCommandContext,
172 : const CShaderTechniquePtr& shaderTech, int pass);
173 :
174 : // Delete all allocated buffers/textures from GPU memory.
175 : void Cleanup();
176 :
177 : // Delete existing buffers/textures and create them again, using a new screen size if needed.
178 : // (the textures are also attached to the framebuffers)
179 : void RecreateBuffers();
180 : };
181 :
182 : #endif // INCLUDED_POSTPROCMANAGER
|