diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index b84c2e7d4..fa6004c53 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -828,6 +828,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) if (FGLRenderBuffers::IsEnabled()) { FGLPostProcessState savedState; + savedState.SaveTextureBindings(2); mBuffers->BindOutputFB(); GL_IRECT box; @@ -856,6 +857,8 @@ void FGLRenderer::DrawPresentTexture(const GL_IRECT &box, bool applyGamma) { glViewport(box.left, box.top, box.width, box.height); + GLRenderer->mBuffers->BindDitherTexture(1); + glActiveTexture(GL_TEXTURE0); if (ViewportLinearScale()) { diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index d60045f3e..b715aff9a 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -82,6 +82,7 @@ FGLRenderBuffers::~FGLRenderBuffers() ClearExposureLevels(); ClearAmbientOcclusion(); ClearShadowMap(); + DeleteTexture(mDitherTexture); } void FGLRenderBuffers::ClearScene() @@ -741,6 +742,36 @@ void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer) glBindFramebuffer(readBuffer ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER, mEyeFBs[eye]); } +void FGLRenderBuffers::BindDitherTexture(int texunit) +{ + if (!mDitherTexture) + { + float halfstep = 1.0f / 65.0f; + float data[64] = + { + 0.0f / 16.0f + halfstep * 1, 8.0f / 16.0f + halfstep * 1, 2.0f / 16.0f + halfstep * 1, 10.0f / 16.0f + halfstep * 1, + 0.0f / 16.0f + halfstep * 3, 8.0f / 16.0f + halfstep * 3, 2.0f / 16.0f + halfstep * 3, 10.0f / 16.0f + halfstep * 3, + 12.0f / 16.0f + halfstep * 1, 4.0f / 16.0f + halfstep * 1, 14.0f / 16.0f + halfstep * 1, 6.0f / 16.0f + halfstep * 1, + 12.0f / 16.0f + halfstep * 3, 4.0f / 16.0f + halfstep * 3, 14.0f / 16.0f + halfstep * 3, 6.0f / 16.0f + halfstep * 3, + 3.0f / 16.0f + halfstep * 1, 11.0f / 16.0f + halfstep * 1, 1.0f / 16.0f + halfstep * 1, 9.0f / 16.0f + halfstep * 1, + 3.0f / 16.0f + halfstep * 3, 11.0f / 16.0f + halfstep * 3, 1.0f / 16.0f + halfstep * 3, 9.0f / 16.0f + halfstep * 3, + 15.0f / 16.0f + halfstep * 1, 7.0f / 16.0f + halfstep * 1, 13.0f / 16.0f + halfstep * 1, 5.0f / 16.0f + halfstep * 1, + 15.0f / 16.0f + halfstep * 3, 7.0f / 16.0f + halfstep * 3, 13.0f / 16.0f + halfstep * 3, 5.0f / 16.0f + halfstep * 3, + 0.0f / 16.0f + halfstep * 4, 8.0f / 16.0f + halfstep * 4, 2.0f / 16.0f + halfstep * 4, 10.0f / 16.0f + halfstep * 4, + 0.0f / 16.0f + halfstep * 2, 8.0f / 16.0f + halfstep * 2, 2.0f / 16.0f + halfstep * 2, 10.0f / 16.0f + halfstep * 2, + 12.0f / 16.0f + halfstep * 4, 4.0f / 16.0f + halfstep * 4, 14.0f / 16.0f + halfstep * 4, 6.0f / 16.0f + halfstep * 4, + 12.0f / 16.0f + halfstep * 2, 4.0f / 16.0f + halfstep * 2, 14.0f / 16.0f + halfstep * 2, 6.0f / 16.0f + halfstep * 2, + 3.0f / 16.0f + halfstep * 4, 11.0f / 16.0f + halfstep * 4, 1.0f / 16.0f + halfstep * 4, 9.0f / 16.0f + halfstep * 4, + 3.0f / 16.0f + halfstep * 2, 11.0f / 16.0f + halfstep * 2, 1.0f / 16.0f + halfstep * 2, 9.0f / 16.0f + halfstep * 2, + 15.0f / 16.0f + halfstep * 4, 7.0f / 16.0f + halfstep * 4, 13.0f / 16.0f + halfstep * 4, 5.0f / 16.0f + halfstep * 4, + 15.0f / 16.0f + halfstep * 2, 7.0f / 16.0f + halfstep * 2, 13.0f / 16.0f + halfstep * 2, 5.0f / 16.0f + halfstep * 2 + }; + + mDitherTexture = Create2DTexture("DitherTexture", GL_R32F, 8, 8, data); + } + mDitherTexture.Bind(1, GL_NEAREST, GL_REPEAT); +} + //========================================================================== // // Shadow map texture and frame buffers diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 1c8ea1690..5e54cfacf 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -51,6 +51,8 @@ public: void BindEyeTexture(int eye, int texunit); void BindEyeFB(int eye, bool readBuffer = false); + void BindDitherTexture(int texunit); + void BindShadowMapFB(); void BindShadowMapTexture(int index); @@ -145,6 +147,8 @@ private: GLuint mShadowMapFB = 0; int mCurrentShadowMapSize = 0; + PPGLTexture mDitherTexture; + static bool FailedCreate; static bool BuffersActive; }; diff --git a/wadsrc/static/shaders/glsl/present.fp b/wadsrc/static/shaders/glsl/present.fp index fd4c28329..79c33072d 100644 --- a/wadsrc/static/shaders/glsl/present.fp +++ b/wadsrc/static/shaders/glsl/present.fp @@ -8,6 +8,7 @@ uniform float Contrast; uniform float Brightness; uniform float Saturation; uniform int GrayFormula; +uniform sampler2D DitherTexture; vec4 ApplyGamma(vec4 c) { @@ -22,30 +23,10 @@ vec4 ApplyGamma(vec4 c) return vec4(val, c.a); } -#define HALFSTEP 1./65. -float DitherMatrix[64] = float[]( - 0.0 / 16.0 + HALFSTEP * 1, 8.0 / 16.0 + HALFSTEP * 1, 2.0 / 16.0 + HALFSTEP * 1, 10.0 / 16.0 + HALFSTEP * 1, - 0.0 / 16.0 + HALFSTEP * 3, 8.0 / 16.0 + HALFSTEP * 3, 2.0 / 16.0 + HALFSTEP * 3, 10.0 / 16.0 + HALFSTEP * 3, - 12.0 / 16.0 + HALFSTEP * 1, 4.0 / 16.0 + HALFSTEP * 1, 14.0 / 16.0 + HALFSTEP * 1, 6.0 / 16.0 + HALFSTEP * 1, - 12.0 / 16.0 + HALFSTEP * 3, 4.0 / 16.0 + HALFSTEP * 3, 14.0 / 16.0 + HALFSTEP * 3, 6.0 / 16.0 + HALFSTEP * 3, - 3.0 / 16.0 + HALFSTEP * 1, 11.0 / 16.0 + HALFSTEP * 1, 1.0 / 16.0 + HALFSTEP * 1, 9.0 / 16.0 + HALFSTEP * 1, - 3.0 / 16.0 + HALFSTEP * 3, 11.0 / 16.0 + HALFSTEP * 3, 1.0 / 16.0 + HALFSTEP * 3, 9.0 / 16.0 + HALFSTEP * 3, - 15.0 / 16.0 + HALFSTEP * 1, 7.0 / 16.0 + HALFSTEP * 1, 13.0 / 16.0 + HALFSTEP * 1, 5.0 / 16.0 + HALFSTEP * 1, - 15.0 / 16.0 + HALFSTEP * 3, 7.0 / 16.0 + HALFSTEP * 3, 13.0 / 16.0 + HALFSTEP * 3, 5.0 / 16.0 + HALFSTEP * 3, - 0.0 / 16.0 + HALFSTEP * 4, 8.0 / 16.0 + HALFSTEP * 4, 2.0 / 16.0 + HALFSTEP * 4, 10.0 / 16.0 + HALFSTEP * 4, - 0.0 / 16.0 + HALFSTEP * 2, 8.0 / 16.0 + HALFSTEP * 2, 2.0 / 16.0 + HALFSTEP * 2, 10.0 / 16.0 + HALFSTEP * 2, - 12.0 / 16.0 + HALFSTEP * 4, 4.0 / 16.0 + HALFSTEP * 4, 14.0 / 16.0 + HALFSTEP * 4, 6.0 / 16.0 + HALFSTEP * 4, - 12.0 / 16.0 + HALFSTEP * 2, 4.0 / 16.0 + HALFSTEP * 2, 14.0 / 16.0 + HALFSTEP * 2, 6.0 / 16.0 + HALFSTEP * 2, - 3.0 / 16.0 + HALFSTEP * 4, 11.0 / 16.0 + HALFSTEP * 4, 1.0 / 16.0 + HALFSTEP * 4, 9.0 / 16.0 + HALFSTEP * 4, - 3.0 / 16.0 + HALFSTEP * 2, 11.0 / 16.0 + HALFSTEP * 2, 1.0 / 16.0 + HALFSTEP * 2, 9.0 / 16.0 + HALFSTEP * 2, - 15.0 / 16.0 + HALFSTEP * 4, 7.0 / 16.0 + HALFSTEP * 4, 13.0 / 16.0 + HALFSTEP * 4, 5.0 / 16.0 + HALFSTEP * 4, - 15.0 / 16.0 + HALFSTEP * 2, 7.0 / 16.0 + HALFSTEP * 2, 13.0 / 16.0 + HALFSTEP * 2, 5.0 / 16.0 + HALFSTEP * 2 -); - vec4 Dither(vec4 c, float colorscale) { - ivec2 pos = ivec2(gl_FragCoord.xy) & 7; - float threshold = DitherMatrix[pos.x + (pos.y << 3)]; + vec2 texSize = vec2(textureSize(DitherTexture, 0)); + float threshold = texture(DitherTexture, gl_FragCoord.xy / texSize).r; return vec4(floor(c.rgb * colorscale + threshold) / colorscale, c.a); }