diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp index 2d2df20913..1ce9aa96bf 100644 --- a/source/graphics/LOSTexture.cpp +++ b/source/graphics/LOSTexture.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2013 Wildfire Games. +/* Copyright (C) 2014 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify diff --git a/source/graphics/LOSTexture.h b/source/graphics/LOSTexture.h index b5b35247af..5232024cea 100644 --- a/source/graphics/LOSTexture.h +++ b/source/graphics/LOSTexture.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2014 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify diff --git a/source/renderer/PostprocManager.cpp b/source/renderer/PostprocManager.cpp index c3eabd8d75..7b35abfd8f 100644 --- a/source/renderer/PostprocManager.cpp +++ b/source/renderer/PostprocManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2013 Wildfire Games. +/* Copyright (C) 2014 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -37,7 +37,7 @@ #if !CONFIG2_GLES CPostprocManager::CPostprocManager() - : m_IsInitialised(false), m_PingFbo(0), m_PongFbo(0), m_PostProcEffect(L"default"), m_ColourTex1(0), m_ColourTex2(0), + : m_IsInitialized(false), m_PingFbo(0), m_PongFbo(0), m_PostProcEffect(L"default"), m_ColourTex1(0), m_ColourTex2(0), m_DepthTex(0), m_BloomFbo(0), m_BlurTex2a(0), m_BlurTex2b(0), m_BlurTex4a(0), m_BlurTex4b(0), m_BlurTex8a(0), m_BlurTex8b(0), m_WhichBuffer(true) { @@ -45,53 +45,60 @@ CPostprocManager::CPostprocManager() CPostprocManager::~CPostprocManager() { - Cleanup(); -} - - -void CPostprocManager::Initialize() -{ - RecreateBuffers(); - m_IsInitialised = true; - SetPostEffect(L"default"); + if (m_IsInitialized) + Cleanup(); } void CPostprocManager::Cleanup() { - if (m_IsInitialised) - { - if (m_PingFbo) pglDeleteFramebuffersEXT(1, &m_PingFbo); - if (m_PongFbo) pglDeleteFramebuffersEXT(1, &m_PongFbo); - if (m_BloomFbo) pglDeleteFramebuffersEXT(1, &m_BloomFbo); - m_PingFbo = m_PongFbo = m_BloomFbo = 0; - - if (m_ColourTex1) glDeleteTextures(1, &m_ColourTex1); - if (m_ColourTex2) glDeleteTextures(1, &m_ColourTex2); - if (m_DepthTex) glDeleteTextures(1, &m_DepthTex); - m_ColourTex1 = m_ColourTex2 = m_DepthTex = 0; - - if (m_BlurTex2a) glDeleteTextures(1, &m_BlurTex2a); - if (m_BlurTex2b) glDeleteTextures(1, &m_BlurTex2b); - if (m_BlurTex4a) glDeleteTextures(1, &m_BlurTex4a); - if (m_BlurTex4b) glDeleteTextures(1, &m_BlurTex4b); - if (m_BlurTex8a) glDeleteTextures(1, &m_BlurTex8a); - if (m_BlurTex8b) glDeleteTextures(1, &m_BlurTex8b); - m_BlurTex2a = m_BlurTex2b = m_BlurTex4a = m_BlurTex4b = m_BlurTex8a = m_BlurTex8b = 0; - } + if (m_PingFbo) pglDeleteFramebuffersEXT(1, &m_PingFbo); + if (m_PongFbo) pglDeleteFramebuffersEXT(1, &m_PongFbo); + if (m_BloomFbo) pglDeleteFramebuffersEXT(1, &m_BloomFbo); + m_PingFbo = m_PongFbo = m_BloomFbo = 0; + + if (m_ColourTex1) glDeleteTextures(1, &m_ColourTex1); + if (m_ColourTex2) glDeleteTextures(1, &m_ColourTex2); + if (m_DepthTex) glDeleteTextures(1, &m_DepthTex); + m_ColourTex1 = m_ColourTex2 = m_DepthTex = 0; + + if (m_BlurTex2a) glDeleteTextures(1, &m_BlurTex2a); + if (m_BlurTex2b) glDeleteTextures(1, &m_BlurTex2b); + if (m_BlurTex4a) glDeleteTextures(1, &m_BlurTex4a); + if (m_BlurTex4b) glDeleteTextures(1, &m_BlurTex4b); + if (m_BlurTex8a) glDeleteTextures(1, &m_BlurTex8a); + if (m_BlurTex8b) glDeleteTextures(1, &m_BlurTex8b); + m_BlurTex2a = m_BlurTex2b = m_BlurTex4a = m_BlurTex4b = m_BlurTex8a = m_BlurTex8b = 0; +} + +void CPostprocManager::Initialize() +{ + // The screen size starts out correct and then must be updated with Resize() + m_Width = g_Renderer.GetWidth(); + m_Height = g_Renderer.GetHeight(); + + RecreateBuffers(); + m_IsInitialized = true; +} + +void CPostprocManager::Resize() +{ + m_Width = g_Renderer.GetWidth(); + m_Height = g_Renderer.GetHeight(); + + // If the buffers were intialized, recreate them to the new size. + if (m_IsInitialized) + RecreateBuffers(); } void CPostprocManager::RecreateBuffers() { - Cleanup(); - - m_Width = g_Renderer.GetWidth(); - m_Height = g_Renderer.GetHeight(); - + if (m_IsInitialized) // Only cleanup if previously used + Cleanup(); + #define GEN_BUFFER_RGBA(name, w, h) \ glGenTextures(1, (GLuint*)&name); \ glBindTexture(GL_TEXTURE_2D, name); \ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, \ - GL_UNSIGNED_BYTE, 0); \ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); \ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); \ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); \ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); \ @@ -119,10 +126,11 @@ void CPostprocManager::RecreateBuffers() // Allocate the Depth/Stencil texture. glGenTextures(1, (GLuint*)&m_DepthTex); glBindTexture(GL_TEXTURE_2D, m_DepthTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, m_Width, m_Height, - 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, - GL_NONE); + 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -134,8 +142,12 @@ void CPostprocManager::RecreateBuffers() pglGenFramebuffersEXT(1, &m_PingFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PingFbo); - pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_ColourTex1, 0); - pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0); + + pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, m_ColourTex1, 0); + + pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, + GL_TEXTURE_2D, m_DepthTex, 0); GLenum status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) @@ -145,8 +157,12 @@ void CPostprocManager::RecreateBuffers() pglGenFramebuffersEXT(1, &m_PongFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo); - pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_ColourTex2, 0); - pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0); + + pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, m_ColourTex2, 0); + + pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, + GL_TEXTURE_2D, m_DepthTex, 0); status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) @@ -156,13 +172,17 @@ void CPostprocManager::RecreateBuffers() pglGenFramebuffersEXT(1, &m_BloomFbo); pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_BloomFbo); - /*pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_BloomTex1, 0); + + /* + pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, m_BloomTex1, 0); status = pglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { LOGWARNING(L"Framebuffer object incomplete (B): 0x%04X", status); - }*/ + } + */ pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } @@ -332,6 +352,9 @@ void CPostprocManager::ApplyBlur() void CPostprocManager::CaptureRenderOutput() { + if (!m_IsInitialized) + Initialize(); + // clear both FBOs and leave m_PingFbo selected for rendering; // m_WhichBuffer stays true at this point pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo); @@ -350,6 +373,9 @@ void CPostprocManager::CaptureRenderOutput() void CPostprocManager::ReleaseRenderOutput() { + if (!m_IsInitialized) + Initialize(); + pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); @@ -370,9 +396,9 @@ void CPostprocManager::ReleaseRenderOutput() void CPostprocManager::LoadEffect(CStrW &name) { - if (!m_IsInitialised) - return; - + if (!m_IsInitialized) + Initialize(); + if (name != L"default") { CStrW n = L"postproc/" + name; @@ -458,14 +484,12 @@ void CPostprocManager::ApplyEffect(CShaderTechniquePtr &shaderTech1, int pass) void CPostprocManager::ApplyPostproc() { - if (!m_IsInitialised) - return; - + if (!m_IsInitialized) + Initialize(); + // Don't do anything if we are using the default effect. if (m_PostProcEffect == L"default") - { return; - } pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0); @@ -488,9 +512,7 @@ void CPostprocManager::ApplyPostproc() ApplyBlur(); for (int pass = 0; pass < m_PostProcTech->GetNumPasses(); ++pass) - { ApplyEffect(m_PostProcTech, pass); - } pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_PongFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthTex, 0); @@ -501,7 +523,7 @@ void CPostprocManager::ApplyPostproc() // Generate list of available effect-sets -std::vector CPostprocManager::GetPostEffects() const +std::vector CPostprocManager::GetPostEffects() { std::vector effects; @@ -509,10 +531,8 @@ std::vector CPostprocManager::GetPostEffects() const VfsPaths pathnames; if(vfs::GetPathnames(g_VFS, path, 0, pathnames) < 0) - { LOGERROR(L"Error finding Post effects in '%ls'", path.string().c_str()); - } - + for(size_t i = 0; i < pathnames.size(); i++) { if (pathnames[i].Extension() != L".xml") @@ -531,6 +551,9 @@ std::vector CPostprocManager::GetPostEffects() const void CPostprocManager::SetPostEffect(CStrW name) { + if (!m_IsInitialized) + Initialize(); + LoadEffect(name); } diff --git a/source/renderer/PostprocManager.h b/source/renderer/PostprocManager.h index 3c3d090ad8..31049c2e7a 100644 --- a/source/renderer/PostprocManager.h +++ b/source/renderer/PostprocManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2014 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -48,8 +48,8 @@ private: // The current screen dimensions in pixels. int m_Width, m_Height; - // Is the postproc manager initialised? Buffers created? Default effect loaded? - bool m_IsInitialised; + // Is the postproc manager initialized? Buffers created? Default effect loaded? + bool m_IsInitialized; // Creates blur textures at various scales, for bloom, DOF, etc. void ApplyBlur(); @@ -68,16 +68,19 @@ private: // the depth buffer, a number of blur textures, the screen size, the zNear/zFar planes and // some other parameters used by the optional bloom/HDR pass. void ApplyEffect(CShaderTechniquePtr &shaderTech1, int pass); - + + // Delete all allocated buffers/textures from GPU memory. + void Cleanup(); + public: CPostprocManager(); ~CPostprocManager(); // Create all buffers/textures in GPU memory and set default effect. void Initialize(); - - // Delete all allocated buffers/textures from GPU memory. - void Cleanup(); + + // Update the size of the screen + void Resize(); // Delete existing buffers/textures and create them again, using a new screen size if needed. // (the textures are also attached to the framebuffers) @@ -87,7 +90,7 @@ public: void LoadEffect(CStrW &name); // Returns a list of xml files found in shaders/effects/postproc. - std::vector GetPostEffects() const; + static std::vector GetPostEffects(); // Returns the name of the current effect. inline const CStrW& GetPostEffect() const diff --git a/source/renderer/Renderer.cpp b/source/renderer/Renderer.cpp index 81d6d18b39..23bed5d144 100644 --- a/source/renderer/Renderer.cpp +++ b/source/renderer/Renderer.cpp @@ -651,7 +651,7 @@ bool CRenderer::Open(int width, int height) } // resize renderer view -void CRenderer::Resize(int width,int height) +void CRenderer::Resize(int width, int height) { // need to recreate the shadow map object to resize the shadow texture m->shadow.RecreateTexture(); @@ -659,8 +659,7 @@ void CRenderer::Resize(int width,int height) m_Width = width; m_Height = height; - if (m_Options.m_Postproc) - m->postprocManager.RecreateBuffers(); + m->postprocManager.Resize(); } //////////////////////////////////////////////////////////////////////////////////////////