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