diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7c66203a..94ce82945 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1068,7 +1068,6 @@ set (PCH_SOURCES hwrenderer/postprocessing/hw_presentshader.cpp hwrenderer/postprocessing/hw_present3dRowshader.cpp hwrenderer/postprocessing/hw_ambientshader.cpp - hwrenderer/postprocessing/hw_tonemapshader.cpp hwrenderer/textures/hw_material.cpp hwrenderer/textures/hw_precache.cpp hwrenderer/utility/hw_clock.cpp diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 39fc5529b..b7f5b5579 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -40,7 +40,6 @@ #include "gl/renderer/gl_postprocessstate.h" #include "gl/data/gl_vertexbuffer.h" #include "hwrenderer/postprocessing/hw_ambientshader.h" -#include "hwrenderer/postprocessing/hw_tonemapshader.h" #include "hwrenderer/postprocessing/hw_presentshader.h" #include "hwrenderer/postprocessing/hw_postprocess.h" #include "hwrenderer/postprocessing/hw_postprocess_cvars.h" @@ -101,10 +100,13 @@ void FGLRenderBuffers::RenderEffect(const FString &name) if (!gltexture) { - gltexture = Create2DTexture(name.GetChars(), glformat, pair->Value.Width, pair->Value.Height); + if (pair->Value.Data) + gltexture = Create2DTexture(pair->Key.GetChars(), glformat, pair->Value.Width, pair->Value.Height, pair->Value.Data.get()); + else + gltexture = Create2DTexture(pair->Key.GetChars(), glformat, pair->Value.Width, pair->Value.Height); gltexture.Width = pair->Value.Width; gltexture.Height = pair->Value.Height; - glframebuffer = CreateFrameBuffer(name.GetChars(), gltexture); + glframebuffer = CreateFrameBuffer(pair->Key.GetChars(), gltexture); } } } @@ -378,76 +380,16 @@ void FGLRenderer::BlurScene(float gameinfobluramount) void FGLRenderer::TonemapScene() { - if (gl_tonemap == 0) - return; - - FGLDebug::PushGroup("TonemapScene"); - - CreateTonemapPalette(); - - FGLPostProcessState savedState; - savedState.SaveTextureBindings(2); - - mBuffers->BindNextFB(); - mBuffers->BindCurrentTexture(0); - mTonemapShader->Bind(NOQUEUE); - - if (mTonemapShader->IsPaletteMode()) - { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mTonemapPalette->GetTextureHandle(0)); - 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); - glActiveTexture(GL_TEXTURE0); - } - else - { - //mBuffers->ExposureTexture.Bind(1); - } - - RenderScreenQuad(); - mBuffers->NextTexture(); - - FGLDebug::PopGroup(); -} - -void FGLRenderer::CreateTonemapPalette() -{ - if (!mTonemapPalette) - { - TArray lut; - lut.Resize(512 * 512 * 4); - for (int r = 0; r < 64; r++) - { - for (int g = 0; g < 64; g++) - { - for (int b = 0; b < 64; b++) - { - PalEntry color = GPalette.BaseColors[(uint8_t)PTM_BestColor((uint32_t *)GPalette.BaseColors, (r << 2) | (r >> 4), (g << 2) | (g >> 4), (b << 2) | (b >> 4), - gl_paltonemap_reverselookup, gl_paltonemap_powtable, 0, 256)]; - int index = ((r * 64 + g) * 64 + b) * 4; - lut[index] = color.b; - lut[index + 1] = color.g; - lut[index + 2] = color.r; - lut[index + 3] = 255; - } - } - } - - mTonemapPalette = new FHardwareTexture(true); - mTonemapPalette->CreateTexture(&lut[0], 512, 512, 0, false, 0, "mTonemapPalette"); - } + PPTonemap tonemap; + tonemap.DeclareShaders(); + tonemap.UpdateTextures(); + tonemap.UpdateSteps(); + mBuffers->RenderEffect("TonemapScene"); } void FGLRenderer::ClearTonemapPalette() { - if (mTonemapPalette) - { - delete mTonemapPalette; - mTonemapPalette = nullptr; - } + hw_postprocess.Textures.Remove("Tonemap.Palette"); } void FGLRenderer::ColormapScene(int fixedcm) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index ce0e9f49f..67fae676e 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -51,7 +51,6 @@ #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_scenedrawer.h" #include "hwrenderer/postprocessing/hw_ambientshader.h" -#include "hwrenderer/postprocessing/hw_tonemapshader.h" #include "hwrenderer/postprocessing/hw_presentshader.h" #include "hwrenderer/postprocessing/hw_present3dRowshader.h" #include "hwrenderer/postprocessing/hw_shadowmapshader.h" @@ -90,7 +89,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mSkyVBO = nullptr; mShaderManager = nullptr; mLights = nullptr; - mTonemapPalette = nullptr; mBuffers = nullptr; mScreenBuffers = nullptr; mSaveBuffers = nullptr; @@ -98,8 +96,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) mPresent3dCheckerShader = nullptr; mPresent3dColumnShader = nullptr; mPresent3dRowShader = nullptr; - mTonemapShader = nullptr; - mTonemapPalette = nullptr; mLinearDepthShader = nullptr; mDepthBlurShader = nullptr; mSSAOShader = nullptr; @@ -117,8 +113,6 @@ void FGLRenderer::Initialize(int width, int height) mDepthBlurShader = new FDepthBlurShader(); mSSAOShader = new FSSAOShader(); mSSAOCombineShader = new FSSAOCombineShader(); - mTonemapShader = new FTonemapShader(); - mTonemapPalette = nullptr; mPresentShader = new FPresentShader(); mPresent3dCheckerShader = new FPresent3DCheckerShader(); mPresent3dColumnShader = new FPresent3DColumnShader(); @@ -173,8 +167,6 @@ FGLRenderer::~FGLRenderer() if (mPresent3dCheckerShader) delete mPresent3dCheckerShader; if (mPresent3dColumnShader) delete mPresent3dColumnShader; if (mPresent3dRowShader) delete mPresent3dRowShader; - if (mTonemapShader) delete mTonemapShader; - if (mTonemapPalette) delete mTonemapPalette; if (mShadowMapShader) delete mShadowMapShader; delete mCustomPostProcessShaders; } diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index e212fe6f2..7dc15cec9 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -29,7 +29,6 @@ class FLinearDepthShader; class FDepthBlurShader; class FSSAOShader; class FSSAOCombineShader; -class FTonemapShader; class FPresentShader; class FPresent3DCheckerShader; class FPresent3DColumnShader; @@ -74,8 +73,6 @@ public: FSSAOShader *mSSAOShader; FDepthBlurShader *mDepthBlurShader; FSSAOCombineShader *mSSAOCombineShader; - FTonemapShader *mTonemapShader; - FHardwareTexture *mTonemapPalette; FPresentShader *mPresentShader; FPresent3DCheckerShader *mPresent3dCheckerShader; FPresent3DColumnShader *mPresent3dColumnShader; @@ -118,7 +115,6 @@ public: void BloomScene(int fixedcm); void TonemapScene(); void ColormapScene(int fixedcm); - void CreateTonemapPalette(); void ClearTonemapPalette(); void LensDistortScene(); void ApplyFXAA(); diff --git a/src/hwrenderer/postprocessing/hw_postprocess.cpp b/src/hwrenderer/postprocessing/hw_postprocess.cpp index 8c282a6f2..896585d22 100644 --- a/src/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/src/hwrenderer/postprocessing/hw_postprocess.cpp @@ -514,3 +514,79 @@ void PPColormap::UpdateSteps(int fixedcm) steps.Push(step); hw_postprocess.Effects["ColormapScene"] = steps; } + +///////////////////////////////////////////////////////////////////////////// + +void PPTonemap::DeclareShaders() +{ + hw_postprocess.Shaders["Tonemap.Linear"] = { "shaders/glsl/tonemap.fp", "#define LINEAR\n", {} }; + hw_postprocess.Shaders["Tonemap.Reinhard"] = { "shaders/glsl/tonemap.fp", "#define REINHARD\n", {} }; + hw_postprocess.Shaders["Tonemap.HejlDawson"] = { "shaders/glsl/tonemap.fp", "#define HEJLDAWSON\n", {} }; + hw_postprocess.Shaders["Tonemap.Uncharted2"] = { "shaders/glsl/tonemap.fp", "#define UNCHARTED2\n", {} }; + hw_postprocess.Shaders["Tonemap.Palette"] = { "shaders/glsl/tonemap.fp", "#define PALETTE\n", {} }; +} + +void PPTonemap::UpdateTextures() +{ + if (gl_tonemap == Palette) + { + auto &texture = hw_postprocess.Textures["Tonemap.Palette"]; + if (!texture.Data) + { + std::shared_ptr data(new uint32_t[512 * 512], [](void *p) { delete[](uint32_t*)p; }); + + uint8_t *lut = (uint8_t *)data.get(); + for (int r = 0; r < 64; r++) + { + for (int g = 0; g < 64; g++) + { + for (int b = 0; b < 64; b++) + { + PalEntry color = GPalette.BaseColors[(uint8_t)PTM_BestColor((uint32_t *)GPalette.BaseColors, (r << 2) | (r >> 4), (g << 2) | (g >> 4), (b << 2) | (b >> 4), + gl_paltonemap_reverselookup, gl_paltonemap_powtable, 0, 256)]; + int index = ((r * 64 + g) * 64 + b) * 4; + lut[index] = color.r; + lut[index + 1] = color.g; + lut[index + 2] = color.b; + lut[index + 3] = 255; + } + } + } + + texture = { 512, 512, PixelFormat::Rgba8, data }; + } + } +} + +void PPTonemap::UpdateSteps() +{ + if (gl_tonemap == 0) + { + hw_postprocess.Effects["TonemapScene"] = {}; + return; + } + + PPShaderName shader; + switch (gl_tonemap) + { + default: + case Linear: shader = "Tonemap.Linear"; break; + case Reinhard: shader = "Tonemap.Reinhard"; break; + case HejlDawson: shader = "Tonemap.HejlDawson"; break; + case Uncharted2: shader = "Tonemap.Uncharted2"; break; + case Palette: shader = "Tonemap.Palette"; break; + } + + PPStep step; + step.ShaderName = shader; + step.Viewport = screen->mScreenViewport; + step.SetInputCurrent(0); + if (gl_tonemap == Palette) + step.SetInputTexture(1, "Tonemap.Palette"); + step.SetOutputNext(); + step.SetNoBlend(); + + TArray steps; + steps.Push(step); + hw_postprocess.Effects["TonemapScene"] = steps; +} diff --git a/src/hwrenderer/postprocessing/hw_postprocess.h b/src/hwrenderer/postprocessing/hw_postprocess.h index 909a8fc33..f2801e697 100644 --- a/src/hwrenderer/postprocessing/hw_postprocess.h +++ b/src/hwrenderer/postprocessing/hw_postprocess.h @@ -179,11 +179,12 @@ class PPTextureDesc { public: PPTextureDesc() { } - PPTextureDesc(int width, int height, PixelFormat format) : Width(width), Height(height), Format(format) { } + PPTextureDesc(int width, int height, PixelFormat format, std::shared_ptr data = {}) : Width(width), Height(height), Format(format), Data(data) { } int Width; int Height; PixelFormat Format; + std::shared_ptr Data; }; class PPShader @@ -411,3 +412,24 @@ public: void DeclareShaders(); void UpdateSteps(int fixedcm); }; + +///////////////////////////////////////////////////////////////////////////// + +class PPTonemap +{ +public: + void DeclareShaders(); + void UpdateTextures(); + void UpdateSteps(); + + enum TonemapMode + { + None, + Uncharted2, + HejlDawson, + Reinhard, + Linear, + Palette, + NumTonemapModes + }; +}; diff --git a/src/hwrenderer/postprocessing/hw_tonemapshader.cpp b/src/hwrenderer/postprocessing/hw_tonemapshader.cpp deleted file mode 100644 index 487059d06..000000000 --- a/src/hwrenderer/postprocessing/hw_tonemapshader.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2016 Magnus Norddahl -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// -/* -** gl_tonemapshader.cpp -** Converts a HDR texture to 0-1 range by applying a tonemap operator -** -*/ - -#include "v_video.h" -#include "hwrenderer/utility/hw_cvars.h" -#include "hw_tonemapshader.h" - -void FTonemapShader::Bind(IRenderQueue *q) -{ - auto &shader = mShader[gl_tonemap]; - if (!shader) - { - auto prolog = GetDefines(gl_tonemap); - - shader.reset(screen->CreateShaderProgram()); - shader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); - shader->Compile(IShaderProgram::Fragment, "shaders/glsl/tonemap.fp", prolog, 330); - shader->Link("shaders/glsl/tonemap"); - } - shader->Bind(q); -} - -bool FTonemapShader::IsPaletteMode() -{ - return gl_tonemap == Palette; -} - -const char *FTonemapShader::GetDefines(int mode) -{ - switch (mode) - { - default: - case Linear: return "#define LINEAR\n"; - case Reinhard: return "#define REINHARD\n"; - case HejlDawson: return "#define HEJLDAWSON\n"; - case Uncharted2: return "#define UNCHARTED2\n"; - case Palette: return "#define PALETTE\n"; - } -} diff --git a/src/hwrenderer/postprocessing/hw_tonemapshader.h b/src/hwrenderer/postprocessing/hw_tonemapshader.h deleted file mode 100644 index e3fa037e6..000000000 --- a/src/hwrenderer/postprocessing/hw_tonemapshader.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __GL_TONEMAPSHADER_H -#define __GL_TONEMAPSHADER_H - -#include "hwrenderer/postprocessing/hw_shaderprogram.h" - -class FTonemapShader -{ -public: - void Bind(IRenderQueue *q); - - static bool IsPaletteMode(); - -private: - enum TonemapMode - { - None, - Uncharted2, - HejlDawson, - Reinhard, - Linear, - Palette, - NumTonemapModes - }; - - static const char *GetDefines(int mode); - - std::unique_ptr mShader[NumTonemapModes]; -}; - -#endif \ No newline at end of file diff --git a/wadsrc/static/shaders/glsl/tonemap.fp b/wadsrc/static/shaders/glsl/tonemap.fp index 0e9c4096a..29d52cd45 100644 --- a/wadsrc/static/shaders/glsl/tonemap.fp +++ b/wadsrc/static/shaders/glsl/tonemap.fp @@ -3,7 +3,6 @@ in vec2 TexCoord; layout(location=0) out vec4 FragColor; layout(binding=0) uniform sampler2D InputTexture; -layout(binding=1) uniform sampler2D ExposureTexture; vec3 Linear(vec3 c) { @@ -65,15 +64,16 @@ vec3 Tonemap(vec3 color) #elif defined(PALETTE) -layout(binding=2) uniform sampler2D PaletteLUT; +layout(binding=1) uniform sampler2D PaletteLUT; vec3 Tonemap(vec3 color) { - ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 63.0 + 0.5); + /*ivec3 c = ivec3(clamp(color.rgb, vec3(0.0), vec3(1.0)) * 63.0 + 0.5); int index = (c.r * 64 + c.g) * 64 + c.b; int tx = index % 512; int ty = index / 512; - return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb; + return texelFetch(PaletteLUT, ivec2(tx, ty), 0).rgb;*/ + return texture(PaletteLUT, TexCoord).rgb; } #else @@ -84,8 +84,6 @@ void main() { vec3 color = texture(InputTexture, TexCoord).rgb; #ifndef PALETTE - float exposureAdjustment = texture(ExposureTexture, vec2(0.5)).x; - color = color * exposureAdjustment; color = Linear(color); // needed because gzdoom's scene texture is not linear at the moment #endif FragColor = vec4(Tonemap(color), 1.0);