diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5317c277ab..b5dd8739c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1063,6 +1063,7 @@ set( FASTMATH_SOURCES gl/renderer/gl_renderbuffers.cpp gl/renderer/gl_lightdata.cpp gl/renderer/gl_postprocess.cpp + gl/renderer/gl_postprocessstate.cpp gl/hqnx/init.cpp gl/hqnx/hq2x.cpp gl/hqnx/hq3x.cpp diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 155321de41..da7031afe8 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -63,6 +63,7 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderbuffers.h" #include "gl/renderer/gl_renderer.h" +#include "gl/renderer/gl_postprocessstate.h" #include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/shaders/gl_bloomshader.h" @@ -117,34 +118,11 @@ void FGLRenderer::BloomScene() if (!gl_bloom || !FGLRenderBuffers::IsEnabled() || gl_fixedcolormap != CM_DEFAULT) return; + FGLPostProcessState savedState; + const float blurAmount = gl_bloom_amount; int sampleCount = gl_bloom_kernel_size; - // TBD: Maybe need a better way to share state with other parts of the pipeline - GLint activeTex, textureBinding, samplerBinding; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - glActiveTexture(GL_TEXTURE0); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - { - glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding); - glBindSampler(0, 0); - } - GLboolean blendEnabled, scissorEnabled; - GLint currentProgram, blendEquationRgb, blendEquationAlpha, blendSrcRgb, blendSrcAlpha, blendDestRgb, blendDestAlpha; - glGetBooleanv(GL_BLEND, &blendEnabled); - glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled); - glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); - glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRgb); - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); - glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRgb); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); - glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRgb); - glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); - - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); - const auto &level0 = mBuffers->BloomLevels[0]; // Extract blooming pixels from scene texture: @@ -207,18 +185,6 @@ void FGLRenderer::BloomScene() mBloomCombineShader->Bind(); mBloomCombineShader->BloomTexture.Set(0); mVBO->RenderScreenQuad(); - - if (blendEnabled) - glEnable(GL_BLEND); - if (scissorEnabled) - glEnable(GL_SCISSOR_TEST); - glBlendEquationSeparate(blendEquationRgb, blendEquationAlpha); - glBlendFuncSeparate(blendSrcRgb, blendDestRgb, blendSrcAlpha, blendDestAlpha); - glUseProgram(currentProgram); - glBindTexture(GL_TEXTURE_2D, textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - glBindSampler(0, samplerBinding); - glActiveTexture(activeTex); } //----------------------------------------------------------------------------- @@ -232,22 +198,7 @@ void FGLRenderer::TonemapScene() if (gl_tonemap == 0) return; - GLint activeTex, textureBinding, samplerBinding; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - glActiveTexture(GL_TEXTURE0); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - { - glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding); - glBindSampler(0, 0); - } - - GLboolean blendEnabled, scissorEnabled; - glGetBooleanv(GL_BLEND, &blendEnabled); - glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled); - - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); + FGLPostProcessState savedState; mBuffers->BindNextFB(); mBuffers->BindCurrentTexture(0); @@ -257,15 +208,6 @@ void FGLRenderer::TonemapScene() mVBO->BindVBO(); mVBO->RenderScreenQuad(); mBuffers->NextTexture(); - - if (blendEnabled) - glEnable(GL_BLEND); - if (scissorEnabled) - glEnable(GL_SCISSOR_TEST); - glBindTexture(GL_TEXTURE_2D, textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - glBindSampler(0, samplerBinding); - glActiveTexture(activeTex); } //----------------------------------------------------------------------------- @@ -279,23 +221,6 @@ void FGLRenderer::LensDistortScene() if (gl_lens == 0) return; - GLint activeTex, textureBinding, samplerBinding; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - glActiveTexture(GL_TEXTURE0); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - { - glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding); - glBindSampler(0, 0); - } - - GLboolean blendEnabled, scissorEnabled; - glGetBooleanv(GL_BLEND, &blendEnabled); - glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled); - - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); - float k[4] = { gl_lens_k, @@ -321,6 +246,8 @@ void FGLRenderer::LensDistortScene() float f = MAX(f0, f2); float scale = 1.0f / f; + FGLPostProcessState savedState; + mBuffers->BindNextFB(); mBuffers->BindCurrentTexture(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -333,16 +260,9 @@ void FGLRenderer::LensDistortScene() mLensShader->CubicDistortionValue.Set(kcube); mVBO->BindVBO(); mVBO->RenderScreenQuad(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mBuffers->NextTexture(); - - if (blendEnabled) - glEnable(GL_BLEND); - if (scissorEnabled) - glEnable(GL_SCISSOR_TEST); - glBindTexture(GL_TEXTURE_2D, textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - glBindSampler(0, samplerBinding); - glActiveTexture(activeTex); } //----------------------------------------------------------------------------- @@ -355,23 +275,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) { if (FGLRenderBuffers::IsEnabled()) { - glDisable(GL_MULTISAMPLE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); - - GLboolean blendEnabled; - GLint currentProgram; - GLint activeTex, textureBinding, samplerBinding; - glGetBooleanv(GL_BLEND, &blendEnabled); - glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); - glActiveTexture(GL_TEXTURE0); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - { - glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding); - glBindSampler(0, 0); - } + FGLPostProcessState savedState; mBuffers->BindOutputFB(); @@ -446,13 +350,5 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mVBO->BindVBO(); mVBO->RenderScreenQuad(mScreenViewport.width / (float)mBuffers->GetWidth(), mScreenViewport.height / (float)mBuffers->GetHeight()); - - if (blendEnabled) - glEnable(GL_BLEND); - glUseProgram(currentProgram); - glBindTexture(GL_TEXTURE_2D, textureBinding); - if (gl.flags & RFL_SAMPLER_OBJECTS) - glBindSampler(0, samplerBinding); - glActiveTexture(activeTex); } } diff --git a/src/gl/renderer/gl_postprocessstate.cpp b/src/gl/renderer/gl_postprocessstate.cpp new file mode 100644 index 0000000000..7e34a11498 --- /dev/null +++ b/src/gl/renderer/gl_postprocessstate.cpp @@ -0,0 +1,124 @@ +/* +** gl_postprocessstate.cpp +** Render state maintenance +** +**--------------------------------------------------------------------------- +** Copyright 2016 Magnus Norddahl +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be +** covered by the terms of the GNU Lesser General Public License as published +** by the Free Software Foundation; either version 2.1 of the License, or (at +** your option) any later version. +** 5. Full disclosure of the entire project's source code, except for third +** party libraries is mandatory. (NOTE: This clause is non-negotiable!) +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "templates.h" +#include "gl/system/gl_system.h" +#include "gl/system/gl_interface.h" +#include "gl/data/gl_data.h" +#include "gl/data/gl_vertexbuffer.h" +#include "gl/system/gl_cvars.h" +#include "gl/shaders/gl_shader.h" +#include "gl/renderer/gl_renderer.h" +#include "gl/renderer/gl_postprocessstate.h" + +//----------------------------------------------------------------------------- +// +// Saves state modified by post processing shaders +// +//----------------------------------------------------------------------------- + +FGLPostProcessState::FGLPostProcessState() +{ + glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); + glActiveTexture(GL_TEXTURE0); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); + if (gl.flags & RFL_SAMPLER_OBJECTS) + { + glGetIntegerv(GL_SAMPLER_BINDING, &samplerBinding); + glBindSampler(0, 0); + } + + glGetBooleanv(GL_BLEND, &blendEnabled); + glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled); + glGetBooleanv(GL_DEPTH_TEST, &depthEnabled); + glGetBooleanv(GL_MULTISAMPLE, &multisampleEnabled); + glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); + glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRgb); + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); + glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRgb); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); + glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRgb); + glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); + + glDisable(GL_MULTISAMPLE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glDisable(GL_BLEND); +} + +//----------------------------------------------------------------------------- +// +// Restores state at the end of post processing +// +//----------------------------------------------------------------------------- + +FGLPostProcessState::~FGLPostProcessState() +{ + if (blendEnabled) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + + if (scissorEnabled) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); + + if (depthEnabled) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + + if (multisampleEnabled) + glEnable(GL_MULTISAMPLE); + else + glDisable(GL_MULTISAMPLE); + + glBlendEquationSeparate(blendEquationRgb, blendEquationAlpha); + glBlendFuncSeparate(blendSrcRgb, blendDestRgb, blendSrcAlpha, blendDestAlpha); + + glUseProgram(currentProgram); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureBinding); + if (gl.flags & RFL_SAMPLER_OBJECTS) + glBindSampler(0, samplerBinding); + glActiveTexture(activeTex); +} diff --git a/src/gl/renderer/gl_postprocessstate.h b/src/gl/renderer/gl_postprocessstate.h new file mode 100644 index 0000000000..5cba736749 --- /dev/null +++ b/src/gl/renderer/gl_postprocessstate.h @@ -0,0 +1,37 @@ +#ifndef __GL_POSTPROCESSSTATE_H +#define __GL_POSTPROCESSSTATE_H + +#include +#include "gl/system/gl_interface.h" +#include "gl/data/gl_data.h" +#include "gl/data/gl_matrix.h" +#include "c_cvars.h" +#include "r_defs.h" + +class FGLPostProcessState +{ +public: + FGLPostProcessState(); + ~FGLPostProcessState(); + +private: + FGLPostProcessState(const FGLPostProcessState &) = delete; + FGLPostProcessState &operator=(const FGLPostProcessState &) = delete; + + GLint activeTex; + GLint textureBinding; + GLint samplerBinding; + GLboolean blendEnabled; + GLboolean scissorEnabled; + GLboolean depthEnabled; + GLboolean multisampleEnabled; + GLint currentProgram; + GLint blendEquationRgb; + GLint blendEquationAlpha; + GLint blendSrcRgb; + GLint blendSrcAlpha; + GLint blendDestRgb; + GLint blendDestAlpha; +}; + +#endif diff --git a/src/gl/shaders/gl_bloomshader.cpp b/src/gl/shaders/gl_bloomshader.cpp index c7191884fb..f9e38e0c32 100644 --- a/src/gl/shaders/gl_bloomshader.cpp +++ b/src/gl/shaders/gl_bloomshader.cpp @@ -53,7 +53,7 @@ void FBloomExtractShader::Bind() { if (!mShader) { - mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/bloomextract.vp", "", 330); + mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/bloomextract.fp", "", 330); mShader.SetFragDataLocation(0, "FragColor"); mShader.Link("shaders/glsl/bloomextract"); @@ -68,7 +68,7 @@ void FBloomCombineShader::Bind() { if (!mShader) { - mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/bloomcombine.vp", "", 330); + mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/bloomcombine.fp", "", 330); mShader.SetFragDataLocation(0, "FragColor"); mShader.Link("shaders/glsl/bloomcombine"); diff --git a/src/gl/shaders/gl_lensshader.cpp b/src/gl/shaders/gl_lensshader.cpp index 39f5042e73..4dc23f14dc 100644 --- a/src/gl/shaders/gl_lensshader.cpp +++ b/src/gl/shaders/gl_lensshader.cpp @@ -53,7 +53,7 @@ void FLensShader::Bind() { if (!mShader) { - mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/lensdistortion.vp", "", 330); + mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/lensdistortion.fp", "", 330); mShader.SetFragDataLocation(0, "FragColor"); mShader.Link("shaders/glsl/lensdistortion"); diff --git a/src/gl/shaders/gl_presentshader.cpp b/src/gl/shaders/gl_presentshader.cpp index 2f96424581..9998fda36d 100644 --- a/src/gl/shaders/gl_presentshader.cpp +++ b/src/gl/shaders/gl_presentshader.cpp @@ -53,7 +53,7 @@ void FPresentShader::Bind() { if (!mShader) { - mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/present.vp", "", 330); + mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/present.fp", "", 330); mShader.SetFragDataLocation(0, "FragColor"); mShader.Link("shaders/glsl/present"); diff --git a/src/gl/shaders/gl_tonemapshader.cpp b/src/gl/shaders/gl_tonemapshader.cpp index c26e8d1af9..8e1f3a8446 100644 --- a/src/gl/shaders/gl_tonemapshader.cpp +++ b/src/gl/shaders/gl_tonemapshader.cpp @@ -54,7 +54,7 @@ void FTonemapShader::Bind() auto &shader = mShader[gl_tonemap]; if (!shader) { - shader.Compile(FShaderProgram::Vertex, "shaders/glsl/tonemap.vp", "", 330); + shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); shader.Compile(FShaderProgram::Fragment, "shaders/glsl/tonemap.fp", GetDefines(gl_tonemap), 330); shader.SetFragDataLocation(0, "FragColor"); shader.Link("shaders/glsl/tonemap"); diff --git a/wadsrc/static/shaders/glsl/bloomcombine.vp b/wadsrc/static/shaders/glsl/bloomcombine.vp deleted file mode 100644 index 5990669a51..0000000000 --- a/wadsrc/static/shaders/glsl/bloomcombine.vp +++ /dev/null @@ -1,9 +0,0 @@ - -in vec4 PositionInProjection; -out vec2 TexCoord; - -void main() -{ - gl_Position = PositionInProjection; - TexCoord = PositionInProjection.xy * 0.5 + 0.5; -} diff --git a/wadsrc/static/shaders/glsl/bloomextract.vp b/wadsrc/static/shaders/glsl/bloomextract.vp deleted file mode 100644 index 5990669a51..0000000000 --- a/wadsrc/static/shaders/glsl/bloomextract.vp +++ /dev/null @@ -1,9 +0,0 @@ - -in vec4 PositionInProjection; -out vec2 TexCoord; - -void main() -{ - gl_Position = PositionInProjection; - TexCoord = PositionInProjection.xy * 0.5 + 0.5; -} diff --git a/wadsrc/static/shaders/glsl/lensdistortion.vp b/wadsrc/static/shaders/glsl/lensdistortion.vp deleted file mode 100644 index 5990669a51..0000000000 --- a/wadsrc/static/shaders/glsl/lensdistortion.vp +++ /dev/null @@ -1,9 +0,0 @@ - -in vec4 PositionInProjection; -out vec2 TexCoord; - -void main() -{ - gl_Position = PositionInProjection; - TexCoord = PositionInProjection.xy * 0.5 + 0.5; -} diff --git a/wadsrc/static/shaders/glsl/present.vp b/wadsrc/static/shaders/glsl/screenquad.vp similarity index 100% rename from wadsrc/static/shaders/glsl/present.vp rename to wadsrc/static/shaders/glsl/screenquad.vp diff --git a/wadsrc/static/shaders/glsl/tonemap.vp b/wadsrc/static/shaders/glsl/tonemap.vp deleted file mode 100644 index 5990669a51..0000000000 --- a/wadsrc/static/shaders/glsl/tonemap.vp +++ /dev/null @@ -1,9 +0,0 @@ - -in vec4 PositionInProjection; -out vec2 TexCoord; - -void main() -{ - gl_Position = PositionInProjection; - TexCoord = PositionInProjection.xy * 0.5 + 0.5; -}