diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp index 386cc41fad..2d2df20913 100644 --- a/source/graphics/LOSTexture.cpp +++ b/source/graphics/LOSTexture.cpp @@ -58,23 +58,10 @@ static const size_t g_BlurSize = 7; static const size_t g_SubTextureAlignment = 4; CLOSTexture::CLOSTexture(CSimulation2& simulation) : - m_Simulation(simulation), m_Dirty(true), m_Texture(0), m_smoothFbo(0), m_MapSize(0), m_TextureSize(0), whichTex(true) + m_Simulation(simulation), m_Dirty(true), m_ShaderInitialized(false), m_Texture(0), m_smoothFbo(0), m_MapSize(0), m_TextureSize(0), whichTex(true) { if (CRenderer::IsInitialised() && g_Renderer.m_Options.m_SmoothLOS) - { - m_smoothShader = g_Renderer.GetShaderManager().LoadEffect(str_los_interp); - CShaderProgramPtr shader = m_smoothShader->GetShader(); - - if (m_smoothShader && shader) - { - pglGenFramebuffersEXT(1, &m_smoothFbo); - } - else - { - LOGERROR(L"Failed to load SmoothLOS shader, disabling."); - g_Renderer.m_Options.m_SmoothLOS = false; - } - } + CreateShader(); } CLOSTexture::~CLOSTexture() @@ -83,15 +70,38 @@ CLOSTexture::~CLOSTexture() DeleteTexture(); } +// Create the LOS texture engine. Should be ran only once. +bool CLOSTexture::CreateShader() +{ + m_smoothShader = g_Renderer.GetShaderManager().LoadEffect(str_los_interp); + CShaderProgramPtr shader = m_smoothShader->GetShader(); + + m_ShaderInitialized = m_smoothShader && shader; + + if (!m_ShaderInitialized) + { + LOGERROR(L"Failed to load SmoothLOS shader, disabling."); + g_Renderer.m_Options.m_SmoothLOS = false; + return false; + } + + pglGenFramebuffersEXT(1, &m_smoothFbo); + return true; +} + void CLOSTexture::DeleteTexture() { glDeleteTextures(1, &m_Texture); - if (CRenderer::IsInitialised() && g_Renderer.m_Options.m_SmoothLOS) - { + + if (m_TextureSmooth1) glDeleteTextures(1, &m_TextureSmooth1); + + if (m_TextureSmooth2) glDeleteTextures(1, &m_TextureSmooth2); - } + m_Texture = 0; + m_TextureSmooth1 = 0; + m_TextureSmooth2 = 0; } void CLOSTexture::MakeDirty() @@ -122,16 +132,28 @@ void CLOSTexture::InterpolateLOS() { if (CRenderer::IsInitialised() && !g_Renderer.m_Options.m_SmoothLOS) return; - + + if (!m_ShaderInitialized) + { + if (!CreateShader()) + return; + + // RecomputeTexture(0) will not cause the ConstructTexture to run. + // Force the textures to be created. + DeleteTexture(); + ConstructTexture(0); + m_Dirty = true; + } + if (m_Dirty) { RecomputeTexture(0); m_Dirty = false; } - + GLint originalFBO; glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &originalFBO); - + pglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_smoothFbo); pglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, whichTex ? m_TextureSmooth2 : m_TextureSmooth1, 0); diff --git a/source/graphics/LOSTexture.h b/source/graphics/LOSTexture.h index dd13f9e1b7..b5b35247af 100644 --- a/source/graphics/LOSTexture.h +++ b/source/graphics/LOSTexture.h @@ -78,6 +78,7 @@ public: private: void DeleteTexture(); + bool CreateShader(); void ConstructTexture(int unit); void RecomputeTexture(int unit); @@ -88,6 +89,8 @@ private: bool m_Dirty; + bool m_ShaderInitialized; + GLuint m_Texture; GLuint m_TextureSmooth1, m_TextureSmooth2;