Line data Source code
1 : /* Copyright (C) 2023 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 : #include "precompiled.h"
19 :
20 : #include "RenderingOptions.h"
21 :
22 : #include "graphics/TextureManager.h"
23 : #include "ps/CLogger.h"
24 : #include "ps/ConfigDB.h"
25 : #include "ps/CStr.h"
26 : #include "ps/CStrInternStatic.h"
27 : #include "ps/VideoMode.h"
28 : #include "renderer/backend/IDevice.h"
29 : #include "renderer/Renderer.h"
30 : #include "renderer/PostprocManager.h"
31 : #include "renderer/SceneRenderer.h"
32 : #include "renderer/ShadowMap.h"
33 : #include "renderer/WaterManager.h"
34 :
35 1 : CRenderingOptions g_RenderingOptions;
36 :
37 2 : class CRenderingOptions::ConfigHooks
38 : {
39 : public:
40 : std::vector<CConfigDBHook>::iterator begin() { return hooks.begin(); }
41 : std::vector<CConfigDBHook>::iterator end() { return hooks.end(); }
42 : template<typename T>
43 0 : void Setup(CStr8 name, T& variable)
44 : {
45 0 : hooks.emplace_back(g_ConfigDB.RegisterHookAndCall(name, [name, &variable]() { CFG_GET_VAL(name, variable); }));
46 0 : }
47 0 : void Setup(CStr8 name, std::function<void()> hook)
48 : {
49 0 : hooks.emplace_back(g_ConfigDB.RegisterHookAndCall(name, hook));
50 0 : }
51 1 : void clear() { hooks.clear(); }
52 : private:
53 : std::vector<CConfigDBHook> hooks;
54 : };
55 :
56 0 : RenderPath RenderPathEnum::FromString(const CStr8& name)
57 : {
58 0 : if (name == "default")
59 0 : return DEFAULT;
60 0 : if (name == "fixed")
61 0 : return FIXED;
62 0 : if (name == "shader")
63 0 : return SHADER;
64 :
65 0 : LOGWARNING("Unknown render path %s", name.c_str());
66 0 : return DEFAULT;
67 : }
68 :
69 0 : CStr8 RenderPathEnum::ToString(RenderPath path)
70 : {
71 0 : switch (path)
72 : {
73 0 : case RenderPath::DEFAULT:
74 0 : return "default";
75 0 : case RenderPath::FIXED:
76 0 : return "fixed";
77 0 : case RenderPath::SHADER:
78 0 : return "shader";
79 : }
80 0 : return "default"; // Silence warning about reaching end of non-void function.
81 : }
82 :
83 0 : RenderDebugMode RenderDebugModeEnum::FromString(const CStr8& name)
84 : {
85 0 : if (name == str_RENDER_DEBUG_MODE_NONE.c_str())
86 0 : return RenderDebugMode::NONE;
87 0 : if (name == str_RENDER_DEBUG_MODE_AO.c_str())
88 0 : return RenderDebugMode::AO;
89 0 : if (name == str_RENDER_DEBUG_MODE_ALPHA.c_str())
90 0 : return RenderDebugMode::ALPHA;
91 0 : if (name == str_RENDER_DEBUG_MODE_CUSTOM.c_str())
92 0 : return RenderDebugMode::CUSTOM;
93 :
94 0 : LOGWARNING("Unknown render debug mode %s", name.c_str());
95 0 : return RenderDebugMode::NONE;
96 : }
97 :
98 0 : CStrIntern RenderDebugModeEnum::ToString(RenderDebugMode mode)
99 : {
100 0 : switch (mode)
101 : {
102 0 : case RenderDebugMode::AO:
103 0 : return str_RENDER_DEBUG_MODE_AO;
104 0 : case RenderDebugMode::ALPHA:
105 0 : return str_RENDER_DEBUG_MODE_ALPHA;
106 0 : case RenderDebugMode::CUSTOM:
107 0 : return str_RENDER_DEBUG_MODE_CUSTOM;
108 0 : default:
109 0 : break;
110 : }
111 0 : return str_RENDER_DEBUG_MODE_NONE;
112 : }
113 :
114 1 : CRenderingOptions::CRenderingOptions() : m_ConfigHooks(new ConfigHooks())
115 : {
116 1 : m_RenderPath = RenderPath::DEFAULT;
117 1 : m_Shadows = false;
118 1 : m_WaterEffects = false;
119 1 : m_WaterFancyEffects = false;
120 1 : m_WaterRealDepth = false;
121 1 : m_WaterRefraction = false;
122 1 : m_WaterReflection = false;
123 1 : m_ShadowAlphaFix = false;
124 1 : m_ShadowPCF = false;
125 1 : m_Particles = false;
126 1 : m_Silhouettes = false;
127 1 : m_Fog = false;
128 1 : m_GPUSkinning = false;
129 1 : m_SmoothLOS = false;
130 1 : m_PostProc = false;
131 1 : m_DisplayFrustum = false;
132 1 : m_DisplayShadowsFrustum = false;
133 1 : m_RenderActors = true;
134 1 : }
135 :
136 2 : CRenderingOptions::~CRenderingOptions()
137 : {
138 1 : ClearHooks();
139 1 : }
140 :
141 0 : void CRenderingOptions::ReadConfigAndSetupHooks()
142 : {
143 0 : m_ConfigHooks->Setup("renderpath", [this]() {
144 0 : CStr renderPath;
145 0 : CFG_GET_VAL("renderpath", renderPath);
146 0 : SetRenderPath(RenderPathEnum::FromString(renderPath));
147 0 : });
148 :
149 0 : m_ConfigHooks->Setup("shadowquality", []() {
150 0 : if (CRenderer::IsInitialised())
151 0 : g_Renderer.GetSceneRenderer().GetShadowMap().RecreateTexture();
152 0 : });
153 0 : m_ConfigHooks->Setup("shadowscascadecount", []() {
154 0 : if (CRenderer::IsInitialised())
155 : {
156 0 : g_Renderer.GetSceneRenderer().GetShadowMap().RecreateTexture();
157 0 : g_Renderer.MakeShadersDirty();
158 : }
159 0 : });
160 0 : m_ConfigHooks->Setup("shadowscovermap", []() {
161 0 : if (CRenderer::IsInitialised())
162 : {
163 0 : g_Renderer.GetSceneRenderer().GetShadowMap().RecreateTexture();
164 0 : g_Renderer.MakeShadersDirty();
165 : }
166 0 : });
167 0 : m_ConfigHooks->Setup("shadowscutoffdistance", []() {
168 0 : if (CRenderer::IsInitialised())
169 0 : g_Renderer.GetSceneRenderer().GetShadowMap().RecreateTexture();
170 0 : });
171 :
172 0 : m_ConfigHooks->Setup("shadows", [this]() {
173 : bool enabled;
174 0 : CFG_GET_VAL("shadows", enabled);
175 0 : SetShadows(enabled);
176 0 : });
177 0 : m_ConfigHooks->Setup("shadowpcf", [this]() {
178 : bool enabled;
179 0 : CFG_GET_VAL("shadowpcf", enabled);
180 0 : SetShadowPCF(enabled);
181 0 : });
182 :
183 0 : m_ConfigHooks->Setup("postproc", m_PostProc);
184 :
185 0 : m_ConfigHooks->Setup("antialiasing", []() {
186 0 : if (CRenderer::IsInitialised())
187 0 : g_Renderer.GetPostprocManager().UpdateAntiAliasingTechnique();
188 0 : });
189 :
190 0 : m_ConfigHooks->Setup("sharpness", []() {
191 0 : if (CRenderer::IsInitialised())
192 0 : g_Renderer.GetPostprocManager().UpdateSharpnessFactor();
193 0 : });
194 :
195 0 : m_ConfigHooks->Setup("sharpening", []() {
196 0 : if (CRenderer::IsInitialised())
197 0 : g_Renderer.GetPostprocManager().UpdateSharpeningTechnique();
198 0 : });
199 :
200 0 : m_ConfigHooks->Setup("smoothlos", m_SmoothLOS);
201 :
202 0 : m_ConfigHooks->Setup("watereffects", [this]() {
203 : bool enabled;
204 0 : CFG_GET_VAL("watereffects", enabled);
205 0 : SetWaterEffects(enabled);
206 0 : if (CRenderer::IsInitialised())
207 0 : g_Renderer.GetSceneRenderer().GetWaterManager().RecreateOrLoadTexturesIfNeeded();
208 0 : });
209 0 : m_ConfigHooks->Setup("waterfancyeffects", [this]() {
210 : bool enabled;
211 0 : CFG_GET_VAL("waterfancyeffects", enabled);
212 0 : SetWaterFancyEffects(enabled);
213 0 : if (CRenderer::IsInitialised())
214 0 : g_Renderer.GetSceneRenderer().GetWaterManager().RecreateOrLoadTexturesIfNeeded();
215 0 : });
216 0 : m_ConfigHooks->Setup("waterrealdepth", m_WaterRealDepth);
217 0 : m_ConfigHooks->Setup("waterrefraction", [this]() {
218 : bool enabled;
219 0 : CFG_GET_VAL("waterrefraction", enabled);
220 0 : SetWaterRefraction(enabled);
221 0 : if (CRenderer::IsInitialised())
222 0 : g_Renderer.GetSceneRenderer().GetWaterManager().RecreateOrLoadTexturesIfNeeded();
223 0 : });
224 0 : m_ConfigHooks->Setup("waterreflection", [this]() {
225 : bool enabled;
226 0 : CFG_GET_VAL("waterreflection", enabled);
227 0 : SetWaterReflection(enabled);
228 0 : if (CRenderer::IsInitialised())
229 0 : g_Renderer.GetSceneRenderer().GetWaterManager().RecreateOrLoadTexturesIfNeeded();
230 0 : });
231 :
232 0 : m_ConfigHooks->Setup("particles", m_Particles);
233 0 : m_ConfigHooks->Setup("fog", [this]() {
234 : bool enabled;
235 0 : CFG_GET_VAL("fog", enabled);
236 0 : SetFog(enabled);
237 0 : });
238 0 : m_ConfigHooks->Setup("silhouettes", m_Silhouettes);
239 :
240 0 : m_ConfigHooks->Setup("gpuskinning", [this]() {
241 : bool enabled;
242 0 : CFG_GET_VAL("gpuskinning", enabled);
243 0 : if (enabled)
244 : {
245 0 : if (g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::GL_ARB)
246 0 : LOGWARNING("GPUSkinning has been disabled, because it is not supported with ARB shaders.");
247 0 : else if (g_VideoMode.GetBackendDevice()->GetBackend() == Renderer::Backend::Backend::VULKAN)
248 0 : LOGWARNING("GPUSkinning has been disabled, because it is not supported for Vulkan backend yet.");
249 : else
250 0 : m_GPUSkinning = true;
251 : }
252 0 : });
253 :
254 0 : m_ConfigHooks->Setup("renderactors", m_RenderActors);
255 :
256 0 : m_ConfigHooks->Setup("textures.quality", []() {
257 0 : if (CRenderer::IsInitialised())
258 0 : g_Renderer.GetTextureManager().OnQualityChanged();
259 0 : });
260 0 : m_ConfigHooks->Setup("textures.maxanisotropy", []() {
261 0 : if (CRenderer::IsInitialised())
262 0 : g_Renderer.GetTextureManager().OnQualityChanged();
263 0 : });
264 0 : }
265 :
266 1 : void CRenderingOptions::ClearHooks()
267 : {
268 1 : m_ConfigHooks->clear();
269 1 : }
270 :
271 0 : void CRenderingOptions::SetShadows(bool value)
272 : {
273 0 : m_Shadows = value;
274 0 : if (CRenderer::IsInitialised())
275 0 : g_Renderer.MakeShadersDirty();
276 0 : }
277 :
278 0 : void CRenderingOptions::SetShadowPCF(bool value)
279 : {
280 0 : m_ShadowPCF = value;
281 0 : if (CRenderer::IsInitialised())
282 0 : g_Renderer.MakeShadersDirty();
283 0 : }
284 :
285 0 : void CRenderingOptions::SetFog(bool value)
286 : {
287 0 : m_Fog = value;
288 0 : if (CRenderer::IsInitialised())
289 0 : g_Renderer.MakeShadersDirty();
290 0 : }
291 :
292 0 : void CRenderingOptions::SetRenderPath(RenderPath value)
293 : {
294 0 : m_RenderPath = value;
295 0 : if (CRenderer::IsInitialised())
296 0 : g_Renderer.SetRenderPath(m_RenderPath);
297 0 : }
298 :
299 0 : void CRenderingOptions::SetRenderDebugMode(RenderDebugMode value)
300 : {
301 0 : m_RenderDebugMode = value;
302 0 : if (CRenderer::IsInitialised())
303 0 : g_Renderer.MakeShadersDirty();
304 3 : }
|