From 976a78429e174ebfbc218546763467b5a23d2fb2 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 4 Aug 2016 17:16:49 +0200 Subject: [PATCH] Simplify post process buffer handling --- src/gl/renderer/gl_postprocess.cpp | 16 ++-- src/gl/renderer/gl_renderbuffers.cpp | 106 +++++++++++++-------------- src/gl/renderer/gl_renderbuffers.h | 31 +++++--- src/gl/renderer/gl_renderer.cpp | 2 +- src/gl/system/gl_wipe.cpp | 6 +- 5 files changed, 85 insertions(+), 76 deletions(-) diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index b934720b32..155321de41 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -150,7 +150,7 @@ void FGLRenderer::BloomScene() // Extract blooming pixels from scene texture: glBindFramebuffer(GL_FRAMEBUFFER, level0.VFramebuffer); glViewport(0, 0, level0.Width, level0.Height); - mBuffers->BindSceneTexture(0); + mBuffers->BindCurrentTexture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); mBloomExtractShader->Bind(); @@ -195,7 +195,7 @@ void FGLRenderer::BloomScene() mBlurShader->BlurVertical(mVBO, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height); // Add bloom back to scene texture: - mBuffers->BindSceneTextureFB(); + mBuffers->BindCurrentFB(); glViewport(mOutputViewport.left, mOutputViewport.top, mOutputViewport.width, mOutputViewport.height); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); @@ -249,13 +249,14 @@ void FGLRenderer::TonemapScene() glDisable(GL_BLEND); glDisable(GL_SCISSOR_TEST); - mBuffers->BindHudFB(); - mBuffers->BindSceneTexture(0); + mBuffers->BindNextFB(); + mBuffers->BindCurrentTexture(0); mTonemapShader->Bind(); mTonemapShader->SceneTexture.Set(0); mTonemapShader->Exposure.Set(mCameraExposure); mVBO->BindVBO(); mVBO->RenderScreenQuad(); + mBuffers->NextTexture(); if (blendEnabled) glEnable(GL_BLEND); @@ -320,8 +321,8 @@ void FGLRenderer::LensDistortScene() float f = MAX(f0, f2); float scale = 1.0f / f; - mBuffers->BindHudFB(); - mBuffers->BindSceneTexture(0); + mBuffers->BindNextFB(); + mBuffers->BindCurrentTexture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); mLensShader->Bind(); @@ -332,6 +333,7 @@ void FGLRenderer::LensDistortScene() mLensShader->CubicDistortionValue.Set(kcube); mVBO->BindVBO(); mVBO->RenderScreenQuad(); + mBuffers->NextTexture(); if (blendEnabled) glEnable(GL_BLEND); @@ -439,7 +441,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) mPresentShader->Contrast.Set(clamp(vid_contrast, 0.1f, 3.f)); mPresentShader->Brightness.Set(clamp(vid_brightness, -0.8f, 0.8f)); } - mBuffers->BindHudTexture(0); + mBuffers->BindCurrentTexture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mVBO->BindVBO(); diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index d9a8823cd3..490d73ed02 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -76,25 +76,26 @@ FGLRenderBuffers::FGLRenderBuffers() FGLRenderBuffers::~FGLRenderBuffers() { ClearScene(); - ClearHud(); + ClearPipeline(); ClearBloom(); } void FGLRenderBuffers::ClearScene() { DeleteFrameBuffer(mSceneFB); - DeleteFrameBuffer(mSceneTextureFB); DeleteRenderBuffer(mSceneMultisample); DeleteRenderBuffer(mSceneDepthStencil); DeleteRenderBuffer(mSceneDepth); DeleteRenderBuffer(mSceneStencil); - DeleteTexture(mSceneTexture); } -void FGLRenderBuffers::ClearHud() +void FGLRenderBuffers::ClearPipeline() { - DeleteFrameBuffer(mHudFB); - DeleteTexture(mHudTexture); + for (int i = 0; i < NumPipelineTextures; i++) + { + DeleteFrameBuffer(mPipelineFB[i]); + DeleteTexture(mPipelineTexture[i]); + } } void FGLRenderBuffers::ClearBloom() @@ -149,8 +150,8 @@ void FGLRenderBuffers::Setup(int width, int height) } else if (width > mWidth || height > mHeight) { + CreatePipeline(width, height); CreateScene(width, height, samples); - CreateHud(width, height); CreateBloom(width, height); mWidth = width; mHeight = height; @@ -173,9 +174,6 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples) { ClearScene(); - mSceneTexture = Create2DTexture(GetHdrFormat(), width, height); - mSceneTextureFB = CreateFrameBuffer(mSceneTexture); - if (samples > 1) mSceneMultisample = CreateRenderBuffer(GetHdrFormat(), samples, width, height); @@ -183,26 +181,30 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples) { mSceneDepth = CreateRenderBuffer(GL_DEPTH_COMPONENT24, samples, width, height); mSceneStencil = CreateRenderBuffer(GL_STENCIL_INDEX8, samples, width, height); - mSceneFB = CreateFrameBuffer(samples > 1 ? mSceneMultisample : mSceneTexture, mSceneDepth, mSceneStencil, samples > 1); + mSceneFB = CreateFrameBuffer(samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneDepth, mSceneStencil, samples > 1); } else { mSceneDepthStencil = CreateRenderBuffer(GL_DEPTH24_STENCIL8, samples, width, height); - mSceneFB = CreateFrameBuffer(samples > 1 ? mSceneMultisample : mSceneTexture, mSceneDepthStencil, samples > 1); + mSceneFB = CreateFrameBuffer(samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneDepthStencil, samples > 1); } } //========================================================================== // -// Creates the post-tonemapping-step buffers +// Creates the buffers needed for post processing steps // //========================================================================== -void FGLRenderBuffers::CreateHud(int width, int height) +void FGLRenderBuffers::CreatePipeline(int width, int height) { - ClearHud(); - mHudTexture = Create2DTexture(GetHdrFormat(), width, height); - mHudFB = CreateFrameBuffer(mHudTexture); + ClearPipeline(); + + for (int i = 0; i < NumPipelineTextures; i++) + { + mPipelineTexture[i] = Create2DTexture(GetHdrFormat(), width, height); + mPipelineFB[i] = CreateFrameBuffer(mPipelineTexture[i]); + } } //========================================================================== @@ -392,11 +394,13 @@ void FGLRenderBuffers::CheckFrameBufferCompleteness() void FGLRenderBuffers::BlitSceneToTexture() { + mCurrentPipelineTexture = 0; + if (mSamples <= 1) return; glBindFramebuffer(GL_READ_FRAMEBUFFER, mSceneFB); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mSceneTextureFB); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); @@ -415,27 +419,48 @@ void FGLRenderBuffers::BindSceneFB() //========================================================================== // -// Makes the scene texture frame buffer active (final 2D texture only) +// Binds the current scene/effect/hud texture to the specified texture unit // //========================================================================== -void FGLRenderBuffers::BindSceneTextureFB() +void FGLRenderBuffers::BindCurrentTexture(int index) { - glBindFramebuffer(GL_FRAMEBUFFER, mSceneTextureFB); + glActiveTexture(GL_TEXTURE0 + index); + glBindTexture(GL_TEXTURE_2D, mPipelineFB[mCurrentPipelineTexture]); } //========================================================================== // -// Makes the 2D/HUD frame buffer active +// Makes the frame buffer for the current texture active // //========================================================================== -void FGLRenderBuffers::BindHudFB() +void FGLRenderBuffers::BindCurrentFB() { - if (gl_tonemap != 0 || gl_lens) - glBindFramebuffer(GL_FRAMEBUFFER, mHudFB); - else - glBindFramebuffer(GL_FRAMEBUFFER, mSceneTextureFB); + glBindFramebuffer(GL_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); +} + +//========================================================================== +// +// Makes the frame buffer for the next texture active +// +//========================================================================== + +void FGLRenderBuffers::BindNextFB() +{ + int out = (mCurrentPipelineTexture + 1) % NumPipelineTextures; + glBindFramebuffer(GL_FRAMEBUFFER, mPipelineFB[out]); +} + +//========================================================================== +// +// Next pipeline texture now contains the output +// +//========================================================================== + +void FGLRenderBuffers::NextTexture() +{ + mCurrentPipelineTexture = (mCurrentPipelineTexture + 1) % NumPipelineTextures; } //========================================================================== @@ -449,33 +474,6 @@ void FGLRenderBuffers::BindOutputFB() glBindFramebuffer(GL_FRAMEBUFFER, mOutputFB); } -//========================================================================== -// -// Binds the scene frame buffer texture to the specified texture unit -// -//========================================================================== - -void FGLRenderBuffers::BindSceneTexture(int index) -{ - glActiveTexture(GL_TEXTURE0 + index); - glBindTexture(GL_TEXTURE_2D, mSceneTexture); -} - -//========================================================================== -// -// Binds the 2D/HUD frame buffer texture to the specified texture unit -// -//========================================================================== - -void FGLRenderBuffers::BindHudTexture(int index) -{ - glActiveTexture(GL_TEXTURE0 + index); - if (gl_tonemap != 0 || gl_lens) - glBindTexture(GL_TEXTURE_2D, mHudTexture); - else - glBindTexture(GL_TEXTURE_2D, mSceneTexture); -} - //========================================================================== // // Returns true if render buffers are supported and should be used diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 37bbdc2e50..8b3001c966 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -21,13 +21,16 @@ public: ~FGLRenderBuffers(); void Setup(int width, int height); - void BlitSceneToTexture(); + void BindSceneFB(); - void BindSceneTextureFB(); - void BindHudFB(); + void BlitSceneToTexture(); + + void BindCurrentTexture(int index); + void BindCurrentFB(); + void BindNextFB(); + void NextTexture(); + void BindOutputFB(); - void BindSceneTexture(int index); - void BindHudTexture(int index); enum { NumBloomLevels = 4 }; FGLBloomTextureLevel BloomLevels[NumBloomLevels]; @@ -39,10 +42,10 @@ public: private: void ClearScene(); - void ClearHud(); + void ClearPipeline(); void ClearBloom(); void CreateScene(int width, int height, int samples); - void CreateHud(int width, int height); + void CreatePipeline(int width, int height); void CreateBloom(int width, int height); GLuint Create2DTexture(GLuint format, int width, int height); GLuint CreateRenderBuffer(GLuint format, int width, int height); @@ -62,15 +65,21 @@ private: int mHeight = 0; int mSamples = 0; - GLuint mSceneTexture = 0; + static const int NumPipelineTextures = 2; + int mCurrentPipelineTexture = 0; + + // Buffers for the scene GLuint mSceneMultisample = 0; GLuint mSceneDepthStencil = 0; GLuint mSceneDepth = 0; GLuint mSceneStencil = 0; GLuint mSceneFB = 0; - GLuint mSceneTextureFB = 0; - GLuint mHudTexture = 0; - GLuint mHudFB = 0; + + // Effect/HUD buffers + GLuint mPipelineTexture[NumPipelineTextures]; + GLuint mPipelineFB[NumPipelineTextures]; + + // Back buffer frame buffer GLuint mOutputFB = 0; }; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 5fa52ec6b2..9105c08c7a 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -251,7 +251,7 @@ void FGLRenderer::Begin2D() if (mDrawingScene2D) mBuffers->BindSceneFB(); else - mBuffers->BindHudFB(); + mBuffers->BindCurrentFB(); } glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 781194ca45..0d1973131e 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -158,7 +158,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) if (FGLRenderBuffers::IsEnabled()) { - GLRenderer->mBuffers->BindHudFB(); + GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); } else @@ -193,7 +193,7 @@ void OpenGLFrameBuffer::WipeEndScreen() wipeendscreen->Bind(0, false, false); if (FGLRenderBuffers::IsEnabled()) - GLRenderer->mBuffers->BindHudFB(); + GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -232,7 +232,7 @@ bool OpenGLFrameBuffer::WipeDo(int ticks) if (FGLRenderBuffers::IsEnabled()) { - GLRenderer->mBuffers->BindHudFB(); + GLRenderer->mBuffers->BindCurrentFB(); const auto &bounds = GLRenderer->mScreenViewport; glViewport(bounds.left, bounds.top, bounds.width, bounds.height); }