- reduce the number of direct OpenGL calls done by the post processing steps

This commit is contained in:
Magnus Norddahl 2018-05-10 14:43:34 +02:00
parent ba9a340c1f
commit 46e2e0b57c
5 changed files with 282 additions and 290 deletions

View file

@ -195,15 +195,10 @@ void FGLRenderer::AmbientOccludeScene()
int randomTexture = clamp(gl_ssao - 1, 0, FGLRenderBuffers::NumAmbientRandomTextures - 1); int randomTexture = clamp(gl_ssao - 1, 0, FGLRenderBuffers::NumAmbientRandomTextures - 1);
// Calculate linear depth values // Calculate linear depth values
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->LinearDepthFB); mBuffers->LinearDepthFB.Bind();
glViewport(0, 0, mBuffers->AmbientWidth, mBuffers->AmbientHeight); glViewport(0, 0, mBuffers->AmbientWidth, mBuffers->AmbientHeight);
mBuffers->BindSceneDepthTexture(0); 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); 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->Bind();
mLinearDepthShader->DepthTexture.Set(0); mLinearDepthShader->DepthTexture.Set(0);
mLinearDepthShader->ColorTexture.Set(1); mLinearDepthShader->ColorTexture.Set(1);
@ -217,20 +212,10 @@ void FGLRenderer::AmbientOccludeScene()
RenderScreenQuad(); RenderScreenQuad();
// Apply ambient occlusion // Apply ambient occlusion
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB1); mBuffers->AmbientFB1.Bind();
glBindTexture(GL_TEXTURE_2D, mBuffers->LinearDepthTexture); mBuffers->LinearDepthTexture.Bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); mBuffers->AmbientRandomTexture[randomTexture].Bind(1, GL_NEAREST, GL_REPEAT);
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->BindSceneNormalTexture(2); 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->Bind();
mSSAOShader->DepthTexture.Set(0); mSSAOShader->DepthTexture.Set(0);
mSSAOShader->RandomTexture.Set(1); mSSAOShader->RandomTexture.Set(1);
@ -251,17 +236,15 @@ void FGLRenderer::AmbientOccludeScene()
// Blur SSAO texture // Blur SSAO texture
if (gl_ssao_debug < 2) if (gl_ssao_debug < 2)
{ {
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB0); mBuffers->AmbientFB0.Bind();
glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture1); mBuffers->AmbientTexture1.Bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
mDepthBlurShader->Bind(false); mDepthBlurShader->Bind(false);
mDepthBlurShader->BlurSharpness[false].Set(blurSharpness); mDepthBlurShader->BlurSharpness[false].Set(blurSharpness);
mDepthBlurShader->InvFullResolution[false].Set(1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight); mDepthBlurShader->InvFullResolution[false].Set(1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight);
RenderScreenQuad(); RenderScreenQuad();
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB1); mBuffers->AmbientFB1.Bind();
glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture0); mBuffers->AmbientTexture0.Bind(0);
mDepthBlurShader->Bind(true); mDepthBlurShader->Bind(true);
mDepthBlurShader->BlurSharpness[true].Set(blurSharpness); mDepthBlurShader->BlurSharpness[true].Set(blurSharpness);
mDepthBlurShader->InvFullResolution[true].Set(1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight); 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); glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
glActiveTexture(GL_TEXTURE0); mBuffers->AmbientTexture1.Bind(0, GL_LINEAR);
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->BindSceneFogTexture(1); mBuffers->BindSceneFogTexture(1);
mSSAOCombineShader->Bind(); mSSAOCombineShader->Bind();
mSSAOCombineShader->AODepthTexture.Set(0); mSSAOCombineShader->AODepthTexture.Set(0);
@ -313,36 +293,32 @@ void FGLRenderer::UpdateCameraExposure()
savedState.SaveTextureBindings(2); savedState.SaveTextureBindings(2);
// Extract light level from scene texture: // Extract light level from scene texture:
const auto &level0 = mBuffers->ExposureLevels[0]; auto &level0 = mBuffers->ExposureLevels[0];
glBindFramebuffer(GL_FRAMEBUFFER, level0.Framebuffer); level0.Framebuffer.Bind();
glViewport(0, 0, level0.Width, level0.Height); glViewport(0, 0, level0.Width, level0.Height);
mBuffers->BindCurrentTexture(0); mBuffers->BindCurrentTexture(0, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
mExposureExtractShader->Bind(); mExposureExtractShader->Bind();
mExposureExtractShader->SceneTexture.Set(0); mExposureExtractShader->SceneTexture.Set(0);
mExposureExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height); 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); mExposureExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
RenderScreenQuad(); 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: // Find the average value:
for (unsigned int i = 0; i + 1 < mBuffers->ExposureLevels.Size(); i++) for (unsigned int i = 0; i + 1 < mBuffers->ExposureLevels.Size(); i++)
{ {
const auto &level = mBuffers->ExposureLevels[i]; auto &level = mBuffers->ExposureLevels[i];
const auto &next = mBuffers->ExposureLevels[i + 1]; auto &next = mBuffers->ExposureLevels[i + 1];
glBindFramebuffer(GL_FRAMEBUFFER, next.Framebuffer); next.Framebuffer.Bind();
glViewport(0, 0, next.Width, next.Height); glViewport(0, 0, next.Width, next.Height);
glBindTexture(GL_TEXTURE_2D, level.Texture); level.Texture.Bind(0);
mExposureAverageShader->Bind(); mExposureAverageShader->Bind();
mExposureAverageShader->ExposureTexture.Set(0); mExposureAverageShader->ExposureTexture.Set(0);
RenderScreenQuad(); RenderScreenQuad();
} }
// Combine average value with current camera exposure: // Combine average value with current camera exposure:
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->ExposureFB); mBuffers->ExposureFB.Bind();
glViewport(0, 0, 1, 1); glViewport(0, 0, 1, 1);
if (!mBuffers->FirstExposureFrame) if (!mBuffers->FirstExposureFrame)
{ {
@ -354,8 +330,7 @@ void FGLRenderer::UpdateCameraExposure()
{ {
mBuffers->FirstExposureFrame = false; mBuffers->FirstExposureFrame = false;
} }
glActiveTexture(GL_TEXTURE0); mBuffers->ExposureLevels.Last().Texture.Bind(0);
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureLevels.Last().Texture);
mExposureCombineShader->Bind(); mExposureCombineShader->Bind();
mExposureCombineShader->ExposureTexture.Set(0); mExposureCombineShader->ExposureTexture.Set(0);
mExposureCombineShader->ExposureBase.Set(gl_exposure_base); mExposureCombineShader->ExposureBase.Set(gl_exposure_base);
@ -388,31 +363,25 @@ void FGLRenderer::BloomScene(int fixedcm)
const float blurAmount = gl_bloom_amount; const float blurAmount = gl_bloom_amount;
int sampleCount = gl_bloom_kernel_size; int sampleCount = gl_bloom_kernel_size;
const auto &level0 = mBuffers->BloomLevels[0]; auto &level0 = mBuffers->BloomLevels[0];
// Extract blooming pixels from scene texture: // Extract blooming pixels from scene texture:
glBindFramebuffer(GL_FRAMEBUFFER, level0.VFramebuffer); level0.VFramebuffer.Bind();
glViewport(0, 0, level0.Width, level0.Height); glViewport(0, 0, level0.Width, level0.Height);
mBuffers->BindCurrentTexture(0); mBuffers->BindCurrentTexture(0, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); mBuffers->ExposureTexture.Bind(1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture);
glActiveTexture(GL_TEXTURE0);
mBloomExtractShader->Bind(); mBloomExtractShader->Bind();
mBloomExtractShader->SceneTexture.Set(0); mBloomExtractShader->SceneTexture.Set(0);
mBloomExtractShader->ExposureTexture.Set(1); mBloomExtractShader->ExposureTexture.Set(1);
mBloomExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height); 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); mBloomExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
RenderScreenQuad(); RenderScreenQuad();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Blur and downscale: // Blur and downscale:
for (int i = 0; i < FGLRenderBuffers::NumBloomLevels - 1; i++) for (int i = 0; i < FGLRenderBuffers::NumBloomLevels - 1; i++)
{ {
const auto &level = mBuffers->BloomLevels[i]; auto &level = mBuffers->BloomLevels[i];
const auto &next = mBuffers->BloomLevels[i + 1]; auto &next = mBuffers->BloomLevels[i + 1];
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); 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); 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: // Blur and upscale:
for (int i = FGLRenderBuffers::NumBloomLevels - 1; i > 0; i--) for (int i = FGLRenderBuffers::NumBloomLevels - 1; i > 0; i--)
{ {
const auto &level = mBuffers->BloomLevels[i]; auto &level = mBuffers->BloomLevels[i];
const auto &next = mBuffers->BloomLevels[i - 1]; auto &next = mBuffers->BloomLevels[i - 1];
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); 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); mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height);
// Linear upscale: // Linear upscale:
glBindFramebuffer(GL_FRAMEBUFFER, next.VFramebuffer); next.VFramebuffer.Bind();
glViewport(0, 0, next.Width, next.Height); glViewport(0, 0, next.Width, next.Height);
glActiveTexture(GL_TEXTURE0); level.VTexture.Bind(0, GL_LINEAR);
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);
mBloomCombineShader->Bind(); mBloomCombineShader->Bind();
mBloomCombineShader->BloomTexture.Set(0); mBloomCombineShader->BloomTexture.Set(0);
RenderScreenQuad(); RenderScreenQuad();
@ -447,10 +413,7 @@ void FGLRenderer::BloomScene(int fixedcm)
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD); glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
glActiveTexture(GL_TEXTURE0); level0.VTexture.Bind(0, GL_LINEAR);
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);
mBloomCombineShader->Bind(); mBloomCombineShader->Bind();
mBloomCombineShader->BloomTexture.Set(0); mBloomCombineShader->BloomTexture.Set(0);
RenderScreenQuad(); RenderScreenQuad();
@ -492,15 +455,13 @@ void FGLRenderer::BlurScene(float gameinfobluramount)
const auto &level0 = mBuffers->BloomLevels[0]; const auto &level0 = mBuffers->BloomLevels[0];
// Grab the area we want to bloom: // Grab the area we want to bloom:
glBindFramebuffer(GL_READ_FRAMEBUFFER, mBuffers->GetCurrentFB()); mBuffers->BlitLinear(mBuffers->GetCurrentFB(), level0.VFramebuffer, viewport.left, viewport.top, viewport.width, viewport.height, 0, 0, level0.Width, level0.Height);
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);
// Blur and downscale: // Blur and downscale:
for (int i = 0; i < numLevels - 1; i++) for (int i = 0; i < numLevels - 1; i++)
{ {
const auto &level = mBuffers->BloomLevels[i]; auto &level = mBuffers->BloomLevels[i];
const auto &next = mBuffers->BloomLevels[i + 1]; auto &next = mBuffers->BloomLevels[i + 1];
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); 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); 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: // Blur and upscale:
for (int i = numLevels - 1; i > 0; i--) for (int i = numLevels - 1; i > 0; i--)
{ {
const auto &level = mBuffers->BloomLevels[i]; auto &level = mBuffers->BloomLevels[i];
const auto &next = mBuffers->BloomLevels[i - 1]; auto &next = mBuffers->BloomLevels[i - 1];
mBlurShader->BlurHorizontal(this, blurAmount, sampleCount, level.VTexture, level.HFramebuffer, level.Width, level.Height); 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); mBlurShader->BlurVertical(this, blurAmount, sampleCount, level.HTexture, level.VFramebuffer, level.Width, level.Height);
// Linear upscale: // Linear upscale:
glBindFramebuffer(GL_FRAMEBUFFER, next.VFramebuffer); next.VFramebuffer.Bind();
glViewport(0, 0, next.Width, next.Height); glViewport(0, 0, next.Width, next.Height);
glActiveTexture(GL_TEXTURE0); level.VTexture.Bind(0, GL_LINEAR);
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);
mBloomCombineShader->Bind(); mBloomCombineShader->Bind();
mBloomCombineShader->BloomTexture.Set(0); mBloomCombineShader->BloomTexture.Set(0);
RenderScreenQuad(); RenderScreenQuad();
@ -530,9 +488,7 @@ void FGLRenderer::BlurScene(float gameinfobluramount)
mBlurShader->BlurVertical(this, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height); mBlurShader->BlurVertical(this, blurAmount, sampleCount, level0.HTexture, level0.VFramebuffer, level0.Width, level0.Height);
// Copy blur back to scene texture: // Copy blur back to scene texture:
glBindFramebuffer(GL_READ_FRAMEBUFFER, level0.VFramebuffer); mBuffers->BlitLinear(level0.VFramebuffer, mBuffers->GetCurrentFB(), 0, 0, level0.Width, level0.Height, viewport.left, viewport.top, viewport.width, viewport.height);
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);
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
@ -576,10 +532,7 @@ void FGLRenderer::TonemapScene()
} }
else else
{ {
glActiveTexture(GL_TEXTURE1); mBuffers->ExposureTexture.Bind(1);
glBindTexture(GL_TEXTURE_2D, mBuffers->ExposureTexture);
glActiveTexture(GL_TEXTURE0);
mTonemapShader->ExposureTexture.Set(1); mTonemapShader->ExposureTexture.Set(1);
} }
@ -699,9 +652,7 @@ void FGLRenderer::LensDistortScene()
FGLPostProcessState savedState; FGLPostProcessState savedState;
mBuffers->BindNextFB(); mBuffers->BindNextFB();
mBuffers->BindCurrentTexture(0); mBuffers->BindCurrentTexture(0, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
mLensShader->Bind(); mLensShader->Bind();
mLensShader->InputTexture.Set(0); mLensShader->InputTexture.Set(0);
mLensShader->AspectRatio.Set(aspect); mLensShader->AspectRatio.Set(aspect);
@ -709,8 +660,6 @@ void FGLRenderer::LensDistortScene()
mLensShader->LensDistortionCoefficient.Set(k); mLensShader->LensDistortionCoefficient.Set(k);
mLensShader->CubicDistortionValue.Set(kcube); mLensShader->CubicDistortionValue.Set(kcube);
RenderScreenQuad(); RenderScreenQuad();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
mBuffers->NextTexture(); mBuffers->NextTexture();
FGLDebug::PopGroup(); FGLDebug::PopGroup();
@ -747,15 +696,11 @@ void FGLRenderer::ApplyFXAA()
mBuffers->NextTexture(); mBuffers->NextTexture();
mBuffers->BindNextFB(); mBuffers->BindNextFB();
mBuffers->BindCurrentTexture(0); mBuffers->BindCurrentTexture(0, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
mFXAAShader->Bind(); mFXAAShader->Bind();
mFXAAShader->InputTexture.Set(0); mFXAAShader->InputTexture.Set(0);
mFXAAShader->ReciprocalResolution.Set(rpcRes); mFXAAShader->ReciprocalResolution.Set(rpcRes);
RenderScreenQuad(); RenderScreenQuad();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
mBuffers->NextTexture(); mBuffers->NextTexture();
FGLDebug::PopGroup(); FGLDebug::PopGroup();

View file

@ -45,18 +45,6 @@ CVAR(Bool, gl_renderbuffers, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI
FGLRenderBuffers::FGLRenderBuffers() 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); glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
} }
@ -83,17 +71,17 @@ void FGLRenderBuffers::ClearScene()
DeleteFrameBuffer(mSceneDataFB); DeleteFrameBuffer(mSceneDataFB);
if (mSceneUsesTextures) if (mSceneUsesTextures)
{ {
DeleteTexture(mSceneMultisample); DeleteTexture(mSceneMultisampleTex);
DeleteTexture(mSceneFog); DeleteTexture(mSceneFogTex);
DeleteTexture(mSceneNormal); DeleteTexture(mSceneNormalTex);
DeleteTexture(mSceneDepthStencil); DeleteTexture(mSceneDepthStencilTex);
} }
else else
{ {
DeleteRenderBuffer(mSceneMultisample); DeleteRenderBuffer(mSceneMultisampleBuf);
DeleteRenderBuffer(mSceneFog); DeleteRenderBuffer(mSceneFogBuf);
DeleteRenderBuffer(mSceneNormal); DeleteRenderBuffer(mSceneNormalBuf);
DeleteRenderBuffer(mSceneDepthStencil); DeleteRenderBuffer(mSceneDepthStencilBuf);
} }
} }
@ -155,25 +143,25 @@ void FGLRenderBuffers::ClearAmbientOcclusion()
DeleteTexture(AmbientRandomTexture[i]); DeleteTexture(AmbientRandomTexture[i]);
} }
void FGLRenderBuffers::DeleteTexture(GLuint &handle) void FGLRenderBuffers::DeleteTexture(PPTexture &tex)
{ {
if (handle != 0) if (tex.handle != 0)
glDeleteTextures(1, &handle); glDeleteTextures(1, &tex.handle);
handle = 0; tex.handle = 0;
} }
void FGLRenderBuffers::DeleteRenderBuffer(GLuint &handle) void FGLRenderBuffers::DeleteRenderBuffer(PPRenderBuffer &buf)
{ {
if (handle != 0) if (buf.handle != 0)
glDeleteRenderbuffers(1, &handle); glDeleteRenderbuffers(1, &buf.handle);
handle = 0; buf.handle = 0;
} }
void FGLRenderBuffers::DeleteFrameBuffer(GLuint &handle) void FGLRenderBuffers::DeleteFrameBuffer(PPFrameBuffer &fb)
{ {
if (handle != 0) if (fb.handle != 0)
glDeleteFramebuffers(1, &handle); glDeleteFramebuffers(1, &fb.handle);
handle = 0; fb.handle = 0;
} }
//========================================================================== //==========================================================================
@ -188,7 +176,7 @@ bool FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHei
if (gl_renderbuffers != BuffersActive) if (gl_renderbuffers != BuffersActive)
{ {
if (BuffersActive) if (BuffersActive)
glBindFramebuffer(GL_FRAMEBUFFER, mOutputFB); glBindFramebuffer(GL_FRAMEBUFFER, 0);
BuffersActive = gl_renderbuffers; BuffersActive = gl_renderbuffers;
GLRenderer->mShaderManager->ResetFixedColormap(); GLRenderer->mShaderManager->ResetFixedColormap();
} }
@ -265,36 +253,36 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples, bool need
{ {
if (needsSceneTextures) if (needsSceneTextures)
{ {
mSceneMultisample = Create2DMultisampleTexture("SceneMultisample", GL_RGBA16F, width, height, samples, false); mSceneMultisampleTex = Create2DMultisampleTexture("SceneMultisample", GL_RGBA16F, width, height, samples, false);
mSceneDepthStencil = Create2DMultisampleTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples, false); mSceneDepthStencilTex = Create2DMultisampleTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples, false);
mSceneFog = Create2DMultisampleTexture("SceneFog", GL_RGBA8, width, height, samples, false); mSceneFogTex = Create2DMultisampleTexture("SceneFog", GL_RGBA8, width, height, samples, false);
mSceneNormal = Create2DMultisampleTexture("SceneNormal", GL_RGB10_A2, width, height, samples, false); mSceneNormalTex = Create2DMultisampleTexture("SceneNormal", GL_RGB10_A2, width, height, samples, false);
mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisample, 0, 0, mSceneDepthStencil, true); mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisampleTex, {}, {}, mSceneDepthStencilTex, true);
mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisample, mSceneFog, mSceneNormal, mSceneDepthStencil, true); mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisampleTex, mSceneFogTex, mSceneNormalTex, mSceneDepthStencilTex, true);
} }
else else
{ {
mSceneMultisample = CreateRenderBuffer("SceneMultisample", GL_RGBA16F, width, height, samples); mSceneMultisampleBuf = CreateRenderBuffer("SceneMultisample", GL_RGBA16F, width, height, samples);
mSceneDepthStencil = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples); mSceneDepthStencilBuf = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples);
mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisample, mSceneDepthStencil, true); mSceneFB = CreateFrameBuffer("SceneFB", mSceneMultisampleBuf, mSceneDepthStencilBuf);
mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisample, mSceneDepthStencil, true); mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mSceneMultisampleBuf, mSceneDepthStencilBuf);
} }
} }
else else
{ {
if (needsSceneTextures) if (needsSceneTextures)
{ {
mSceneDepthStencil = Create2DTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); mSceneDepthStencilTex = Create2DTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height);
mSceneFog = Create2DTexture("SceneFog", GL_RGBA8, width, height); mSceneFogTex = Create2DTexture("SceneFog", GL_RGBA8, width, height);
mSceneNormal = Create2DTexture("SceneNormal", GL_RGB10_A2, width, height); mSceneNormalTex = Create2DTexture("SceneNormal", GL_RGB10_A2, width, height);
mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], 0, 0, mSceneDepthStencil, false); mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], {}, {}, mSceneDepthStencilTex, false);
mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneFog, mSceneNormal, mSceneDepthStencil, false); mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneFogTex, mSceneNormalTex, mSceneDepthStencilTex, false);
} }
else else
{ {
mSceneDepthStencil = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height); mSceneDepthStencilBuf = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height);
mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mSceneDepthStencil, false); mSceneFB = CreateFrameBuffer("SceneFB", mPipelineTexture[0], mSceneDepthStencilBuf);
mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneDepthStencil, false); mSceneDataFB = CreateFrameBuffer("SceneGBufferFB", mPipelineTexture[0], mSceneDepthStencilBuf);
} }
} }
} }
@ -452,7 +440,7 @@ void FGLRenderBuffers::CreateEyeBuffers(int eye)
while (mEyeFBs.Size() <= unsigned(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); mEyeTextures.Push(texture);
mEyeFBs.Push(CreateFrameBuffer("EyeFB", 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; PPTexture tex;
glGenTextures(1, &handle); glGenTextures(1, &tex.handle);
glBindTexture(GL_TEXTURE_2D, handle); glBindTexture(GL_TEXTURE_2D, tex.handle);
FGLDebug::LabelObject(GL_TEXTURE, handle, name); FGLDebug::LabelObject(GL_TEXTURE, tex.handle, name);
GLenum dataformat = 0, datatype = 0; GLenum dataformat = 0, datatype = 0;
switch (format) 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_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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; PPTexture tex;
glGenTextures(1, &handle); glGenTextures(1, &tex.handle);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, handle); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex.handle);
FGLDebug::LabelObject(GL_TEXTURE, handle, name); FGLDebug::LabelObject(GL_TEXTURE, tex.handle, name);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, format, width, height, fixedSampleLocations); glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, format, width, height, fixedSampleLocations);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); 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; PPRenderBuffer buf;
glGenRenderbuffers(1, &handle); glGenRenderbuffers(1, &buf.handle);
glBindRenderbuffer(GL_RENDERBUFFER, handle); glBindRenderbuffer(GL_RENDERBUFFER, buf.handle);
FGLDebug::LabelObject(GL_RENDERBUFFER, handle, name); FGLDebug::LabelObject(GL_RENDERBUFFER, buf.handle, name);
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height); 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) if (samples <= 1)
return CreateRenderBuffer(name, format, width, height); return CreateRenderBuffer(name, format, width, height);
GLuint handle = 0; PPRenderBuffer buf;
glGenRenderbuffers(1, &handle); glGenRenderbuffers(1, &buf.handle);
glBindRenderbuffer(GL_RENDERBUFFER, handle); glBindRenderbuffer(GL_RENDERBUFFER, buf.handle);
FGLDebug::LabelObject(GL_RENDERBUFFER, handle, name); FGLDebug::LabelObject(GL_RENDERBUFFER, buf.handle, name);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, width, height); 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; PPFrameBuffer fb;
glGenFramebuffers(1, &handle); glGenFramebuffers(1, &fb.handle);
glBindFramebuffer(GL_FRAMEBUFFER, handle); glBindFramebuffer(GL_FRAMEBUFFER, fb.handle);
FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); FGLDebug::LabelObject(GL_FRAMEBUFFER, fb.handle, name);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer.handle, 0);
if (CheckFrameBufferCompleteness()) if (CheckFrameBufferCompleteness())
ClearFrameBuffer(false, false); 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; PPFrameBuffer fb;
glGenFramebuffers(1, &handle); glGenFramebuffers(1, &fb.handle);
glBindFramebuffer(GL_FRAMEBUFFER, handle); glBindFramebuffer(GL_FRAMEBUFFER, fb.handle);
FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); FGLDebug::LabelObject(GL_FRAMEBUFFER, fb.handle, name);
if (colorIsARenderBuffer) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer.handle, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil.handle);
else
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthstencil);
if (CheckFrameBufferCompleteness()) if (CheckFrameBufferCompleteness())
ClearFrameBuffer(true, true); 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; PPFrameBuffer fb;
glGenFramebuffers(1, &handle); glGenFramebuffers(1, &fb.handle);
glBindFramebuffer(GL_FRAMEBUFFER, handle); glBindFramebuffer(GL_FRAMEBUFFER, fb.handle);
FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name); 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) if (multisample)
{ {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer0, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer0.handle, 0);
if (colorbuffer1 != 0) if (colorbuffer1.handle != 0)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer1, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer1.handle, 0);
if (colorbuffer2 != 0) if (colorbuffer2.handle != 0)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer2, 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, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, depthstencil.handle, 0);
} }
else else
{ {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer0, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer0.handle, 0);
if (colorbuffer1 != 0) if (colorbuffer1.handle != 0)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, colorbuffer1, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, colorbuffer1.handle, 0);
if (colorbuffer2 != 0) if (colorbuffer2.handle != 0)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorbuffer2, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorbuffer2.handle, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthstencil, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthstencil.handle, 0);
} }
if (CheckFrameBufferCompleteness()) if (CheckFrameBufferCompleteness())
ClearFrameBuffer(true, true); ClearFrameBuffer(true, true);
return handle; return fb;
} }
//========================================================================== //==========================================================================
@ -683,8 +681,8 @@ void FGLRenderBuffers::BlitSceneToTexture()
if (mSamples <= 1) if (mSamples <= 1)
return; return;
glBindFramebuffer(GL_READ_FRAMEBUFFER, mSceneFB); glBindFramebuffer(GL_READ_FRAMEBUFFER, mSceneFB.handle);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle);
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0)
@ -697,6 +695,13 @@ void FGLRenderBuffers::BlitSceneToTexture()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 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 // Eye textures and their frame buffers
@ -707,8 +712,8 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye)
{ {
CreateEyeBuffers(eye); CreateEyeBuffers(eye);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); glBindFramebuffer(GL_READ_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye].handle);
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0) if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0)
@ -725,13 +730,13 @@ void FGLRenderBuffers::BindEyeTexture(int eye, int texunit)
{ {
CreateEyeBuffers(eye); CreateEyeBuffers(eye);
glActiveTexture(GL_TEXTURE0 + texunit); glActiveTexture(GL_TEXTURE0 + texunit);
glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye]); glBindTexture(GL_TEXTURE_2D, mEyeTextures[eye].handle);
} }
void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer) void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
{ {
CreateEyeBuffers(eye); 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() void FGLRenderBuffers::BindShadowMapFB()
{ {
CreateShadowMap(); CreateShadowMap();
glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapFB); glBindFramebuffer(GL_FRAMEBUFFER, mShadowMapFB.handle);
} }
void FGLRenderBuffers::BindShadowMapTexture(int texunit) void FGLRenderBuffers::BindShadowMapTexture(int texunit)
{ {
CreateShadowMap(); CreateShadowMap();
glActiveTexture(GL_TEXTURE0 + texunit); glActiveTexture(GL_TEXTURE0 + texunit);
glBindTexture(GL_TEXTURE_2D, mShadowMapTexture); glBindTexture(GL_TEXTURE_2D, mShadowMapTexture.handle);
} }
void FGLRenderBuffers::ClearShadowMap() void FGLRenderBuffers::ClearShadowMap()
@ -762,7 +767,7 @@ void FGLRenderBuffers::ClearShadowMap()
void FGLRenderBuffers::CreateShadowMap() void FGLRenderBuffers::CreateShadowMap()
{ {
if (mShadowMapTexture != 0 && gl_shadowmap_quality == mCurrentShadowMapSize) if (mShadowMapTexture.handle != 0 && gl_shadowmap_quality == mCurrentShadowMapSize)
return; return;
ClearShadowMap(); ClearShadowMap();
@ -796,7 +801,7 @@ void FGLRenderBuffers::CreateShadowMap()
void FGLRenderBuffers::BindSceneFB(bool sceneData) 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); glActiveTexture(GL_TEXTURE0 + index);
if (mSamples > 1) if (mSamples > 1)
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneMultisample); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneMultisampleTex.handle);
else 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); glActiveTexture(GL_TEXTURE0 + index);
if (mSamples > 1) if (mSamples > 1)
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneFog); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneFogTex.handle);
else 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); glActiveTexture(GL_TEXTURE0 + index);
if (mSamples > 1) if (mSamples > 1)
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneNormal); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneNormalTex.handle);
else 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); glActiveTexture(GL_TEXTURE0 + index);
if (mSamples > 1) if (mSamples > 1)
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneDepthStencil); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneDepthStencilTex.handle);
else 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); mPipelineTexture[mCurrentPipelineTexture].Bind(index, filter, wrap);
glBindTexture(GL_TEXTURE_2D, mPipelineTexture[mCurrentPipelineTexture]);
} }
//========================================================================== //==========================================================================
@ -879,7 +883,7 @@ void FGLRenderBuffers::BindCurrentTexture(int index)
void FGLRenderBuffers::BindCurrentFB() void FGLRenderBuffers::BindCurrentFB()
{ {
glBindFramebuffer(GL_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture]); mPipelineFB[mCurrentPipelineTexture].Bind();
} }
//========================================================================== //==========================================================================
@ -891,7 +895,7 @@ void FGLRenderBuffers::BindCurrentFB()
void FGLRenderBuffers::BindNextFB() void FGLRenderBuffers::BindNextFB()
{ {
int out = (mCurrentPipelineTexture + 1) % NumPipelineTextures; int out = (mCurrentPipelineTexture + 1) % NumPipelineTextures;
glBindFramebuffer(GL_FRAMEBUFFER, mPipelineFB[out]); mPipelineFB[out].Bind();
} }
//========================================================================== //==========================================================================
@ -913,7 +917,7 @@ void FGLRenderBuffers::NextTexture()
void FGLRenderBuffers::BindOutputFB() void FGLRenderBuffers::BindOutputFB()
{ {
glBindFramebuffer(GL_FRAMEBUFFER, mOutputFB); glBindFramebuffer(GL_FRAMEBUFFER, 0);
} }
//========================================================================== //==========================================================================

View file

@ -3,24 +3,65 @@
#include "gl/shaders/gl_shader.h" #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 class FGLBloomTextureLevel
{ {
public: public:
GLuint VTexture = 0; PPTexture VTexture;
GLuint VFramebuffer = 0; PPFrameBuffer VFramebuffer;
GLuint HTexture = 0; PPTexture HTexture;
GLuint HFramebuffer = 0; PPFrameBuffer HFramebuffer;
GLuint Width = 0; int Width = 0;
GLuint Height = 0; int Height = 0;
}; };
class FGLExposureTextureLevel class FGLExposureTextureLevel
{ {
public: public:
GLuint Texture = 0; PPTexture Texture;
GLuint Framebuffer = 0; PPFrameBuffer Framebuffer;
GLuint Width = 0; int Width = 0;
GLuint Height = 0; int Height = 0;
}; };
class FGLRenderBuffers class FGLRenderBuffers
@ -38,12 +79,14 @@ public:
void BindSceneDepthTexture(int index); void BindSceneDepthTexture(int index);
void BlitSceneToTexture(); 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 BindCurrentFB();
void BindNextFB(); void BindNextFB();
void NextTexture(); void NextTexture();
int GetCurrentFB() const { return mPipelineFB[mCurrentPipelineTexture]; } PPFrameBuffer GetCurrentFB() const { return mPipelineFB[mCurrentPipelineTexture]; }
void BindOutputFB(); void BindOutputFB();
@ -58,21 +101,21 @@ public:
FGLBloomTextureLevel BloomLevels[NumBloomLevels]; FGLBloomTextureLevel BloomLevels[NumBloomLevels];
TArray<FGLExposureTextureLevel> ExposureLevels; TArray<FGLExposureTextureLevel> ExposureLevels;
GLuint ExposureTexture = 0; PPTexture ExposureTexture;
GLuint ExposureFB = 0; PPFrameBuffer ExposureFB;
bool FirstExposureFrame = true; bool FirstExposureFrame = true;
// Ambient occlusion buffers // Ambient occlusion buffers
GLuint LinearDepthTexture = 0; PPTexture LinearDepthTexture;
GLuint LinearDepthFB = 0; PPFrameBuffer LinearDepthFB;
GLuint AmbientTexture0 = 0; PPTexture AmbientTexture0;
GLuint AmbientTexture1 = 0; PPTexture AmbientTexture1;
GLuint AmbientFB0 = 0; PPFrameBuffer AmbientFB0;
GLuint AmbientFB1 = 0; PPFrameBuffer AmbientFB1;
int AmbientWidth = 0; int AmbientWidth = 0;
int AmbientHeight = 0; int AmbientHeight = 0;
enum { NumAmbientRandomTextures = 3 }; enum { NumAmbientRandomTextures = 3 };
GLuint AmbientRandomTexture[NumAmbientRandomTextures]; PPTexture AmbientRandomTexture[NumAmbientRandomTextures];
static bool IsEnabled(); static bool IsEnabled();
@ -98,18 +141,19 @@ private:
void CreateShadowMap(); void CreateShadowMap();
void CreateAmbientOcclusion(int width, int height); void CreateAmbientOcclusion(int width, int height);
GLuint Create2DTexture(const char *name, GLuint format, int width, int height, const void *data = nullptr); PPTexture 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); PPTexture 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); PPRenderBuffer CreateRenderBuffer(const char *name, GLuint format, int width, int height);
GLuint CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples); PPRenderBuffer CreateRenderBuffer(const char *name, GLuint format, int width, int height, int samples);
GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer); PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer);
GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer, GLuint depthstencil, bool colorIsARenderBuffer); PPFrameBuffer CreateFrameBuffer(const char *name, PPTexture colorbuffer, PPRenderBuffer depthstencil);
GLuint CreateFrameBuffer(const char *name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint colorbuffer2, GLuint depthstencil, bool multisample); 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(); bool CheckFrameBufferCompleteness();
void ClearFrameBuffer(bool stencil, bool depth); void ClearFrameBuffer(bool stencil, bool depth);
void DeleteTexture(GLuint &handle); void DeleteTexture(PPTexture &handle);
void DeleteRenderBuffer(GLuint &handle); void DeleteRenderBuffer(PPRenderBuffer &handle);
void DeleteFrameBuffer(GLuint &handle); void DeleteFrameBuffer(PPFrameBuffer &handle);
int mWidth = 0; int mWidth = 0;
int mHeight = 0; int mHeight = 0;
@ -122,28 +166,29 @@ private:
int mCurrentPipelineTexture = 0; int mCurrentPipelineTexture = 0;
// Buffers for the scene // Buffers for the scene
GLuint mSceneMultisample = 0; PPTexture mSceneMultisampleTex;
GLuint mSceneDepthStencil = 0; PPTexture mSceneDepthStencilTex;
GLuint mSceneFog = 0; PPTexture mSceneFogTex;
GLuint mSceneNormal = 0; PPTexture mSceneNormalTex;
GLuint mSceneFB = 0; PPRenderBuffer mSceneMultisampleBuf;
GLuint mSceneDataFB = 0; PPRenderBuffer mSceneDepthStencilBuf;
PPRenderBuffer mSceneFogBuf;
PPRenderBuffer mSceneNormalBuf;
PPFrameBuffer mSceneFB;
PPFrameBuffer mSceneDataFB;
bool mSceneUsesTextures = false; bool mSceneUsesTextures = false;
// Effect/HUD buffers // Effect/HUD buffers
GLuint mPipelineTexture[NumPipelineTextures]; PPTexture mPipelineTexture[NumPipelineTextures];
GLuint mPipelineFB[NumPipelineTextures]; PPFrameBuffer mPipelineFB[NumPipelineTextures];
// Back buffer frame buffer
GLuint mOutputFB = 0;
// Eye buffers // Eye buffers
TArray<GLuint> mEyeTextures; TArray<PPTexture> mEyeTextures;
TArray<GLuint> mEyeFBs; TArray<PPFrameBuffer> mEyeFBs;
// Shadow map texture // Shadow map texture
GLuint mShadowMapTexture = 0; PPTexture mShadowMapTexture;
GLuint mShadowMapFB = 0; PPFrameBuffer mShadowMapFB;
int mCurrentShadowMapSize = 0; int mCurrentShadowMapSize = 0;
static bool FailedCreate; static bool FailedCreate;

View file

@ -30,6 +30,7 @@
#include "gl/shaders/gl_blurshader.h" #include "gl/shaders/gl_blurshader.h"
#include "gl/data/gl_vertexbuffer.h" #include "gl/data/gl_vertexbuffer.h"
#include "gl/renderer/gl_renderer.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); 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); 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); BlurSetup *setup = GetSetup(blurAmount, sampleCount);
if (vertical) if (vertical)
@ -67,14 +68,9 @@ void FBlurShader::Blur(FGLRenderer *renderer, float blurAmount, int sampleCount,
else else
setup->HorizontalShader->Bind(); setup->HorizontalShader->Bind();
glActiveTexture(GL_TEXTURE0); inputTexture.Bind(0);
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);
glBindFramebuffer(GL_FRAMEBUFFER, outputFrameBuffer); outputFrameBuffer.Bind();
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glDisable(GL_BLEND); glDisable(GL_BLEND);

View file

@ -5,15 +5,17 @@
#include <memory> #include <memory>
class FGLRenderer; class FGLRenderer;
class PPFrameBuffer;
class PPTexture;
class FBlurShader class FBlurShader
{ {
public: public:
void BlurVertical(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, GLuint inputTexture, GLuint outputFrameBuffer, int width, int height); void BlurHorizontal(FGLRenderer *renderer, float blurAmount, int sampleCount, PPTexture inputTexture, PPFrameBuffer outputFrameBuffer, int width, int height);
private: 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 struct BlurSetup
{ {