From 46e2e0b57cd0ede32f3b15a8e6b47ce082fe85d3 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 10 May 2018 14:43:34 +0200 Subject: [PATCH] - reduce the number of direct OpenGL calls done by the post processing steps --- src/gl/renderer/gl_postprocess.cpp | 135 ++++--------- src/gl/renderer/gl_renderbuffers.cpp | 276 ++++++++++++++------------- src/gl/renderer/gl_renderbuffers.h | 137 ++++++++----- src/gl/shaders/gl_blurshader.cpp | 16 +- src/gl/shaders/gl_blurshader.h | 8 +- 5 files changed, 282 insertions(+), 290 deletions(-) diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index a19e90ef1d..5b2a6f0d74 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -195,15 +195,10 @@ void FGLRenderer::AmbientOccludeScene() int randomTexture = clamp(gl_ssao - 1, 0, FGLRenderBuffers::NumAmbientRandomTextures - 1); // Calculate linear depth values - glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->LinearDepthFB); + mBuffers->LinearDepthFB.Bind(); glViewport(0, 0, mBuffers->AmbientWidth, mBuffers->AmbientHeight); mBuffers->BindSceneDepthTexture(0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mBuffers->BindSceneColorTexture(1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE0); mLinearDepthShader->Bind(); mLinearDepthShader->DepthTexture.Set(0); mLinearDepthShader->ColorTexture.Set(1); @@ -217,20 +212,10 @@ void FGLRenderer::AmbientOccludeScene() RenderScreenQuad(); // Apply ambient occlusion - glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB1); - glBindTexture(GL_TEXTURE_2D, mBuffers->LinearDepthTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientRandomTexture[randomTexture]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + mBuffers->AmbientFB1.Bind(); + mBuffers->LinearDepthTexture.Bind(0); + mBuffers->AmbientRandomTexture[randomTexture].Bind(1, GL_NEAREST, GL_REPEAT); mBuffers->BindSceneNormalTexture(2); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE0); mSSAOShader->Bind(); mSSAOShader->DepthTexture.Set(0); mSSAOShader->RandomTexture.Set(1); @@ -251,17 +236,15 @@ void FGLRenderer::AmbientOccludeScene() // Blur SSAO texture if (gl_ssao_debug < 2) { - glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB0); - glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mBuffers->AmbientFB0.Bind(); + mBuffers->AmbientTexture1.Bind(0); mDepthBlurShader->Bind(false); mDepthBlurShader->BlurSharpness[false].Set(blurSharpness); mDepthBlurShader->InvFullResolution[false].Set(1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight); RenderScreenQuad(); - glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB1); - glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture0); + mBuffers->AmbientFB1.Bind(); + mBuffers->AmbientTexture0.Bind(0); mDepthBlurShader->Bind(true); mDepthBlurShader->BlurSharpness[true].Set(blurSharpness); mDepthBlurShader->InvFullResolution[true].Set(1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight); @@ -280,10 +263,7 @@ void FGLRenderer::AmbientOccludeScene() glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); } - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + mBuffers->AmbientTexture1.Bind(0, GL_LINEAR); mBuffers->BindSceneFogTexture(1); mSSAOCombineShader->Bind(); mSSAOCombineShader->AODepthTexture.Set(0); @@ -313,36 +293,32 @@ void FGLRenderer::UpdateCameraExposure() savedState.SaveTextureBindings(2); // Extract light level from scene texture: - const auto &level0 = mBuffers->ExposureLevels[0]; - glBindFramebuffer(GL_FRAMEBUFFER, level0.Framebuffer); + auto &level0 = mBuffers->ExposureLevels[0]; + level0.Framebuffer.Bind(); glViewport(0, 0, level0.Width, level0.Height); - mBuffers->BindCurrentTexture(0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + mBuffers->BindCurrentTexture(0, GL_LINEAR); mExposureExtractShader->Bind(); mExposureExtractShader->SceneTexture.Set(0); mExposureExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height); mExposureExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height); RenderScreenQuad(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Find the average value: for (unsigned int i = 0; i + 1 < mBuffers->ExposureLevels.Size(); i++) { - const auto &level = mBuffers->ExposureLevels[i]; - const auto &next = mBuffers->ExposureLevels[i + 1]; + auto &level = mBuffers->ExposureLevels[i]; + auto &next = mBuffers->ExposureLevels[i + 1]; - glBindFramebuffer(GL_FRAMEBUFFER, next.Framebuffer); + next.Framebuffer.Bind(); glViewport(0, 0, next.Width, next.Height); - glBindTexture(GL_TEXTURE_2D, level.Texture); + level.Texture.Bind(0); mExposureAverageShader->Bind(); mExposureAverageShader->ExposureTexture.Set(0); RenderScreenQuad(); } // Combine average value with current camera exposure: - glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->ExposureFB); + mBuffers->ExposureFB.Bind(); glViewport(0, 0, 1, 1); if (!mBuffers->FirstExposureFrame) { @@ -354,8 +330,7 @@ void FGLRenderer::UpdateCameraExposure() { mBuffers->FirstExposureFrame = false; } - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureLevels.Last().Texture); + mBuffers->ExposureLevels.Last().Texture.Bind(0); mExposureCombineShader->Bind(); mExposureCombineShader->ExposureTexture.Set(0); mExposureCombineShader->ExposureBase.Set(gl_exposure_base); @@ -388,31 +363,25 @@ void FGLRenderer::BloomScene(int fixedcm) const float blurAmount = gl_bloom_amount; int sampleCount = gl_bloom_kernel_size; - const auto &level0 = mBuffers->BloomLevels[0]; + auto &level0 = mBuffers->BloomLevels[0]; // Extract blooming pixels from scene texture: - glBindFramebuffer(GL_FRAMEBUFFER, level0.VFramebuffer); + level0.VFramebuffer.Bind(); glViewport(0, 0, level0.Width, level0.Height); - mBuffers->BindCurrentTexture(0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture); - glActiveTexture(GL_TEXTURE0); + mBuffers->BindCurrentTexture(0, GL_LINEAR); + mBuffers->ExposureTexture.Bind(1); mBloomExtractShader->Bind(); mBloomExtractShader->SceneTexture.Set(0); mBloomExtractShader->ExposureTexture.Set(1); mBloomExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height); mBloomExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height); RenderScreenQuad(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Blur and downscale: for (int i = 0; i < FGLRenderBuffers::NumBloomLevels - 1; i++) { - const auto &level = mBuffers->BloomLevels[i]; - const auto &next = mBuffers->BloomLevels[i + 1]; + auto &level = mBuffers->BloomLevels[i]; + auto &next = mBuffers->BloomLevels[i + 1]; mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, next.VFramebuffer, next.Width, next.Height); } @@ -420,19 +389,16 @@ void FGLRenderer::BloomScene(int fixedcm) // Blur and upscale: for (int i = FGLRenderBuffers::NumBloomLevels - 1; i > 0; i--) { - const auto &level = mBuffers->BloomLevels[i]; - const auto &next = mBuffers->BloomLevels[i - 1]; + auto &level = mBuffers->BloomLevels[i]; + auto &next = mBuffers->BloomLevels[i - 1]; mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height); // Linear upscale: - glBindFramebuffer(GL_FRAMEBUFFER, next.VFramebuffer); + next.VFramebuffer.Bind(); glViewport(0, 0, next.Width, next.Height); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, level.VTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + level.VTexture.Bind(0, GL_LINEAR); mBloomCombineShader->Bind(); mBloomCombineShader->BloomTexture.Set(0); RenderScreenQuad(); @@ -447,10 +413,7 @@ void FGLRenderer::BloomScene(int fixedcm) glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, level0.VTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + level0.VTexture.Bind(0, GL_LINEAR); mBloomCombineShader->Bind(); mBloomCombineShader->BloomTexture.Set(0); RenderScreenQuad(); @@ -492,15 +455,13 @@ void FGLRenderer::BlurScene(float gameinfobluramount) const auto &level0 = mBuffers->BloomLevels[0]; // Grab the area we want to bloom: - glBindFramebuffer(GL_READ_FRAMEBUFFER, mBuffers->GetCurrentFB()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, level0.VFramebuffer); - glBlitFramebuffer(viewport.left, viewport.top, viewport.width, viewport.height, 0, 0, level0.Width, level0.Height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + mBuffers->BlitLinear(mBuffers->GetCurrentFB(), level0.VFramebuffer, viewport.left, viewport.top, viewport.width, viewport.height, 0, 0, level0.Width, level0.Height); // Blur and downscale: for (int i = 0; i < numLevels - 1; i++) { - const auto &level = mBuffers->BloomLevels[i]; - const auto &next = mBuffers->BloomLevels[i + 1]; + auto &level = mBuffers->BloomLevels[i]; + auto &next = mBuffers->BloomLevels[i + 1]; mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, next.VFramebuffer, next.Width, next.Height); } @@ -508,19 +469,16 @@ void FGLRenderer::BlurScene(float gameinfobluramount) // Blur and upscale: for (int i = numLevels - 1; i > 0; i--) { - const auto &level = mBuffers->BloomLevels[i]; - const auto &next = mBuffers->BloomLevels[i - 1]; + auto &level = mBuffers->BloomLevels[i]; + auto &next = mBuffers->BloomLevels[i - 1]; mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height); // Linear upscale: - glBindFramebuffer(GL_FRAMEBUFFER, next.VFramebuffer); + next.VFramebuffer.Bind(); glViewport(0, 0, next.Width, next.Height); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, level.VTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + level.VTexture.Bind(0, GL_LINEAR); mBloomCombineShader->Bind(); mBloomCombineShader->BloomTexture.Set(0); RenderScreenQuad(); @@ -530,9 +488,7 @@ void FGLRenderer::BlurScene(float gameinfobluramount) mBlurShader->BlurVertical(this, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height); // Copy blur back to scene texture: - glBindFramebuffer(GL_READ_FRAMEBUFFER, level0.VFramebuffer); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mBuffers->GetCurrentFB()); - glBlitFramebuffer(0, 0, level0.Width, level0.Height, viewport.left, viewport.top, viewport.width, viewport.height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + mBuffers->BlitLinear(level0.VFramebuffer, mBuffers->GetCurrentFB(), 0, 0, level0.Width, level0.Height, viewport.left, viewport.top, viewport.width, viewport.height); glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); @@ -576,10 +532,7 @@ void FGLRenderer::TonemapScene() } else { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture); - glActiveTexture(GL_TEXTURE0); - + mBuffers->ExposureTexture.Bind(1); mTonemapShader->ExposureTexture.Set(1); } @@ -699,9 +652,7 @@ void FGLRenderer::LensDistortScene() FGLPostProcessState savedState; 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); + mBuffers->BindCurrentTexture(0, GL_LINEAR); mLensShader->Bind(); mLensShader->InputTexture.Set(0); mLensShader->AspectRatio.Set(aspect); @@ -709,8 +660,6 @@ void FGLRenderer::LensDistortScene() mLensShader->LensDistortionCoefficient.Set(k); mLensShader->CubicDistortionValue.Set(kcube); RenderScreenQuad(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mBuffers->NextTexture(); FGLDebug::PopGroup(); @@ -747,15 +696,11 @@ void FGLRenderer::ApplyFXAA() mBuffers->NextTexture(); 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); + mBuffers->BindCurrentTexture(0, GL_LINEAR); mFXAAShader->Bind(); mFXAAShader->InputTexture.Set(0); mFXAAShader->ReciprocalResolution.Set(rpcRes); RenderScreenQuad(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mBuffers->NextTexture(); FGLDebug::PopGroup(); diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 6315719ab4..30ce0e04b0 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -45,18 +45,6 @@ CVAR(Bool, gl_renderbuffers, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI FGLRenderBuffers::FGLRenderBuffers() { - for (int i = 0; i < NumPipelineTextures; i++) - { - mPipelineTexture[i] = 0; - mPipelineFB[i] = 0; - } - - for (int i = 0; i < NumAmbientRandomTextures; i++) - { - AmbientRandomTexture[i] = 0; - } - - glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&mOutputFB); glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); } @@ -83,17 +71,17 @@ void FGLRenderBuffers::ClearScene() DeleteFrameBuffer(mSceneDataFB); if (mSceneUsesTextures) { - DeleteTexture(mSceneMultisample); - DeleteTexture(mSceneFog); - DeleteTexture(mSceneNormal); - DeleteTexture(mSceneDepthStencil); + DeleteTexture(mSceneMultisampleTex); + DeleteTexture(mSceneFogTex); + DeleteTexture(mSceneNormalTex); + DeleteTexture(mSceneDepthStencilTex); } else { - DeleteRenderBuffer(mSceneMultisample); - DeleteRenderBuffer(mSceneFog); - DeleteRenderBuffer(mSceneNormal); - DeleteRenderBuffer(mSceneDepthStencil); + DeleteRenderBuffer(mSceneMultisampleBuf); + DeleteRenderBuffer(mSceneFogBuf); + DeleteRenderBuffer(mSceneNormalBuf); + DeleteRenderBuffer(mSceneDepthStencilBuf); } } @@ -155,25 +143,25 @@ void FGLRenderBuffers::ClearAmbientOcclusion() DeleteTexture(AmbientRandomTexture[i]); } -void FGLRenderBuffers::DeleteTexture(GLuint &handle) +void FGLRenderBuffers::DeleteTexture(PPTexture &tex) { - if (handle != 0) - glDeleteTextures(1, &handle); - handle = 0; + if (tex.handle != 0) + glDeleteTextures(1, &tex.handle); + tex.handle = 0; } -void FGLRenderBuffers::DeleteRenderBuffer(GLuint &handle) +void FGLRenderBuffers::DeleteRenderBuffer(PPRenderBuffer &buf) { - if (handle != 0) - glDeleteRenderbuffers(1, &handle); - handle = 0; + if (buf.handle != 0) + glDeleteRenderbuffers(1, &buf.handle); + buf.handle = 0; } -void FGLRenderBuffers::DeleteFrameBuffer(GLuint &handle) +void FGLRenderBuffers::DeleteFrameBuffer(PPFrameBuffer &fb) { - if (handle != 0) - glDeleteFramebuffers(1, &handle); - handle = 0; + if (fb.handle != 0) + glDeleteFramebuffers(1, &fb.handle); + fb.handle = 0; } //========================================================================== @@ -188,7 +176,7 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei if (gl_renderbuffers != BuffersActive) { if (BuffersActive) - glBindFramebuffer(GL_FRAMEBUFFER, mOutputFB); + glBindFramebuffer(GL_FRAMEBUFFER, 0); BuffersActive = gl_renderbuffers; GLRenderer->mShaderManager->ResetFixedColormap(); } @@ -265,36 +253,36 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples, bool need { if (needsSceneTextures) { - mSceneMultisample = Create2DMultisampleTexture("SceneMultisample", GL_RGBA16F, width, height, samples, false); - mSceneDepthStencil = Create2DMultisampleTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples, false); - mSceneFog = Create2DMultisampleTexture("SceneFog", GL_RGBA8, width, height, samples, false); - mSceneNormal = Create2DMultisampleTexture("SceneNormal", GL_RGB10_A2, width, height, samples, false); - mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisample, 0, 0, mSceneDepthStencil, true); - mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisample, mSceneFog, mSceneNormal, mSceneDepthStencil, true); + mSceneMultisampleTex = Create2DMultisampleTexture("SceneMultisample", GL_RGBA16F, width, height, samples, false); + mSceneDepthStencilTex = Create2DMultisampleTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples, false); + mSceneFogTex = Create2DMultisampleTexture("SceneFog", GL_RGBA8, width, height, samples, false); + mSceneNormalTex = Create2DMultisampleTexture("SceneNormal", GL_RGB10_A2, width, height, samples, false); + mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisampleTex, {}, {}, mSceneDepthStencilTex, true); + mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisampleTex, mSceneFogTex, mSceneNormalTex, mSceneDepthStencilTex, true); } else { - mSceneMultisample = CreateRenderBuffer("SceneMultisample", GL_RGBA16F, width, height, samples); - mSceneDepthStencil = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples); - mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisample, mSceneDepthStencil, true); - mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisample, mSceneDepthStencil, true); + mSceneMultisampleBuf = CreateRenderBuffer("SceneMultisample", GL_RGBA16F, width, height, samples); + mSceneDepthStencilBuf = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples); + mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisampleBuf, mSceneDepthStencilBuf); + mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisampleBuf, mSceneDepthStencilBuf); } } else { if (needsSceneTextures) { - mSceneDepthStencil = Create2DTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); - mSceneFog = Create2DTexture("SceneFog", GL_RGBA8, width, height); - mSceneNormal = Create2DTexture("SceneNormal", GL_RGB10_A2, width, height); - mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], 0, 0, mSceneDepthStencil, false); - mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneFog, mSceneNormal, mSceneDepthStencil, false); + mSceneDepthStencilTex = Create2DTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); + mSceneFogTex = Create2DTexture("SceneFog", GL_RGBA8, width, height); + mSceneNormalTex = Create2DTexture("SceneNormal", GL_RGB10_A2, width, height); + mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], {}, {}, mSceneDepthStencilTex, false); + mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneFogTex, mSceneNormalTex, mSceneDepthStencilTex, false); } else { - mSceneDepthStencil = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); - mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mSceneDepthStencil, false); - mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneDepthStencil, false); + mSceneDepthStencilBuf = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); + mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mSceneDepthStencilBuf); + mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneDepthStencilBuf); } } } @@ -452,7 +440,7 @@ void FGLRenderBuffers::CreateEyeBuffers(int eye) while (mEyeFBs.Size() <= unsigned(eye)) { - GLuint texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight); + PPTexture texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight); mEyeTextures.Push(texture); mEyeFBs.Push(CreateFrameBuffer("EyeFB", texture)); } @@ -468,12 +456,12 @@ void FGLRenderBuffers::CreateEyeBuffers(int eye) // //========================================================================== -GLuint FGLRenderBuffers::Create2DTexture(const char *name, GLuint format, int width, int height, const void *data) +PPTexture FGLRenderBuffers::Create2DTexture(const char *name, GLuint format, int width, int height, const void *data) { - GLuint handle = 0; - glGenTextures(1, &handle); - glBindTexture(GL_TEXTURE_2D, handle); - FGLDebug::LabelObject(GL_TEXTURE, handle, name); + PPTexture tex; + glGenTextures(1, &tex.handle); + glBindTexture(GL_TEXTURE_2D, tex.handle); + FGLDebug::LabelObject(GL_TEXTURE, tex.handle, name); GLenum dataformat = 0, datatype = 0; switch (format) @@ -499,18 +487,18 @@ GLuint FGLRenderBuffers::Create2DTexture(const char *name, GLuint format, int wi glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - return handle; + return tex; } -GLuint FGLRenderBuffers::Create2DMultisampleTexture(const char *name, GLuint format, int width, int height, int samples, bool fixedSampleLocations) +PPTexture FGLRenderBuffers::Create2DMultisampleTexture(const char *name, GLuint format, int width, int height, int samples, bool fixedSampleLocations) { - GLuint handle = 0; - glGenTextures(1, &handle); - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, handle); - FGLDebug::LabelObject(GL_TEXTURE, handle, name); + PPTexture tex; + glGenTextures(1, &tex.handle); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex.handle); + FGLDebug::LabelObject(GL_TEXTURE, tex.handle, name); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, format, width, height, fixedSampleLocations); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); - return handle; + return tex; } //========================================================================== @@ -519,27 +507,27 @@ GLuint FGLRenderBuffers::Create2DMultisampleTexture(const char *name, GLuint for // //========================================================================== -GLuint FGLRenderBuffers::CreateRenderBuffer(const char *name, GLuint format, int width, int height) +PPRenderBuffer FGLRenderBuffers::CreateRenderBuffer(const char *name, GLuint format, int width, int height) { - GLuint handle = 0; - glGenRenderbuffers(1, &handle); - glBindRenderbuffer(GL_RENDERBUFFER, handle); - FGLDebug::LabelObject(GL_RENDERBUFFER, handle, name); + PPRenderBuffer buf; + glGenRenderbuffers(1, &buf.handle); + glBindRenderbuffer(GL_RENDERBUFFER, buf.handle); + FGLDebug::LabelObject(GL_RENDERBUFFER, buf.handle, name); glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); - return handle; + return buf; } -GLuint FGLRenderBuffers::CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples) +PPRenderBuffer FGLRenderBuffers::CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples) { if (samples <= 1) return CreateRenderBuffer(name, format, width, height); - GLuint handle = 0; - glGenRenderbuffers(1, &handle); - glBindRenderbuffer(GL_RENDERBUFFER, handle); - FGLDebug::LabelObject(GL_RENDERBUFFER, handle, name); + PPRenderBuffer buf; + glGenRenderbuffers(1, &buf.handle); + glBindRenderbuffer(GL_RENDERBUFFER, buf.handle); + FGLDebug::LabelObject(GL_RENDERBUFFER, buf.handle, name); glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, width, height); - return handle; + return buf; } //========================================================================== @@ -548,61 +536,71 @@ GLuint FGLRenderBuffers::CreateRenderBuffer(const char *name, GLuint format, int // //========================================================================== -GLuint FGLRenderBuffers::CreateFrameBuffer(const char *name, GLuint colorbuffer) +PPFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char *name, PPTexture colorbuffer) { - GLuint handle = 0; - glGenFramebuffers(1, &handle); - glBindFramebuffer(GL_FRAMEBUFFER, handle); - FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); + PPFrameBuffer fb; + glGenFramebuffers(1, &fb.handle); + glBindFramebuffer(GL_FRAMEBUFFER, fb.handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, fb.handle, name); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer.handle, 0); if (CheckFrameBufferCompleteness()) ClearFrameBuffer(false, false); - return handle; + return fb; } -GLuint FGLRenderBuffers::CreateFrameBuffer(const char *name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer) +PPFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char *name, PPTexture colorbuffer, PPRenderBuffer depthstencil) { - GLuint handle = 0; - glGenFramebuffers(1, &handle); - glBindFramebuffer(GL_FRAMEBUFFER, handle); - FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); - if (colorIsARenderBuffer) - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer); - else - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil); + PPFrameBuffer fb; + glGenFramebuffers(1, &fb.handle); + glBindFramebuffer(GL_FRAMEBUFFER, fb.handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, fb.handle, name); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer.handle, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil.handle); if (CheckFrameBufferCompleteness()) ClearFrameBuffer(true, true); - return handle; + return fb; } -GLuint FGLRenderBuffers::CreateFrameBuffer(const char *name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint colorbuffer2, GLuint depthstencil, bool multisample) +PPFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char *name, PPRenderBuffer colorbuffer, PPRenderBuffer depthstencil) { - GLuint handle = 0; - glGenFramebuffers(1, &handle); - glBindFramebuffer(GL_FRAMEBUFFER, handle); - FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); + PPFrameBuffer fb; + glGenFramebuffers(1, &fb.handle); + glBindFramebuffer(GL_FRAMEBUFFER, fb.handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, fb.handle, name); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer.handle); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil.handle); + if (CheckFrameBufferCompleteness()) + ClearFrameBuffer(true, true); + return fb; +} + +PPFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char *name, PPTexture colorbuffer0, PPTexture colorbuffer1, PPTexture colorbuffer2, PPTexture depthstencil, bool multisample) +{ + PPFrameBuffer fb; + glGenFramebuffers(1, &fb.handle); + glBindFramebuffer(GL_FRAMEBUFFER, fb.handle); + FGLDebug::LabelObject(GL_FRAMEBUFFER, fb.handle, name); if (multisample) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer0, 0); - if (colorbuffer1 != 0) - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer1, 0); - if (colorbuffer2 != 0) - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer2, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, depthstencil, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer0.handle, 0); + if (colorbuffer1.handle != 0) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer1.handle, 0); + if (colorbuffer2.handle != 0) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer2.handle, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, depthstencil.handle, 0); } else { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer0, 0); - if (colorbuffer1 != 0) - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, colorbuffer1, 0); - if (colorbuffer2 != 0) - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorbuffer2, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthstencil, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer0.handle, 0); + if (colorbuffer1.handle != 0) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, colorbuffer1.handle, 0); + if (colorbuffer2.handle != 0) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorbuffer2.handle, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthstencil.handle, 0); } if (CheckFrameBufferCompleteness()) ClearFrameBuffer(true, true); - return handle; + return fb; } //========================================================================== @@ -683,8 +681,8 @@ void FGLRenderBuffers::BlitSceneToTexture() if (mSamples <= 1) return; - glBindFramebuffer(GL_READ_FRAMEBUFFER, mSceneFB); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); + glBindFramebuffer(GL_READ_FRAMEBUFFER, mSceneFB.handle); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) @@ -697,6 +695,13 @@ void FGLRenderBuffers::BlitSceneToTexture() glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } +void FGLRenderBuffers::BlitLinear(PPFrameBuffer src, PPFrameBuffer dest, int sx0, int sy0, int sx1, int sy1, int dx0, int dy0, int dx1, int dy1) +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, src.handle); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dest.handle); + glBlitFramebuffer(sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1, GL_COLOR_BUFFER_BIT, GL_LINEAR); +} + //========================================================================== // // Eye textures and their frame buffers @@ -707,8 +712,8 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye) { CreateEyeBuffers(eye); - glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye]); + glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye].handle); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) @@ -725,13 +730,13 @@ void FGLRenderBuffers::BindEyeTexture(int eye, int texunit) { CreateEyeBuffers(eye); glActiveTexture(GL_TEXTURE0 + texunit); - glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye]); + glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye].handle); } void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer) { CreateEyeBuffers(eye); - glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]); + glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye].handle); } //========================================================================== @@ -743,14 +748,14 @@ void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer) void FGLRenderBuffers::BindShadowMapFB() { CreateShadowMap(); - glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapFB); + glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapFB.handle); } void FGLRenderBuffers::BindShadowMapTexture(int texunit) { CreateShadowMap(); glActiveTexture(GL_TEXTURE0 + texunit); - glBindTexture(GL_TEXTURE_2D, mShadowMapTexture); + glBindTexture(GL_TEXTURE_2D, mShadowMapTexture.handle); } void FGLRenderBuffers::ClearShadowMap() @@ -762,7 +767,7 @@ void FGLRenderBuffers::ClearShadowMap() void FGLRenderBuffers::CreateShadowMap() { - if (mShadowMapTexture != 0 && gl_shadowmap_quality == mCurrentShadowMapSize) + if (mShadowMapTexture.handle != 0 && gl_shadowmap_quality == mCurrentShadowMapSize) return; ClearShadowMap(); @@ -796,7 +801,7 @@ void FGLRenderBuffers::CreateShadowMap() void FGLRenderBuffers::BindSceneFB(bool sceneData) { - glBindFramebuffer(GL_FRAMEBUFFER, sceneData ? mSceneDataFB : mSceneFB); + glBindFramebuffer(GL_FRAMEBUFFER, sceneData ? mSceneDataFB.handle : mSceneFB.handle); } //========================================================================== @@ -809,9 +814,9 @@ void FGLRenderBuffers::BindSceneColorTexture(int index) { glActiveTexture(GL_TEXTURE0 + index); if (mSamples > 1) - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneMultisample); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneMultisampleTex.handle); else - glBindTexture(GL_TEXTURE_2D, mPipelineTexture[0]); + glBindTexture(GL_TEXTURE_2D, mPipelineTexture[0].handle); } //========================================================================== @@ -824,9 +829,9 @@ void FGLRenderBuffers::BindSceneFogTexture(int index) { glActiveTexture(GL_TEXTURE0 + index); if (mSamples > 1) - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneFog); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneFogTex.handle); else - glBindTexture(GL_TEXTURE_2D, mSceneFog); + glBindTexture(GL_TEXTURE_2D, mSceneFogTex.handle); } //========================================================================== @@ -839,9 +844,9 @@ void FGLRenderBuffers::BindSceneNormalTexture(int index) { glActiveTexture(GL_TEXTURE0 + index); if (mSamples > 1) - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneNormal); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneNormalTex.handle); else - glBindTexture(GL_TEXTURE_2D, mSceneNormal); + glBindTexture(GL_TEXTURE_2D, mSceneNormalTex.handle); } //========================================================================== @@ -854,9 +859,9 @@ void FGLRenderBuffers::BindSceneDepthTexture(int index) { glActiveTexture(GL_TEXTURE0 + index); if (mSamples > 1) - glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneDepthStencil); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneDepthStencilTex.handle); else - glBindTexture(GL_TEXTURE_2D, mSceneDepthStencil); + glBindTexture(GL_TEXTURE_2D, mSceneDepthStencilTex.handle); } //========================================================================== @@ -865,10 +870,9 @@ void FGLRenderBuffers::BindSceneDepthTexture(int index) // //========================================================================== -void FGLRenderBuffers::BindCurrentTexture(int index) +void FGLRenderBuffers::BindCurrentTexture(int index, int filter, int wrap) { - glActiveTexture(GL_TEXTURE0 + index); - glBindTexture(GL_TEXTURE_2D, mPipelineTexture[mCurrentPipelineTexture]); + mPipelineTexture[mCurrentPipelineTexture].Bind(index, filter, wrap); } //========================================================================== @@ -879,7 +883,7 @@ void FGLRenderBuffers::BindCurrentTexture(int index) void FGLRenderBuffers::BindCurrentFB() { - glBindFramebuffer(GL_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); + mPipelineFB[mCurrentPipelineTexture].Bind(); } //========================================================================== @@ -891,7 +895,7 @@ void FGLRenderBuffers::BindCurrentFB() void FGLRenderBuffers::BindNextFB() { int out = (mCurrentPipelineTexture + 1) % NumPipelineTextures; - glBindFramebuffer(GL_FRAMEBUFFER, mPipelineFB[out]); + mPipelineFB[out].Bind(); } //========================================================================== @@ -913,7 +917,7 @@ void FGLRenderBuffers::NextTexture() void FGLRenderBuffers::BindOutputFB() { - glBindFramebuffer(GL_FRAMEBUFFER, mOutputFB); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } //========================================================================== diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 84c0f63ece..1b2867e4bc 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -3,24 +3,65 @@ #include "gl/shaders/gl_shader.h" +class PPTexture +{ +public: + void Bind(int index, int filter = GL_NEAREST, int wrap = GL_CLAMP_TO_EDGE) + { + glActiveTexture(GL_TEXTURE0 + index); + glBindTexture(GL_TEXTURE_2D, handle); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + } + +private: + GLuint handle = 0; + + friend class FGLRenderBuffers; +}; + +class PPFrameBuffer +{ +public: + void Bind() + { + glBindFramebuffer(GL_FRAMEBUFFER, handle); + } + +private: + GLuint handle = 0; + + friend class FGLRenderBuffers; +}; + +class PPRenderBuffer +{ +private: + GLuint handle = 0; + + friend class FGLRenderBuffers; +}; + class FGLBloomTextureLevel { public: - GLuint VTexture = 0; - GLuint VFramebuffer = 0; - GLuint HTexture = 0; - GLuint HFramebuffer = 0; - GLuint Width = 0; - GLuint Height = 0; + PPTexture VTexture; + PPFrameBuffer VFramebuffer; + PPTexture HTexture; + PPFrameBuffer HFramebuffer; + int Width = 0; + int Height = 0; }; class FGLExposureTextureLevel { public: - GLuint Texture = 0; - GLuint Framebuffer = 0; - GLuint Width = 0; - GLuint Height = 0; + PPTexture Texture; + PPFrameBuffer Framebuffer; + int Width = 0; + int Height = 0; }; class FGLRenderBuffers @@ -38,12 +79,14 @@ public: void BindSceneDepthTexture(int index); void BlitSceneToTexture(); - void BindCurrentTexture(int index); + void BlitLinear(PPFrameBuffer src, PPFrameBuffer dest, int sx0, int sy0, int sx1, int sy1, int dx0, int dy0, int dx1, int dy1); + + void BindCurrentTexture(int index, int filter = GL_NEAREST, int wrap = GL_CLAMP_TO_EDGE); void BindCurrentFB(); void BindNextFB(); void NextTexture(); - int GetCurrentFB() const { return mPipelineFB[mCurrentPipelineTexture]; } + PPFrameBuffer GetCurrentFB() const { return mPipelineFB[mCurrentPipelineTexture]; } void BindOutputFB(); @@ -58,21 +101,21 @@ public: FGLBloomTextureLevel BloomLevels[NumBloomLevels]; TArray ExposureLevels; - GLuint ExposureTexture = 0; - GLuint ExposureFB = 0; + PPTexture ExposureTexture; + PPFrameBuffer ExposureFB; bool FirstExposureFrame = true; // Ambient occlusion buffers - GLuint LinearDepthTexture = 0; - GLuint LinearDepthFB = 0; - GLuint AmbientTexture0 = 0; - GLuint AmbientTexture1 = 0; - GLuint AmbientFB0 = 0; - GLuint AmbientFB1 = 0; + PPTexture LinearDepthTexture; + PPFrameBuffer LinearDepthFB; + PPTexture AmbientTexture0; + PPTexture AmbientTexture1; + PPFrameBuffer AmbientFB0; + PPFrameBuffer AmbientFB1; int AmbientWidth = 0; int AmbientHeight = 0; enum { NumAmbientRandomTextures = 3 }; - GLuint AmbientRandomTexture[NumAmbientRandomTextures]; + PPTexture AmbientRandomTexture[NumAmbientRandomTextures]; static bool IsEnabled(); @@ -98,18 +141,19 @@ private: void CreateShadowMap(); void CreateAmbientOcclusion(int width, int height); - GLuint Create2DTexture(const char *name, GLuint format, int width, int height, const void *data = nullptr); - GLuint Create2DMultisampleTexture(const char *name, GLuint format, int width, int height, int samples, bool fixedSampleLocations); - GLuint CreateRenderBuffer(const char *name, GLuint format, int width, int height); - GLuint CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples); - GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer); - GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); - GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint colorbuffer2, GLuint depthstencil, bool multisample); + PPTexture Create2DTexture(const char *name, GLuint format, int width, int height, const void *data = nullptr); + PPTexture Create2DMultisampleTexture(const char *name, GLuint format, int width, int height, int samples, bool fixedSampleLocations); + PPRenderBuffer CreateRenderBuffer(const char *name, GLuint format, int width, int height); + PPRenderBuffer CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples); + PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer); + PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer, PPRenderBuffer depthstencil); + PPFrameBuffer CreateFrameBuffer(const char *name, PPRenderBuffer colorbuffer, PPRenderBuffer depthstencil); + PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer0, PPTexture colorbuffer1, PPTexture colorbuffer2, PPTexture depthstencil, bool multisample); bool CheckFrameBufferCompleteness(); void ClearFrameBuffer(bool stencil, bool depth); - void DeleteTexture(GLuint &handle); - void DeleteRenderBuffer(GLuint &handle); - void DeleteFrameBuffer(GLuint &handle); + void DeleteTexture(PPTexture &handle); + void DeleteRenderBuffer(PPRenderBuffer &handle); + void DeleteFrameBuffer(PPFrameBuffer &handle); int mWidth = 0; int mHeight = 0; @@ -122,28 +166,29 @@ private: int mCurrentPipelineTexture = 0; // Buffers for the scene - GLuint mSceneMultisample = 0; - GLuint mSceneDepthStencil = 0; - GLuint mSceneFog = 0; - GLuint mSceneNormal = 0; - GLuint mSceneFB = 0; - GLuint mSceneDataFB = 0; + PPTexture mSceneMultisampleTex; + PPTexture mSceneDepthStencilTex; + PPTexture mSceneFogTex; + PPTexture mSceneNormalTex; + PPRenderBuffer mSceneMultisampleBuf; + PPRenderBuffer mSceneDepthStencilBuf; + PPRenderBuffer mSceneFogBuf; + PPRenderBuffer mSceneNormalBuf; + PPFrameBuffer mSceneFB; + PPFrameBuffer mSceneDataFB; bool mSceneUsesTextures = false; // Effect/HUD buffers - GLuint mPipelineTexture[NumPipelineTextures]; - GLuint mPipelineFB[NumPipelineTextures]; - - // Back buffer frame buffer - GLuint mOutputFB = 0; + PPTexture mPipelineTexture[NumPipelineTextures]; + PPFrameBuffer mPipelineFB[NumPipelineTextures]; // Eye buffers - TArray mEyeTextures; - TArray mEyeFBs; + TArray mEyeTextures; + TArray mEyeFBs; // Shadow map texture - GLuint mShadowMapTexture = 0; - GLuint mShadowMapFB = 0; + PPTexture mShadowMapTexture; + PPFrameBuffer mShadowMapFB; int mCurrentShadowMapSize = 0; static bool FailedCreate; diff --git a/src/gl/shaders/gl_blurshader.cpp b/src/gl/shaders/gl_blurshader.cpp index 970b0ebf34..623912087e 100644 --- a/src/gl/shaders/gl_blurshader.cpp +++ b/src/gl/shaders/gl_blurshader.cpp @@ -30,6 +30,7 @@ #include "gl/shaders/gl_blurshader.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/renderer/gl_renderer.h" +#include "gl/renderer/gl_renderbuffers.h" //========================================================================== // @@ -37,7 +38,7 @@ // //========================================================================== -void FBlurShader::BlurVertical(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height) +void FBlurShader::BlurVertical(FGLRenderer *renderer, float blurAmount, int sampleCount, PPTexture inputTexture, PPFrameBuffer outputFrameBuffer, int width, int height) { Blur(renderer, blurAmount, sampleCount, inputTexture, outputFrameBuffer, width, height, true); } @@ -48,7 +49,7 @@ void FBlurShader::BlurVertical(FGLRenderer *renderer, float blurAmount, int samp // //========================================================================== -void FBlurShader::BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height) +void FBlurShader::BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sampleCount, PPTexture inputTexture, PPFrameBuffer outputFrameBuffer, int width, int height) { Blur(renderer, blurAmount, sampleCount, inputTexture, outputFrameBuffer, width, height, false); } @@ -59,7 +60,7 @@ void FBlurShader::BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sa // //========================================================================== -void FBlurShader::Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height, bool vertical) +void FBlurShader::Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, PPTexture inputTexture, PPFrameBuffer outputFrameBuffer, int width, int height, bool vertical) { BlurSetup *setup = GetSetup(blurAmount, sampleCount); if (vertical) @@ -67,14 +68,9 @@ void FBlurShader::Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, else setup->HorizontalShader->Bind(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, inputTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + inputTexture.Bind(0); - glBindFramebuffer(GL_FRAMEBUFFER, outputFrameBuffer); + outputFrameBuffer.Bind(); glViewport(0, 0, width, height); glDisable(GL_BLEND); diff --git a/src/gl/shaders/gl_blurshader.h b/src/gl/shaders/gl_blurshader.h index 92ef5f115e..0ffd6a4e74 100644 --- a/src/gl/shaders/gl_blurshader.h +++ b/src/gl/shaders/gl_blurshader.h @@ -5,15 +5,17 @@ #include class FGLRenderer; +class PPFrameBuffer; +class PPTexture; class FBlurShader { public: - void BlurVertical(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height); - void BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height); + void BlurVertical(FGLRenderer *renderer, float blurAmount, int sampleCount, PPTexture inputTexture, PPFrameBuffer outputFrameBuffer, int width, int height); + void BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sampleCount, PPTexture inputTexture, PPFrameBuffer outputFrameBuffer, int width, int height); private: - void Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height, bool vertical); + void Blur(FGLRenderer *renderer, float blurAmount, int sampleCount, PPTexture inputTexture, PPFrameBuffer outputFrameBuffer, int width, int height, bool vertical); struct BlurSetup {