Merge 'remotes/trunk'
[0ad.git] / source / renderer / PostprocManager.cpp
blob242fa2bec4ee065cec2d07018739e9fde45490ff
1 /* Copyright (C) 2015 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 #include "precompiled.h"
20 #include "lib/ogl.h"
21 #include "maths/MathUtil.h"
23 #include "gui/GUIutil.h"
24 #include "lib/bits.h"
25 #include "ps/CLogger.h"
26 #include "ps/Filesystem.h"
27 #include "ps/Game.h"
28 #include "ps/World.h"
30 #include "graphics/GameView.h"
31 #include "graphics/LightEnv.h"
32 #include "graphics/ShaderManager.h"
34 #include "renderer/PostprocManager.h"
35 #include "renderer/Renderer.h"
37 #if !CONFIG2_GLES
39 CPostprocManager::CPostprocManager()
40 : m_IsInitialized(false), m_PingFbo(0), m_PongFbo(0), m_PostProcEffect(L"default"), m_ColorTex1(0), m_ColorTex2(0),
41 m_DepthTex(0), m_BloomFbo(0), m_BlurTex2a(0), m_BlurTex2b(0), m_BlurTex4a(0), m_BlurTex4b(0),
42 m_BlurTex8a(0), m_BlurTex8b(0), m_WhichBuffer(true)
46 CPostprocManager::~CPostprocManager()
48 Cleanup();
51 void CPostprocManager::Cleanup()
53 if (!m_IsInitialized) // Only cleanup if previously used
54 return;
56 if (m_PingFbo) pglDeleteFramebuffersEXT(1, &m_PingFbo);
57 if (m_PongFbo) pglDeleteFramebuffersEXT(1, &m_PongFbo);
58 if (m_BloomFbo) pglDeleteFramebuffersEXT(1, &m_BloomFbo);
59 m_PingFbo = m_PongFbo = m_BloomFbo = 0;
61 if (m_ColorTex1) glDeleteTextures(1, &m_ColorTex1);
62 if (m_ColorTex2) glDeleteTextures(1, &m_ColorTex2);
63 if (m_DepthTex) glDeleteTextures(1, &m_DepthTex);
64 m_ColorTex1 = m_ColorTex2 = m_DepthTex = 0;
66 if (m_BlurTex2a) glDeleteTextures(1, &m_BlurTex2a);
67 if (m_BlurTex2b) glDeleteTextures(1, &m_BlurTex2b);
68 if (m_BlurTex4a) glDeleteTextures(1, &m_BlurTex4a);
69 if (m_BlurTex4b) glDeleteTextures(1, &m_BlurTex4b);
70 if (m_BlurTex8a) glDeleteTextures(1, &m_BlurTex8a);
71 if (m_BlurTex8b) glDeleteTextures(1, &m_BlurTex8b);
72 m_BlurTex2a = m_BlurTex2b = m_BlurTex4a = m_BlurTex4b = m_BlurTex8a = m_BlurTex8b = 0;
75 void CPostprocManager::Initialize()
77 if (m_IsInitialized)
78 return;
80 // The screen size starts out correct and then must be updated with Resize()
81 m_Width = g_Renderer.GetWidth();
82 m_Height = g_Renderer.GetHeight();
84 RecreateBuffers();
85 m_IsInitialized = true;
87 // This might happen after the map is loaded and the effect chosen
88 SetPostEffect(m_PostProcEffect);
91 void CPostprocManager::Resize()
93 m_Width = g_Renderer.GetWidth();
94 m_Height = g_Renderer.GetHeight();
96 // If the buffers were intialized, recreate them to the new size.
97 if (m_IsInitialized)
98 RecreateBuffers();
101 void CPostprocManager::RecreateBuffers()
103 Cleanup();
105 #define GEN_BUFFER_RGBA(name, w, h) \
106 glGenTextures(1, (GLuint*)&name); \
107 glBindTexture(GL_TEXTURE_2D, name); \
108 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); \
109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \
110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \
111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); \
112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
114 // Two fullscreen ping-pong textures.
115 GEN_BUFFER_RGBA(m_ColorTex1, m_Width, m_Height);
116 GEN_BUFFER_RGBA(m_ColorTex2, m_Width, m_Height);
118 // Textures for several blur sizes. It would be possible to reuse
119 // m_BlurTex2b, thus avoiding the need for m_BlurTex4b and m_BlurTex8b, though given
120 // that these are fairly small it's probably not worth complicating the coordinates passed
121 // to the blur helper functions.
122 GEN_BUFFER_RGBA(m_BlurTex2a, m_Width / 2, m_Height / 2);
123 GEN_BUFFER_RGBA(m_BlurTex2b, m_Width / 2, m_Height / 2);
125 GEN_BUFFER_RGBA(m_BlurTex4a, m_Width / 4, m_Height / 4);
126 GEN_BUFFER_RGBA(m_BlurTex4b, m_Width / 4, m_Height / 4);
128 GEN_BUFFER_RGBA(m_BlurTex8a, m_Width / 8, m_Height / 8);
129 GEN_BUFFER_RGBA(m_BlurTex8b, m_Width / 8, m_Height / 8);
131 #undef GEN_BUFFER_RGBA
133 // Allocate the Depth/Stencil texture.
134 glGenTextures(1, (GLuint*)&m_DepthTex);
135 glBindTexture(GL_TEXTURE_2D, m_DepthTex);
137 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, m_Width, m_Height,
138 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0);
140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
143 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
146 glBindTexture(GL_TEXTURE_2D, 0);
148 // Set up the framebuffers with some initial textures.
150 pglGenFramebuffersEXT(1, &m_PingFbo);
151 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo);
153 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
154 GL_TEXTURE_2D, m_ColorTex1, 0);
156 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT,
157 GL_TEXTURE_2D, m_DepthTex, 0);
159 GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
160 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
162 LOGWARNING("Framebuffer object incomplete (A): 0x%04X", status);
165 pglGenFramebuffersEXT(1, &m_PongFbo);
166 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
168 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
169 GL_TEXTURE_2D, m_ColorTex2, 0);
171 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT,
172 GL_TEXTURE_2D, m_DepthTex, 0);
174 status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
175 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
177 LOGWARNING("Framebuffer object incomplete (B): 0x%04X", status);
180 pglGenFramebuffersEXT(1, &m_BloomFbo);
181 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo);
184 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
185 GL_TEXTURE_2D, m_BloomTex1, 0);
187 status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
188 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
190 LOGWARNING("Framebuffer object incomplete (B): 0x%04X", status);
194 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
198 void CPostprocManager::ApplyBlurDownscale2x(GLuint inTex, GLuint outTex, int inWidth, int inHeight)
200 // Bind inTex to framebuffer for rendering.
201 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo);
202 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, outTex, 0);
204 // Get bloom shader with instructions to simply copy texels.
205 CShaderDefines defines;
206 defines.Add(str_BLOOM_NOP, str_1);
207 CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom,
208 g_Renderer.GetSystemShaderDefines(), defines);
210 tech->BeginPass();
211 CShaderProgramPtr shader = tech->GetShader();
213 GLuint renderedTex = inTex;
215 // Cheat by creating high quality mipmaps for inTex, so the copying operation actually
216 // produces good scaling due to hardware filtering.
217 glBindTexture(GL_TEXTURE_2D, renderedTex);
218 pglGenerateMipmapEXT(GL_TEXTURE_2D);
219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
221 glBindTexture(GL_TEXTURE_2D, 0);
223 shader->BindTexture(str_renderedTex, renderedTex);
225 const SViewPort oldVp = g_Renderer.GetViewport();
226 const SViewPort vp = { 0, 0, inWidth / 2, inHeight / 2 };
227 g_Renderer.SetViewport(vp);
229 float quadVerts[] = {
230 1.0f, 1.0f,
231 -1.0f, 1.0f,
232 -1.0f, -1.0f,
234 -1.0f, -1.0f,
235 1.0f, -1.0f,
236 1.0f, 1.0f
238 float quadTex[] = {
239 1.0f, 1.0f,
240 0.0f, 1.0f,
241 0.0f, 0.0f,
243 0.0f, 0.0f,
244 1.0f, 0.0f,
245 1.0f, 1.0f
247 shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
248 shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
249 shader->AssertPointersBound();
250 glDrawArrays(GL_TRIANGLES, 0, 6);
252 g_Renderer.SetViewport(oldVp);
254 tech->EndPass();
257 void CPostprocManager::ApplyBlurGauss(GLuint inOutTex, GLuint tempTex, int inWidth, int inHeight)
259 // Set tempTex as our rendering target.
260 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo);
261 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tempTex, 0);
263 // Get bloom shader, for a horizontal Gaussian blur pass.
264 CShaderDefines defines2;
265 defines2.Add(str_BLOOM_PASS_H, str_1);
266 CShaderTechniquePtr tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom,
267 g_Renderer.GetSystemShaderDefines(), defines2);
269 tech->BeginPass();
270 CShaderProgramPtr shader = tech->GetShader();
271 shader->BindTexture(str_renderedTex, inOutTex);
272 shader->Uniform(str_texSize, inWidth, inHeight, 0.0f, 0.0f);
274 const SViewPort oldVp = g_Renderer.GetViewport();
275 const SViewPort vp = { 0, 0, inWidth, inHeight };
276 g_Renderer.SetViewport(vp);
278 float quadVerts[] = {
279 1.0f, 1.0f,
280 -1.0f, 1.0f,
281 -1.0f, -1.0f,
283 -1.0f, -1.0f,
284 1.0f, -1.0f,
285 1.0f, 1.0f
287 float quadTex[] = {
288 1.0f, 1.0f,
289 0.0f, 1.0f,
290 0.0f, 0.0f,
292 0.0f, 0.0f,
293 1.0f, 0.0f,
294 1.0f, 1.0f
296 shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
297 shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
298 shader->AssertPointersBound();
299 glDrawArrays(GL_TRIANGLES, 0, 6);
301 g_Renderer.SetViewport(oldVp);
303 tech->EndPass();
305 // Set result texture as our render target.
306 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo);
307 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, inOutTex, 0);
309 // Get bloom shader, for a vertical Gaussian blur pass.
310 CShaderDefines defines3;
311 defines3.Add(str_BLOOM_PASS_V, str_1);
312 tech = g_Renderer.GetShaderManager().LoadEffect(str_bloom,
313 g_Renderer.GetSystemShaderDefines(), defines3);
315 tech->BeginPass();
316 shader = tech->GetShader();
318 // Our input texture to the shader is the output of the horizontal pass.
319 shader->BindTexture(str_renderedTex, tempTex);
320 shader->Uniform(str_texSize, inWidth, inHeight, 0.0f, 0.0f);
322 g_Renderer.SetViewport(vp);
324 shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
325 shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
326 shader->AssertPointersBound();
327 glDrawArrays(GL_TRIANGLES, 0, 6);
329 g_Renderer.SetViewport(oldVp);
331 tech->EndPass();
334 void CPostprocManager::ApplyBlur()
336 glDisable(GL_BLEND);
338 GLint originalFBO;
339 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &originalFBO);
341 int width = m_Width, height = m_Height;
343 #define SCALE_AND_BLUR(tex1, tex2, temptex) \
344 ApplyBlurDownscale2x(tex1, tex2, width, height); \
345 width /= 2; \
346 height /= 2; \
347 ApplyBlurGauss(tex2, temptex, width, height);
349 // We do the same thing for each scale, incrementally adding more and more blur.
350 SCALE_AND_BLUR(m_WhichBuffer ? m_ColorTex1 : m_ColorTex2, m_BlurTex2a, m_BlurTex2b);
351 SCALE_AND_BLUR(m_BlurTex2a, m_BlurTex4a, m_BlurTex4b);
352 SCALE_AND_BLUR(m_BlurTex4a, m_BlurTex8a, m_BlurTex8b);
354 #undef SCALE_AND_BLUR
356 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, originalFBO);
360 void CPostprocManager::CaptureRenderOutput()
362 ENSURE(m_IsInitialized);
364 // clear both FBOs and leave m_PingFbo selected for rendering;
365 // m_WhichBuffer stays true at this point
366 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
367 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
369 GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
370 pglDrawBuffers(1, buffers);
372 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo);
373 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
374 pglDrawBuffers(1, buffers);
376 m_WhichBuffer = true;
380 void CPostprocManager::ReleaseRenderOutput()
382 ENSURE(m_IsInitialized);
384 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
385 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
387 // we blit to screen from the previous active buffer
388 if (m_WhichBuffer)
389 pglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_PingFbo);
390 else
391 pglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_PongFbo);
393 pglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
394 pglBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height,
395 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
396 pglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
398 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
401 void CPostprocManager::ApplyEffect(CShaderTechniquePtr &shaderTech1, int pass)
403 // select the other FBO for rendering
404 if (!m_WhichBuffer)
405 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo);
406 else
407 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
409 glDisable(GL_DEPTH_TEST);
410 glDepthMask(GL_FALSE);
412 shaderTech1->BeginPass(pass);
413 CShaderProgramPtr shader = shaderTech1->GetShader(pass);
415 shader->Bind();
417 // Use the textures from the current FBO as input to the shader.
418 // We also bind a bunch of other textures and parameters, but since
419 // this only happens once per frame the overhead is negligible.
420 if (m_WhichBuffer)
421 shader->BindTexture(str_renderedTex, m_ColorTex1);
422 else
423 shader->BindTexture(str_renderedTex, m_ColorTex2);
425 shader->BindTexture(str_depthTex, m_DepthTex);
427 shader->BindTexture(str_blurTex2, m_BlurTex2a);
428 shader->BindTexture(str_blurTex4, m_BlurTex4a);
429 shader->BindTexture(str_blurTex8, m_BlurTex8a);
431 shader->Uniform(str_width, m_Width);
432 shader->Uniform(str_height, m_Height);
433 shader->Uniform(str_zNear, g_Game->GetView()->GetNear());
434 shader->Uniform(str_zFar, g_Game->GetView()->GetFar());
436 shader->Uniform(str_brightness, g_LightEnv.m_Brightness);
437 shader->Uniform(str_hdr, g_LightEnv.m_Contrast);
438 shader->Uniform(str_saturation, g_LightEnv.m_Saturation);
439 shader->Uniform(str_bloom, g_LightEnv.m_Bloom);
441 float quadVerts[] = {
442 1.0f, 1.0f,
443 -1.0f, 1.0f,
444 -1.0f, -1.0f,
446 -1.0f, -1.0f,
447 1.0f, -1.0f,
448 1.0f, 1.0f
450 float quadTex[] = {
451 1.0f, 1.0f,
452 0.0f, 1.0f,
453 0.0f, 0.0f,
455 0.0f, 0.0f,
456 1.0f, 0.0f,
457 1.0f, 1.0f
459 shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 0, quadTex);
460 shader->VertexPointer(2, GL_FLOAT, 0, quadVerts);
461 shader->AssertPointersBound();
462 glDrawArrays(GL_TRIANGLES, 0, 6);
464 shader->Unbind();
466 shaderTech1->EndPass(pass);
468 glDepthMask(GL_TRUE);
469 glEnable(GL_DEPTH_TEST);
471 m_WhichBuffer = !m_WhichBuffer;
474 void CPostprocManager::ApplyPostproc()
476 ENSURE(m_IsInitialized);
478 // Don't do anything if we are using the default effect.
479 if (m_PostProcEffect == L"default")
480 return;
482 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
483 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
485 GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT };
486 pglDrawBuffers(1, buffers);
488 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo);
489 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
490 pglDrawBuffers(1, buffers);
492 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
493 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
495 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo);
496 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
498 // First render blur textures. Note that this only happens ONLY ONCE, before any effects are applied!
499 // (This may need to change depending on future usage, however that will have a fps hit)
500 ApplyBlur();
502 for (int pass = 0; pass < m_PostProcTech->GetNumPasses(); ++pass)
503 ApplyEffect(m_PostProcTech, pass);
505 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo);
506 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0);
508 pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo);
509 pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0);
513 // Generate list of available effect-sets
514 std::vector<CStrW> CPostprocManager::GetPostEffects()
516 std::vector<CStrW> effects;
518 const VfsPath path(L"shaders/effects/postproc/");
520 VfsPaths pathnames;
521 if (vfs::GetPathnames(g_VFS, path, 0, pathnames) < 0)
522 LOGERROR("Error finding Post effects in '%s'", path.string8());
524 for (const VfsPath& path : pathnames)
525 if (path.Extension() == L".xml")
526 effects.push_back(path.Basename().string());
528 // Add the default "null" effect to the list.
529 effects.push_back(L"default");
531 sort(effects.begin(), effects.end());
533 return effects;
536 void CPostprocManager::SetPostEffect(const CStrW& name)
538 if (m_IsInitialized)
540 if (name != L"default")
542 CStrW n = L"postproc/" + name;
543 m_PostProcTech = g_Renderer.GetShaderManager().LoadEffect(CStrIntern(n.ToUTF8()));
547 m_PostProcEffect = name;
550 #else
552 #warning TODO: implement PostprocManager for GLES
554 void ApplyBlurDownscale2x(GLuint UNUSED(inTex), GLuint UNUSED(outTex), int UNUSED(inWidth), int UNUSED(inHeight))
558 void CPostprocManager::ApplyBlurGauss(GLuint UNUSED(inOutTex), GLuint UNUSED(tempTex), int UNUSED(inWidth), int UNUSED(inHeight))
562 void CPostprocManager::ApplyEffect(CShaderTechniquePtr &UNUSED(shaderTech1), int UNUSED(pass))
566 CPostprocManager::CPostprocManager()
570 CPostprocManager::~CPostprocManager()
574 void CPostprocManager::Initialize()
578 void CPostprocManager::Resize()
582 void CPostprocManager::Cleanup()
586 void CPostprocManager::RecreateBuffers()
590 std::vector<CStrW> CPostprocManager::GetPostEffects()
592 return std::vector<CStrW>();
595 void CPostprocManager::SetPostEffect(const CStrW& UNUSED(name))
599 void CPostprocManager::CaptureRenderOutput()
603 void CPostprocManager::ApplyPostproc()
607 void CPostprocManager::ReleaseRenderOutput()
611 #endif