- Simplify FGLRenderer::PostProcessScene

This commit is contained in:
Magnus Norddahl 2018-06-29 21:55:46 +02:00
parent a7529ce3b4
commit ecb5d69ae3
6 changed files with 290 additions and 275 deletions

View file

@ -57,182 +57,31 @@ void FGLRenderer::RenderScreenQuad()
void FGLRenderer::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) void FGLRenderer::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
{ {
hw_postprocess.fixedcm = fixedcm;
hw_postprocess.SceneWidth = mBuffers->GetSceneWidth();
hw_postprocess.SceneHeight = mBuffers->GetSceneHeight();
hw_postprocess.DeclareShaders();
hw_postprocess.UpdateTextures();
hw_postprocess.UpdateSteps();
mBuffers->BlitSceneToTexture(); mBuffers->BlitSceneToTexture();
UpdateCameraExposure();
mBuffers->CompileEffectShaders();
mBuffers->UpdateEffectTextures();
mBuffers->RenderEffect("UpdateCameraExposure");
mCustomPostProcessShaders->Run("beforebloom"); mCustomPostProcessShaders->Run("beforebloom");
BloomScene(fixedcm); mBuffers->RenderEffect("BloomScene");
mBuffers->BindCurrentFB(); mBuffers->BindCurrentFB();
afterBloomDrawEndScene2D(); afterBloomDrawEndScene2D();
TonemapScene(); mBuffers->RenderEffect("TonemapScene");
ColormapScene(fixedcm); mBuffers->RenderEffect("ColormapScene");
LensDistortScene(); mBuffers->RenderEffect("LensDistortScene");
ApplyFXAA(); mBuffers->RenderEffect("ApplyFXAA");
mCustomPostProcessShaders->Run("scene"); mCustomPostProcessShaders->Run("scene");
} }
void FGLRenderBuffers::RenderEffect(const FString &name)
{
// Create/update textures (To do: move out of RunEffect)
{
TMap<FString, PPTextureDesc>::Iterator it(hw_postprocess.Textures);
TMap<FString, PPTextureDesc>::Pair *pair;
while (it.NextPair(pair))
{
auto &gltexture = GLTextures[pair->Key];
auto &glframebuffer = GLTextureFBs[pair->Key];
int glformat;
switch (pair->Value.Format)
{
default:
case PixelFormat::Rgba8: glformat = GL_RGBA8; break;
case PixelFormat::Rgba16f: glformat = GL_RGBA16F; break;
case PixelFormat::R32f: glformat = GL_R32F; break;
}
if (gltexture && (gltexture.Width != pair->Value.Width || gltexture.Height != pair->Value.Height))
{
glDeleteTextures(1, &gltexture.handle);
glDeleteFramebuffers(1, &glframebuffer.handle);
gltexture.handle = 0;
glframebuffer.handle = 0;
}
if (!gltexture)
{
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(pair->Key.GetChars(), gltexture);
}
}
}
// Compile shaders (To do: move out of RunEffect)
{
TMap<FString, PPShader>::Iterator it(hw_postprocess.Shaders);
TMap<FString, PPShader>::Pair *pair;
while (it.NextPair(pair))
{
const auto &desc = pair->Value;
auto &glshader = GLShaders[pair->Key];
if (!glshader)
{
glshader = std::make_unique<FShaderProgram>();
FString prolog;
if (!desc.Uniforms.empty())
prolog = UniformBlockDecl::Create("Uniforms", desc.Uniforms, POSTPROCESS_BINDINGPOINT);
prolog += desc.Defines;
glshader->Compile(IShaderProgram::Vertex, desc.VertexShader, "", desc.Version);
glshader->Compile(IShaderProgram::Fragment, desc.FragmentShader, prolog, desc.Version);
glshader->Link(pair->Key.GetChars());
if (!desc.Uniforms.empty())
glshader->SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
}
}
}
// Render the effect
FGLDebug::PushGroup(name.GetChars());
FGLPostProcessState savedState;
savedState.SaveTextureBindings(3);
for (const PPStep &step : hw_postprocess.Effects[name])
{
// Bind input textures
for (unsigned int index = 0; index < step.Textures.Size(); index++)
{
const PPTextureInput &input = step.Textures[index];
int filter = (input.Filter == PPFilterMode::Nearest) ? GL_NEAREST : GL_LINEAR;
switch (input.Type)
{
default:
case PPTextureType::CurrentPipelineTexture:
BindCurrentTexture(index, filter);
break;
case PPTextureType::NextPipelineTexture:
I_FatalError("PPTextureType::NextPipelineTexture not allowed as input\n");
break;
case PPTextureType::PPTexture:
GLTextures[input.Texture].Bind(index, filter);
break;
}
}
// Set render target
switch (step.Output.Type)
{
default:
case PPTextureType::CurrentPipelineTexture:
BindCurrentFB();
break;
case PPTextureType::NextPipelineTexture:
BindNextFB();
break;
case PPTextureType::PPTexture:
GLTextureFBs[step.Output.Texture].Bind();
break;
}
// Set blend mode
if (step.BlendMode.BlendOp == STYLEOP_Add && step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_Zero && step.BlendMode.Flags == 0)
{
glDisable(GL_BLEND);
}
else
{
// To do: support all the modes
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
if (step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_One)
glBlendFunc(GL_ONE, GL_ONE);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
// Setup viewport
glViewport(step.Viewport.left, step.Viewport.top, step.Viewport.width, step.Viewport.height);
auto &shader = GLShaders[step.ShaderName];
// Set uniforms
if (step.Uniforms.Size > 0)
{
if (!shader->Uniforms)
shader->Uniforms.reset(screen->CreateUniformBuffer(step.Uniforms.Size));
shader->Uniforms->SetData(step.Uniforms.Data);
shader->Uniforms->Bind(POSTPROCESS_BINDINGPOINT);
}
// Set shader
shader->Bind(NOQUEUE);
// Draw the screen quad
GLRenderer->RenderScreenQuad();
// Advance to next PP texture if our output was sent there
if (step.Output.Type == PPTextureType::NextPipelineTexture)
NextTexture();
}
glViewport(screen->mScreenViewport.left, screen->mScreenViewport.top, screen->mScreenViewport.width, screen->mScreenViewport.height);
FGLDebug::PopGroup();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// Adds ambient occlusion to the scene // Adds ambient occlusion to the scene
@ -345,77 +194,25 @@ void FGLRenderer::AmbientOccludeScene(float m5)
FGLDebug::PopGroup(); FGLDebug::PopGroup();
} }
void FGLRenderer::UpdateCameraExposure()
{
PPCameraExposure exposure;
exposure.DeclareShaders();
exposure.UpdateTextures(mBuffers->GetSceneWidth(), mBuffers->GetSceneHeight());
exposure.UpdateSteps();
mBuffers->RenderEffect("UpdateCameraExposure");
}
void FGLRenderer::BloomScene(int fixedcm)
{
if (mBuffers->GetSceneWidth() <= 0 || mBuffers->GetSceneHeight() <= 0)
return;
PPBloom bloom;
bloom.DeclareShaders();
bloom.UpdateTextures(mBuffers->GetSceneWidth(), mBuffers->GetSceneHeight());
bloom.UpdateSteps(fixedcm);
mBuffers->RenderEffect("BloomScene");
}
void FGLRenderer::BlurScene(float gameinfobluramount) void FGLRenderer::BlurScene(float gameinfobluramount)
{ {
if (mBuffers->GetSceneWidth() <= 0 || mBuffers->GetSceneHeight() <= 0) hw_postprocess.gameinfobluramount = gameinfobluramount;
return;
hw_postprocess.DeclareShaders();
hw_postprocess.UpdateTextures();
hw_postprocess.UpdateSteps();
mBuffers->CompileEffectShaders();
mBuffers->UpdateEffectTextures();
PPBloom blur;
blur.DeclareShaders();
blur.UpdateTextures(mBuffers->GetSceneWidth(), mBuffers->GetSceneHeight());
blur.UpdateBlurSteps(gameinfobluramount);
mBuffers->RenderEffect("BlurScene"); mBuffers->RenderEffect("BlurScene");
} }
void FGLRenderer::TonemapScene()
{
PPTonemap tonemap;
tonemap.DeclareShaders();
tonemap.UpdateTextures();
tonemap.UpdateSteps();
mBuffers->RenderEffect("TonemapScene");
}
void FGLRenderer::ClearTonemapPalette() void FGLRenderer::ClearTonemapPalette()
{ {
hw_postprocess.Textures.Remove("Tonemap.Palette"); hw_postprocess.Textures.Remove("Tonemap.Palette");
} }
void FGLRenderer::ColormapScene(int fixedcm)
{
PPColormap colormap;
colormap.DeclareShaders();
colormap.UpdateSteps(fixedcm);
mBuffers->RenderEffect("ColormapScene");
}
void FGLRenderer::LensDistortScene()
{
PPLensDistort lens;
lens.DeclareShaders();
lens.UpdateSteps();
mBuffers->RenderEffect("LensDistortScene");
}
void FGLRenderer::ApplyFXAA()
{
PPFXAA fxaa;
fxaa.DeclareShaders();
fxaa.UpdateSteps();
mBuffers->RenderEffect("ApplyFXAA");
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// Copies the rendered screen to its final destination // Copies the rendered screen to its final destination

View file

@ -32,6 +32,8 @@
#include "gl/system/gl_debug.h" #include "gl/system/gl_debug.h"
#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_renderbuffers.h" #include "gl/renderer/gl_renderbuffers.h"
#include "gl/renderer/gl_postprocessstate.h"
#include "gl/shaders/gl_shaderprogram.h"
#include <random> #include <random>
CVAR(Int, gl_multisample, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); CVAR(Int, gl_multisample, 1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
@ -586,13 +588,6 @@ 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
@ -818,3 +813,183 @@ void FGLRenderBuffers::BindOutputFB()
//========================================================================== //==========================================================================
bool FGLRenderBuffers::FailedCreate = false; bool FGLRenderBuffers::FailedCreate = false;
//==========================================================================
//
// Creates or updates textures used by postprocess effects
//
//==========================================================================
void FGLRenderBuffers::UpdateEffectTextures()
{
TMap<FString, PPTextureDesc>::Iterator it(hw_postprocess.Textures);
TMap<FString, PPTextureDesc>::Pair *pair;
while (it.NextPair(pair))
{
auto &gltexture = GLTextures[pair->Key];
auto &glframebuffer = GLTextureFBs[pair->Key];
int glformat;
switch (pair->Value.Format)
{
default:
case PixelFormat::Rgba8: glformat = GL_RGBA8; break;
case PixelFormat::Rgba16f: glformat = GL_RGBA16F; break;
case PixelFormat::R32f: glformat = GL_R32F; break;
}
if (gltexture && (gltexture.Width != pair->Value.Width || gltexture.Height != pair->Value.Height))
{
glDeleteTextures(1, &gltexture.handle);
glDeleteFramebuffers(1, &glframebuffer.handle);
gltexture.handle = 0;
glframebuffer.handle = 0;
}
if (!gltexture)
{
FGLPostProcessState savedState;
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(pair->Key.GetChars(), gltexture);
}
}
}
//==========================================================================
//
// Compile the shaders declared by post process effects
//
//==========================================================================
void FGLRenderBuffers::CompileEffectShaders()
{
TMap<FString, PPShader>::Iterator it(hw_postprocess.Shaders);
TMap<FString, PPShader>::Pair *pair;
while (it.NextPair(pair))
{
const auto &desc = pair->Value;
auto &glshader = GLShaders[pair->Key];
if (!glshader)
{
glshader = std::make_unique<FShaderProgram>();
FString prolog;
if (!desc.Uniforms.empty())
prolog = UniformBlockDecl::Create("Uniforms", desc.Uniforms, POSTPROCESS_BINDINGPOINT);
prolog += desc.Defines;
glshader->Compile(IShaderProgram::Vertex, desc.VertexShader, "", desc.Version);
glshader->Compile(IShaderProgram::Fragment, desc.FragmentShader, prolog, desc.Version);
glshader->Link(pair->Key.GetChars());
if (!desc.Uniforms.empty())
glshader->SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms");
}
}
}
//==========================================================================
//
// Renders one post process effect
//
//==========================================================================
void FGLRenderBuffers::RenderEffect(const FString &name)
{
FGLDebug::PushGroup(name.GetChars());
FGLPostProcessState savedState;
savedState.SaveTextureBindings(3);
for (const PPStep &step : hw_postprocess.Effects[name])
{
// Bind input textures
for (unsigned int index = 0; index < step.Textures.Size(); index++)
{
const PPTextureInput &input = step.Textures[index];
int filter = (input.Filter == PPFilterMode::Nearest) ? GL_NEAREST : GL_LINEAR;
switch (input.Type)
{
default:
case PPTextureType::CurrentPipelineTexture:
BindCurrentTexture(index, filter);
break;
case PPTextureType::NextPipelineTexture:
I_FatalError("PPTextureType::NextPipelineTexture not allowed as input\n");
break;
case PPTextureType::PPTexture:
GLTextures[input.Texture].Bind(index, filter);
break;
}
}
// Set render target
switch (step.Output.Type)
{
default:
case PPTextureType::CurrentPipelineTexture:
BindCurrentFB();
break;
case PPTextureType::NextPipelineTexture:
BindNextFB();
break;
case PPTextureType::PPTexture:
GLTextureFBs[step.Output.Texture].Bind();
break;
}
// Set blend mode
if (step.BlendMode.BlendOp == STYLEOP_Add && step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_Zero && step.BlendMode.Flags == 0)
{
glDisable(GL_BLEND);
}
else
{
// To do: support all the modes
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
if (step.BlendMode.SrcAlpha == STYLEALPHA_One && step.BlendMode.DestAlpha == STYLEALPHA_One)
glBlendFunc(GL_ONE, GL_ONE);
else
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
// Setup viewport
glViewport(step.Viewport.left, step.Viewport.top, step.Viewport.width, step.Viewport.height);
auto &shader = GLShaders[step.ShaderName];
// Set uniforms
if (step.Uniforms.Size > 0)
{
if (!shader->Uniforms)
shader->Uniforms.reset(screen->CreateUniformBuffer(step.Uniforms.Size));
shader->Uniforms->SetData(step.Uniforms.Data);
shader->Uniforms->Bind(POSTPROCESS_BINDINGPOINT);
}
// Set shader
shader->Bind(NOQUEUE);
// Draw the screen quad
GLRenderer->RenderScreenQuad();
// Advance to next PP texture if our output was sent there
if (step.Output.Type == PPTextureType::NextPipelineTexture)
NextTexture();
}
glViewport(screen->mScreenViewport.left, screen->mScreenViewport.top, screen->mScreenViewport.width, screen->mScreenViewport.height);
FGLDebug::PopGroup();
}

View file

@ -64,6 +64,8 @@ public:
bool Setup(int width, int height, int sceneWidth, int sceneHeight); bool Setup(int width, int height, int sceneWidth, int sceneHeight);
void UpdateEffectTextures();
void CompileEffectShaders();
void RenderEffect(const FString &name); void RenderEffect(const FString &name);
TMap<PPTextureName, PPTexture> GLTextures; TMap<PPTextureName, PPTexture> GLTextures;
@ -77,8 +79,6 @@ public:
void BindSceneDepthTexture(int index); void BindSceneDepthTexture(int index);
void BlitSceneToTexture(); void BlitSceneToTexture();
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 BindCurrentTexture(int index, int filter = GL_NEAREST, int wrap = GL_CLAMP_TO_EDGE);
void BindCurrentFB(); void BindCurrentFB();
void BindNextFB(); void BindNextFB();
@ -107,8 +107,6 @@ public:
enum { NumAmbientRandomTextures = 3 }; enum { NumAmbientRandomTextures = 3 };
PPTexture AmbientRandomTexture[NumAmbientRandomTextures]; PPTexture AmbientRandomTexture[NumAmbientRandomTextures];
static bool IsEnabled();
int GetWidth() const { return mWidth; } int GetWidth() const { return mWidth; }
int GetHeight() const { return mHeight; } int GetHeight() const { return mHeight; }

View file

@ -108,13 +108,7 @@ public:
void RenderScreenQuad(); void RenderScreenQuad();
void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D); void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D);
void AmbientOccludeScene(float m5); void AmbientOccludeScene(float m5);
void UpdateCameraExposure();
void BloomScene(int fixedcm);
void TonemapScene();
void ColormapScene(int fixedcm);
void ClearTonemapPalette(); void ClearTonemapPalette();
void LensDistortScene();
void ApplyFXAA();
void BlurScene(float gameinfobluramount); void BlurScene(float gameinfobluramount);
void CopyToBackbuffer(const IntRect *bounds, bool applyGamma); void CopyToBackbuffer(const IntRect *bounds, bool applyGamma);
void DrawPresentTexture(const IntRect &box, bool applyGamma); void DrawPresentTexture(const IntRect &box, bool applyGamma);

View file

@ -6,6 +6,24 @@
Postprocess hw_postprocess; Postprocess hw_postprocess;
Postprocess::Postprocess()
{
Managers.Push(new PPBloom());
Managers.Push(new PPLensDistort());
Managers.Push(new PPFXAA());
Managers.Push(new PPCameraExposure());
Managers.Push(new PPColormap());
Managers.Push(new PPTonemap());
}
Postprocess::~Postprocess()
{
for (unsigned int i = 0; i < Managers.Size(); i++)
delete Managers[i];
}
/////////////////////////////////////////////////////////////////////////////
void PPBloom::DeclareShaders() void PPBloom::DeclareShaders()
{ {
hw_postprocess.Shaders["BloomCombine"] = { "shaders/glsl/bloomcombine.fp", "", {} }; hw_postprocess.Shaders["BloomCombine"] = { "shaders/glsl/bloomcombine.fp", "", {} };
@ -14,8 +32,11 @@ void PPBloom::DeclareShaders()
hw_postprocess.Shaders["BlurHorizontal"] = { "shaders/glsl/blur.fp", "#define BLUR_HORIZONTAL\n", BlurUniforms::Desc() }; hw_postprocess.Shaders["BlurHorizontal"] = { "shaders/glsl/blur.fp", "#define BLUR_HORIZONTAL\n", BlurUniforms::Desc() };
} }
void PPBloom::UpdateTextures(int width, int height) void PPBloom::UpdateTextures()
{ {
int width = hw_postprocess.SceneWidth;
int height = hw_postprocess.SceneHeight;
// No scene, no bloom! // No scene, no bloom!
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
return; return;
@ -42,10 +63,12 @@ void PPBloom::UpdateTextures(int width, int height)
} }
} }
void PPBloom::UpdateSteps(int fixedcm) void PPBloom::UpdateSteps()
{ {
UpdateBlurSteps();
// Only bloom things if enabled and no special fixed light mode is active // Only bloom things if enabled and no special fixed light mode is active
if (!gl_bloom || fixedcm != CM_DEFAULT || gl_ssao_debug) if (!gl_bloom || hw_postprocess.fixedcm != CM_DEFAULT || gl_ssao_debug || hw_postprocess.SceneWidth <= 0 || hw_postprocess.SceneHeight <= 0)
{ {
hw_postprocess.Effects["BloomScene"] = {}; hw_postprocess.Effects["BloomScene"] = {};
return; return;
@ -117,14 +140,14 @@ void PPBloom::UpdateSteps(int fixedcm)
hw_postprocess.Effects["BloomScene"] = steps; hw_postprocess.Effects["BloomScene"] = steps;
} }
void PPBloom::UpdateBlurSteps(float gameinfobluramount) void PPBloom::UpdateBlurSteps()
{ {
// first, respect the CVar // first, respect the CVar
float blurAmount = gl_menu_blur; float blurAmount = gl_menu_blur;
// if CVar is negative, use the gameinfo entry // if CVar is negative, use the gameinfo entry
if (gl_menu_blur < 0) if (gl_menu_blur < 0)
blurAmount = gameinfobluramount; blurAmount = hw_postprocess.gameinfobluramount;
// if blurAmount == 0 or somehow still returns negative, exit to prevent a crash, clearly we don't want this // if blurAmount == 0 or somehow still returns negative, exit to prevent a crash, clearly we don't want this
if (blurAmount <= 0.0) if (blurAmount <= 0.0)
@ -377,8 +400,11 @@ void PPCameraExposure::DeclareShaders()
hw_postprocess.Shaders["ExposureCombine"] = { "shaders/glsl/exposurecombine.fp", "", ExposureCombineUniforms::Desc() }; hw_postprocess.Shaders["ExposureCombine"] = { "shaders/glsl/exposurecombine.fp", "", ExposureCombineUniforms::Desc() };
} }
void PPCameraExposure::UpdateTextures(int width, int height) void PPCameraExposure::UpdateTextures()
{ {
int width = hw_postprocess.SceneWidth;
int height = hw_postprocess.SceneHeight;
if (ExposureLevels.Size() > 0 && ExposureLevels[0].Viewport.width == width && ExposureLevels[0].Viewport.height == height) if (ExposureLevels.Size() > 0 && ExposureLevels[0].Viewport.width == width && ExposureLevels[0].Viewport.height == height)
{ {
return; return;
@ -486,8 +512,10 @@ void PPColormap::DeclareShaders()
hw_postprocess.Shaders["Colormap"] = { "shaders/glsl/colormap.fp", "", ColormapUniforms::Desc() }; hw_postprocess.Shaders["Colormap"] = { "shaders/glsl/colormap.fp", "", ColormapUniforms::Desc() };
} }
void PPColormap::UpdateSteps(int fixedcm) void PPColormap::UpdateSteps()
{ {
int fixedcm = hw_postprocess.fixedcm;
if (fixedcm < CM_FIRSTSPECIALCOLORMAP || fixedcm >= CM_MAXCOLORMAP) if (fixedcm < CM_FIRSTSPECIALCOLORMAP || fixedcm >= CM_MAXCOLORMAP)
{ {
hw_postprocess.Effects["ColormapScene"] = {}; hw_postprocess.Effects["ColormapScene"] = {};

View file

@ -201,12 +201,34 @@ public:
int Version = 330; int Version = 330;
}; };
class PPEffectManager
{
public:
virtual void DeclareShaders() { }
virtual void UpdateTextures() { }
virtual void UpdateSteps() { }
};
class Postprocess class Postprocess
{ {
public: public:
Postprocess();
~Postprocess();
void DeclareShaders() { for (unsigned int i = 0; i < Managers.Size(); i++) Managers[i]->DeclareShaders(); }
void UpdateTextures() { for (unsigned int i = 0; i < Managers.Size(); i++) Managers[i]->UpdateTextures(); }
void UpdateSteps() { for (unsigned int i = 0; i < Managers.Size(); i++) Managers[i]->UpdateSteps(); }
int SceneWidth = 0;
int SceneHeight = 0;
int fixedcm;
float gameinfobluramount;
TMap<FString, TArray<PPStep>> Effects; TMap<FString, TArray<PPStep>> Effects;
TMap<FString, PPTextureDesc> Textures; TMap<FString, PPTextureDesc> Textures;
TMap<FString, PPShader> Shaders; TMap<FString, PPShader> Shaders;
TArray<PPEffectManager*> Managers;
}; };
extern Postprocess hw_postprocess; extern Postprocess hw_postprocess;
@ -258,15 +280,16 @@ public:
PPTextureName HTexture; PPTextureName HTexture;
}; };
class PPBloom class PPBloom : public PPEffectManager
{ {
public: public:
void DeclareShaders(); void DeclareShaders() override;
void UpdateTextures(int sceneWidth, int sceneHeight); void UpdateTextures() override;
void UpdateSteps(int fixedcm); void UpdateSteps() override;
void UpdateBlurSteps(float gameinfobluramount);
private: private:
void UpdateBlurSteps();
PPStep BlurStep(const BlurUniforms &blurUniforms, PPTextureName input, PPTextureName output, PPViewport viewport, bool vertical); PPStep BlurStep(const BlurUniforms &blurUniforms, PPTextureName input, PPTextureName output, PPViewport viewport, bool vertical);
static float ComputeBlurGaussian(float n, float theta); static float ComputeBlurGaussian(float n, float theta);
@ -299,11 +322,11 @@ struct LensUniforms
} }
}; };
class PPLensDistort class PPLensDistort : public PPEffectManager
{ {
public: public:
void DeclareShaders(); void DeclareShaders() override;
void UpdateSteps(); void UpdateSteps() override;
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -324,11 +347,11 @@ struct FXAAUniforms
} }
}; };
class PPFXAA class PPFXAA : public PPEffectManager
{ {
public: public:
void DeclareShaders(); void DeclareShaders() override;
void UpdateSteps(); void UpdateSteps() override;
private: private:
int GetMaxVersion(); int GetMaxVersion();
@ -378,12 +401,12 @@ public:
PPTextureName Texture; PPTextureName Texture;
}; };
class PPCameraExposure class PPCameraExposure : public PPEffectManager
{ {
public: public:
void DeclareShaders(); void DeclareShaders() override;
void UpdateTextures(int sceneWidth, int sceneHeight); void UpdateTextures() override;
void UpdateSteps(); void UpdateSteps() override;
private: private:
TArray<PPExposureLevel> ExposureLevels; TArray<PPExposureLevel> ExposureLevels;
@ -407,21 +430,21 @@ struct ColormapUniforms
} }
}; };
class PPColormap class PPColormap : public PPEffectManager
{ {
public: public:
void DeclareShaders(); void DeclareShaders() override;
void UpdateSteps(int fixedcm); void UpdateSteps() override;
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
class PPTonemap class PPTonemap : public PPEffectManager
{ {
public: public:
void DeclareShaders(); void DeclareShaders() override;
void UpdateTextures(); void UpdateTextures() override;
void UpdateSteps(); void UpdateSteps() override;
enum TonemapMode enum TonemapMode
{ {