mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-13 07:57:51 +00:00
- write OpenGL backend for hw_postprocess (FGLRenderBuffers::RenderEffect)
- remove old fxaa and lens shader classes - render the fxaa and lens effects
This commit is contained in:
parent
e3997d5f11
commit
151ed22967
13 changed files with 270 additions and 319 deletions
|
@ -1072,8 +1072,6 @@ set (PCH_SOURCES
|
||||||
hwrenderer/postprocessing/hw_blurshader.cpp
|
hwrenderer/postprocessing/hw_blurshader.cpp
|
||||||
hwrenderer/postprocessing/hw_colormapshader.cpp
|
hwrenderer/postprocessing/hw_colormapshader.cpp
|
||||||
hwrenderer/postprocessing/hw_tonemapshader.cpp
|
hwrenderer/postprocessing/hw_tonemapshader.cpp
|
||||||
hwrenderer/postprocessing/hw_lensshader.cpp
|
|
||||||
hwrenderer/postprocessing/hw_fxaashader.cpp
|
|
||||||
hwrenderer/textures/hw_material.cpp
|
hwrenderer/textures/hw_material.cpp
|
||||||
hwrenderer/textures/hw_precache.cpp
|
hwrenderer/textures/hw_precache.cpp
|
||||||
hwrenderer/utility/hw_clock.cpp
|
hwrenderer/utility/hw_clock.cpp
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
#include "hwrenderer/postprocessing/hw_blurshader.h"
|
#include "hwrenderer/postprocessing/hw_blurshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_tonemapshader.h"
|
#include "hwrenderer/postprocessing/hw_tonemapshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_colormapshader.h"
|
#include "hwrenderer/postprocessing/hw_colormapshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_lensshader.h"
|
|
||||||
#include "hwrenderer/postprocessing/hw_fxaashader.h"
|
|
||||||
#include "hwrenderer/postprocessing/hw_presentshader.h"
|
#include "hwrenderer/postprocessing/hw_presentshader.h"
|
||||||
|
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||||
|
#include "hwrenderer/postprocessing/hw_postprocess_cvars.h"
|
||||||
#include "gl/shaders/gl_postprocessshaderinstance.h"
|
#include "gl/shaders/gl_postprocessshaderinstance.h"
|
||||||
#include "gl/stereo3d/gl_stereo3d.h"
|
#include "gl/stereo3d/gl_stereo3d.h"
|
||||||
#include "gl/textures/gl_hwtexture.h"
|
#include "gl/textures/gl_hwtexture.h"
|
||||||
|
@ -74,6 +74,164 @@ void FGLRenderer::PostProcessScene(int fixedcm, const std::function<void()> &aft
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
gltexture = Create2DTexture(name.GetChars(), glformat, pair->Value.Width, pair->Value.Height);
|
||||||
|
gltexture.Width = pair->Value.Width;
|
||||||
|
gltexture.Height = pair->Value.Height;
|
||||||
|
glframebuffer = CreateFrameBuffer(name.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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -304,6 +462,18 @@ static void RenderBlur(FGLRenderer *renderer, float blurAmount, PPTexture input,
|
||||||
|
|
||||||
void FGLRenderer::BloomScene(int fixedcm)
|
void FGLRenderer::BloomScene(int fixedcm)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
if (mBuffers->GetSceneWidth() <= 0 || mBuffers->GetSceneHeight() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PPBloom bloom;
|
||||||
|
bloom.DeclareShaders();
|
||||||
|
bloom.UpdateTextures(mBuffers->GetSceneWidth(), mBuffers->GetSceneHeight());
|
||||||
|
bloom.UpdateSteps(fixedcm);
|
||||||
|
mBuffers->RenderEffect("Bloom");
|
||||||
|
|
||||||
|
#else
|
||||||
// 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 || fixedcm != CM_DEFAULT || gl_ssao_debug)
|
||||||
return;
|
return;
|
||||||
|
@ -372,6 +542,7 @@ void FGLRenderer::BloomScene(int fixedcm)
|
||||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -566,6 +737,14 @@ void FGLRenderer::ColormapScene(int fixedcm)
|
||||||
|
|
||||||
void FGLRenderer::LensDistortScene()
|
void FGLRenderer::LensDistortScene()
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
PPLensDistort lens;
|
||||||
|
lens.DeclareShaders();
|
||||||
|
lens.UpdateSteps();
|
||||||
|
mBuffers->RenderEffect("LensDistortScene");
|
||||||
|
|
||||||
|
#else
|
||||||
if (gl_lens == 0)
|
if (gl_lens == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -610,6 +789,7 @@ void FGLRenderer::LensDistortScene()
|
||||||
mBuffers->NextTexture();
|
mBuffers->NextTexture();
|
||||||
|
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -620,6 +800,15 @@ void FGLRenderer::LensDistortScene()
|
||||||
|
|
||||||
void FGLRenderer::ApplyFXAA()
|
void FGLRenderer::ApplyFXAA()
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
PPFXAA fxaa;
|
||||||
|
fxaa.DeclareShaders();
|
||||||
|
fxaa.UpdateSteps();
|
||||||
|
mBuffers->RenderEffect("ApplyFXAA");
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
if (0 == gl_fxaa)
|
if (0 == gl_fxaa)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -644,6 +833,8 @@ void FGLRenderer::ApplyFXAA()
|
||||||
mBuffers->NextTexture();
|
mBuffers->NextTexture();
|
||||||
|
|
||||||
FGLDebug::PopGroup();
|
FGLDebug::PopGroup();
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __GL_RENDERBUFFERS_H
|
#define __GL_RENDERBUFFERS_H
|
||||||
|
|
||||||
#include "gl/shaders/gl_shader.h"
|
#include "gl/shaders/gl_shader.h"
|
||||||
|
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||||
|
|
||||||
class PPTexture
|
class PPTexture
|
||||||
{
|
{
|
||||||
|
@ -16,6 +17,11 @@ public:
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Width = -1;
|
||||||
|
int Height = -1;
|
||||||
|
|
||||||
|
explicit operator bool() const { return handle != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint handle = 0;
|
GLuint handle = 0;
|
||||||
|
|
||||||
|
@ -30,6 +36,8 @@ public:
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, handle);
|
glBindFramebuffer(GL_FRAMEBUFFER, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const { return handle != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint handle = 0;
|
GLuint handle = 0;
|
||||||
|
|
||||||
|
@ -41,6 +49,8 @@ class PPRenderBuffer
|
||||||
private:
|
private:
|
||||||
GLuint handle = 0;
|
GLuint handle = 0;
|
||||||
|
|
||||||
|
explicit operator bool() const { return handle != 0; }
|
||||||
|
|
||||||
friend class FGLRenderBuffers;
|
friend class FGLRenderBuffers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,6 +74,8 @@ public:
|
||||||
int Height = 0;
|
int Height = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FShaderProgram;
|
||||||
|
|
||||||
class FGLRenderBuffers
|
class FGLRenderBuffers
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -72,6 +84,12 @@ public:
|
||||||
|
|
||||||
bool Setup(int width, int height, int sceneWidth, int sceneHeight);
|
bool Setup(int width, int height, int sceneWidth, int sceneHeight);
|
||||||
|
|
||||||
|
void RenderEffect(const FString &name);
|
||||||
|
|
||||||
|
TMap<PPTextureName, PPTexture> GLTextures;
|
||||||
|
TMap<PPTextureName, PPFrameBuffer> GLTextureFBs;
|
||||||
|
TMap<PPShaderName, std::shared_ptr<FShaderProgram>> GLShaders;
|
||||||
|
|
||||||
void BindSceneFB(bool sceneData);
|
void BindSceneFB(bool sceneData);
|
||||||
void BindSceneColorTexture(int index);
|
void BindSceneColorTexture(int index);
|
||||||
void BindSceneFogTexture(int index);
|
void BindSceneFogTexture(int index);
|
||||||
|
|
|
@ -55,8 +55,6 @@
|
||||||
#include "hwrenderer/postprocessing/hw_blurshader.h"
|
#include "hwrenderer/postprocessing/hw_blurshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_tonemapshader.h"
|
#include "hwrenderer/postprocessing/hw_tonemapshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_colormapshader.h"
|
#include "hwrenderer/postprocessing/hw_colormapshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_lensshader.h"
|
|
||||||
#include "hwrenderer/postprocessing/hw_fxaashader.h"
|
|
||||||
#include "hwrenderer/postprocessing/hw_presentshader.h"
|
#include "hwrenderer/postprocessing/hw_presentshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_present3dRowshader.h"
|
#include "hwrenderer/postprocessing/hw_present3dRowshader.h"
|
||||||
#include "hwrenderer/postprocessing/hw_shadowmapshader.h"
|
#include "hwrenderer/postprocessing/hw_shadowmapshader.h"
|
||||||
|
@ -112,13 +110,10 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
||||||
mTonemapShader = nullptr;
|
mTonemapShader = nullptr;
|
||||||
mTonemapPalette = nullptr;
|
mTonemapPalette = nullptr;
|
||||||
mColormapShader = nullptr;
|
mColormapShader = nullptr;
|
||||||
mLensShader = nullptr;
|
|
||||||
mLinearDepthShader = nullptr;
|
mLinearDepthShader = nullptr;
|
||||||
mDepthBlurShader = nullptr;
|
mDepthBlurShader = nullptr;
|
||||||
mSSAOShader = nullptr;
|
mSSAOShader = nullptr;
|
||||||
mSSAOCombineShader = nullptr;
|
mSSAOCombineShader = nullptr;
|
||||||
mFXAAShader = nullptr;
|
|
||||||
mFXAALumaShader = nullptr;
|
|
||||||
mShadowMapShader = nullptr;
|
mShadowMapShader = nullptr;
|
||||||
mCustomPostProcessShaders = nullptr;
|
mCustomPostProcessShaders = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -141,9 +136,6 @@ void FGLRenderer::Initialize(int width, int height)
|
||||||
mTonemapShader = new FTonemapShader();
|
mTonemapShader = new FTonemapShader();
|
||||||
mColormapShader = new FColormapShader();
|
mColormapShader = new FColormapShader();
|
||||||
mTonemapPalette = nullptr;
|
mTonemapPalette = nullptr;
|
||||||
mLensShader = new FLensShader();
|
|
||||||
mFXAAShader = new FFXAAShader;
|
|
||||||
mFXAALumaShader = new FFXAALumaShader;
|
|
||||||
mPresentShader = new FPresentShader();
|
mPresentShader = new FPresentShader();
|
||||||
mPresent3dCheckerShader = new FPresent3DCheckerShader();
|
mPresent3dCheckerShader = new FPresent3DCheckerShader();
|
||||||
mPresent3dColumnShader = new FPresent3DColumnShader();
|
mPresent3dColumnShader = new FPresent3DColumnShader();
|
||||||
|
@ -207,11 +199,8 @@ FGLRenderer::~FGLRenderer()
|
||||||
if (mTonemapShader) delete mTonemapShader;
|
if (mTonemapShader) delete mTonemapShader;
|
||||||
if (mTonemapPalette) delete mTonemapPalette;
|
if (mTonemapPalette) delete mTonemapPalette;
|
||||||
if (mColormapShader) delete mColormapShader;
|
if (mColormapShader) delete mColormapShader;
|
||||||
if (mLensShader) delete mLensShader;
|
|
||||||
if (mShadowMapShader) delete mShadowMapShader;
|
if (mShadowMapShader) delete mShadowMapShader;
|
||||||
delete mCustomPostProcessShaders;
|
delete mCustomPostProcessShaders;
|
||||||
delete mFXAAShader;
|
|
||||||
delete mFXAALumaShader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -37,9 +37,6 @@ class FExposureCombineShader;
|
||||||
class FBlurShader;
|
class FBlurShader;
|
||||||
class FTonemapShader;
|
class FTonemapShader;
|
||||||
class FColormapShader;
|
class FColormapShader;
|
||||||
class FLensShader;
|
|
||||||
class FFXAALumaShader;
|
|
||||||
class FFXAAShader;
|
|
||||||
class FPresentShader;
|
class FPresentShader;
|
||||||
class FPresent3DCheckerShader;
|
class FPresent3DCheckerShader;
|
||||||
class FPresent3DColumnShader;
|
class FPresent3DColumnShader;
|
||||||
|
@ -93,9 +90,6 @@ public:
|
||||||
FTonemapShader *mTonemapShader;
|
FTonemapShader *mTonemapShader;
|
||||||
FColormapShader *mColormapShader;
|
FColormapShader *mColormapShader;
|
||||||
FHardwareTexture *mTonemapPalette;
|
FHardwareTexture *mTonemapPalette;
|
||||||
FLensShader *mLensShader;
|
|
||||||
FFXAALumaShader *mFXAALumaShader;
|
|
||||||
FFXAAShader *mFXAAShader;
|
|
||||||
FPresentShader *mPresentShader;
|
FPresentShader *mPresentShader;
|
||||||
FPresent3DCheckerShader *mPresent3dCheckerShader;
|
FPresent3DCheckerShader *mPresent3dCheckerShader;
|
||||||
FPresent3DColumnShader *mPresent3dColumnShader;
|
FPresent3DColumnShader *mPresent3dColumnShader;
|
||||||
|
|
|
@ -21,6 +21,8 @@ public:
|
||||||
GLuint Handle() { return mProgram; }
|
GLuint Handle() { return mProgram; }
|
||||||
//explicit operator bool() const { return mProgram != 0; }
|
//explicit operator bool() const { return mProgram != 0; }
|
||||||
|
|
||||||
|
std::unique_ptr<IUniformBuffer> Uniforms;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FShaderProgram(const FShaderProgram &) = delete;
|
FShaderProgram(const FShaderProgram &) = delete;
|
||||||
FShaderProgram &operator=(const FShaderProgram &) = delete;
|
FShaderProgram &operator=(const FShaderProgram &) = delete;
|
||||||
|
|
|
@ -38,6 +38,54 @@ public:
|
||||||
std::size_t Offset;
|
std::size_t Offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UniformBlockDecl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static FString Create(const char *name, const std::vector<UniformFieldDesc> &fields, int bindingpoint)
|
||||||
|
{
|
||||||
|
FString decl;
|
||||||
|
FString layout;
|
||||||
|
if (screen->glslversion < 4.20)
|
||||||
|
{
|
||||||
|
layout = "std140";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layout.Format("std140, binding = %d", bindingpoint);
|
||||||
|
}
|
||||||
|
decl.Format("layout(%s) uniform %s\n{\n", layout.GetChars(), name);
|
||||||
|
for (const auto &field : fields)
|
||||||
|
{
|
||||||
|
decl.AppendFormat("\t%s %s;\n", GetTypeStr(field.Type), field.Name);
|
||||||
|
}
|
||||||
|
decl += "};\n";
|
||||||
|
|
||||||
|
return decl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char *GetTypeStr(UniformType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case UniformType::Int: return "int";
|
||||||
|
case UniformType::UInt: return "uint";
|
||||||
|
case UniformType::Float: return "float";
|
||||||
|
case UniformType::Vec2: return "vec2";
|
||||||
|
case UniformType::Vec3: return "vec3";
|
||||||
|
case UniformType::Vec4: return "vec4";
|
||||||
|
case UniformType::IVec2: return "ivec2";
|
||||||
|
case UniformType::IVec3: return "ivec3";
|
||||||
|
case UniformType::IVec4: return "ivec4";
|
||||||
|
case UniformType::UVec2: return "uvec2";
|
||||||
|
case UniformType::UVec3: return "uvec3";
|
||||||
|
case UniformType::UVec4: return "uvec4";
|
||||||
|
case UniformType::Mat4: return "mat4";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T, int bindingpoint>
|
template<typename T, int bindingpoint>
|
||||||
class ShaderUniforms
|
class ShaderUniforms
|
||||||
{
|
{
|
||||||
|
@ -61,25 +109,7 @@ public:
|
||||||
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
|
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
|
||||||
{
|
{
|
||||||
mFields = fields;
|
mFields = fields;
|
||||||
|
return UniformBlockDecl::Create(name, fields, bindingpoint);
|
||||||
FString decl;
|
|
||||||
FString layout;
|
|
||||||
if (screen->glslversion < 4.20)
|
|
||||||
{
|
|
||||||
layout = "std140";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
layout.Format("std140, binding = %d", bindingpoint);
|
|
||||||
}
|
|
||||||
decl.Format("layout(%s) uniform %s\n{\n", layout.GetChars(), name);
|
|
||||||
for (const auto &field : fields)
|
|
||||||
{
|
|
||||||
decl.AppendFormat("\t%s %s;\n", GetTypeStr(field.Type), field.Name);
|
|
||||||
}
|
|
||||||
decl += "};\n";
|
|
||||||
|
|
||||||
return decl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
|
@ -107,27 +137,6 @@ private:
|
||||||
ShaderUniforms(const ShaderUniforms &) = delete;
|
ShaderUniforms(const ShaderUniforms &) = delete;
|
||||||
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
|
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
|
||||||
|
|
||||||
const char *GetTypeStr(UniformType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case UniformType::Int: return "int";
|
|
||||||
case UniformType::UInt: return "uint";
|
|
||||||
case UniformType::Float: return "float";
|
|
||||||
case UniformType::Vec2: return "vec2";
|
|
||||||
case UniformType::Vec3: return "vec3";
|
|
||||||
case UniformType::Vec4: return "vec4";
|
|
||||||
case UniformType::IVec2: return "ivec2";
|
|
||||||
case UniformType::IVec3: return "ivec3";
|
|
||||||
case UniformType::IVec4: return "ivec4";
|
|
||||||
case UniformType::UVec2: return "uvec2";
|
|
||||||
case UniformType::UVec3: return "uvec3";
|
|
||||||
case UniformType::UVec4: return "uvec4";
|
|
||||||
case UniformType::Mat4: return "mat4";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IUniformBuffer *mBuffer = nullptr;
|
IUniformBuffer *mBuffer = nullptr;
|
||||||
std::vector<UniformFieldDesc> mFields;
|
std::vector<UniformFieldDesc> mFields;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Copyright(C) 2016 Alexey Lysiuk
|
|
||||||
// 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/
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fast approXimate Anti-Aliasing (FXAA) post-processing
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "hw_fxaashader.h"
|
|
||||||
|
|
||||||
EXTERN_CVAR(Int, gl_fxaa)
|
|
||||||
|
|
||||||
void FFXAALumaShader::Bind(IRenderQueue *q)
|
|
||||||
{
|
|
||||||
if (!mShader)
|
|
||||||
{
|
|
||||||
mShader.reset(screen->CreateShaderProgram());
|
|
||||||
mShader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
|
||||||
mShader->Compile(IShaderProgram::Fragment, "shaders/glsl/fxaa.fp", "#define FXAA_LUMA_PASS\n", 330);
|
|
||||||
mShader->Link("shaders/glsl/fxaa");
|
|
||||||
}
|
|
||||||
|
|
||||||
mShader->Bind(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int GetMaxVersion()
|
|
||||||
{
|
|
||||||
return screen->glslversion >= 4.f ? 400 : 330;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FString GetDefines()
|
|
||||||
{
|
|
||||||
int quality;
|
|
||||||
|
|
||||||
switch (gl_fxaa)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case FFXAAShader::Low: quality = 10; break;
|
|
||||||
case FFXAAShader::Medium: quality = 12; break;
|
|
||||||
case FFXAAShader::High: quality = 29; break;
|
|
||||||
case FFXAAShader::Extreme: quality = 39; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int gatherAlpha = GetMaxVersion() >= 400 ? 1 : 0;
|
|
||||||
|
|
||||||
// TODO: enable FXAA_GATHER4_ALPHA on OpenGL earlier than 4.0
|
|
||||||
// when GL_ARB_gpu_shader5/GL_NV_gpu_shader5 extensions are supported
|
|
||||||
|
|
||||||
FString result;
|
|
||||||
result.Format(
|
|
||||||
"#define FXAA_QUALITY__PRESET %i\n"
|
|
||||||
"#define FXAA_GATHER4_ALPHA %i\n",
|
|
||||||
quality, gatherAlpha);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FFXAAShader::Bind(IRenderQueue *q)
|
|
||||||
{
|
|
||||||
assert(gl_fxaa > 0 && gl_fxaa < Count);
|
|
||||||
auto &shader = mShaders[gl_fxaa];
|
|
||||||
|
|
||||||
if (!shader)
|
|
||||||
{
|
|
||||||
FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc()) + GetDefines();
|
|
||||||
const int maxVersion = GetMaxVersion();
|
|
||||||
|
|
||||||
shader.reset(screen->CreateShaderProgram());
|
|
||||||
shader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", maxVersion);
|
|
||||||
shader->Compile(IShaderProgram::Fragment, "shaders/glsl/fxaa.fp", prolog, maxVersion);
|
|
||||||
shader->Link("shaders/glsl/fxaa");
|
|
||||||
shader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
|
|
||||||
Uniforms.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
shader->Bind(q);
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Copyright(C) 2016 Alexey Lysiuk
|
|
||||||
// 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/
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Fast approXimate Anti-Aliasing (FXAA) post-processing
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef __GL_FXAASHADER_H__
|
|
||||||
#define __GL_FXAASHADER_H__
|
|
||||||
|
|
||||||
#include "hwrenderer/postprocessing/hw_shaderprogram.h"
|
|
||||||
#include "hwrenderer/postprocessing/hw_postprocess_cvars.h"
|
|
||||||
|
|
||||||
class FFXAALumaShader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void Bind(IRenderQueue *q);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<IShaderProgram> mShader;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FFXAAShader : public IFXAAShader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void Bind(IRenderQueue *q);
|
|
||||||
|
|
||||||
struct UniformBlock
|
|
||||||
{
|
|
||||||
FVector2 ReciprocalResolution;
|
|
||||||
float Padding0, Padding1;
|
|
||||||
|
|
||||||
static std::vector<UniformFieldDesc> Desc()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
|
||||||
{ "ReciprocalResolution", UniformType::Vec2, offsetof(UniformBlock, ReciprocalResolution) },
|
|
||||||
{ "Padding0", UniformType::Float, offsetof(UniformBlock, Padding0) },
|
|
||||||
{ "Padding1", UniformType::Float, offsetof(UniformBlock, Padding1) }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<IShaderProgram> mShaders[Count];
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // __GL_FXAASHADER_H__
|
|
|
@ -1,45 +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_lensshader.cpp
|
|
||||||
** Lens distortion with chromatic aberration shader
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "v_video.h"
|
|
||||||
#include "hw_lensshader.h"
|
|
||||||
|
|
||||||
void FLensShader::Bind(IRenderQueue *q)
|
|
||||||
{
|
|
||||||
if (!mShader)
|
|
||||||
{
|
|
||||||
FString prolog = Uniforms.CreateDeclaration("Uniforms", UniformBlock::Desc());
|
|
||||||
|
|
||||||
mShader.reset(screen->CreateShaderProgram());
|
|
||||||
mShader->Compile(IShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
|
||||||
mShader->Compile(IShaderProgram::Fragment, "shaders/glsl/lensdistortion.fp", prolog, 330);
|
|
||||||
mShader->Link("shaders/glsl/lensdistortion");
|
|
||||||
mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms");
|
|
||||||
Uniforms.Init();
|
|
||||||
}
|
|
||||||
mShader->Bind(q);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#ifndef __GL_LENSSHADER_H
|
|
||||||
#define __GL_LENSSHADER_H
|
|
||||||
|
|
||||||
#include "hwrenderer/postprocessing/hw_shaderprogram.h"
|
|
||||||
|
|
||||||
class FLensShader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void Bind(IRenderQueue *q);
|
|
||||||
|
|
||||||
struct UniformBlock
|
|
||||||
{
|
|
||||||
float AspectRatio;
|
|
||||||
float Scale;
|
|
||||||
float Padding0, Padding1;
|
|
||||||
FVector4 LensDistortionCoefficient;
|
|
||||||
FVector4 CubicDistortionValue;
|
|
||||||
|
|
||||||
static std::vector<UniformFieldDesc> Desc()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
{
|
|
||||||
{ "Aspect", UniformType::Float, offsetof(UniformBlock, AspectRatio) },
|
|
||||||
{ "Scale", UniformType::Float, offsetof(UniformBlock, Scale) },
|
|
||||||
{ "Padding0", UniformType::Float, offsetof(UniformBlock, Padding0) },
|
|
||||||
{ "Padding1", UniformType::Float, offsetof(UniformBlock, Padding1) },
|
|
||||||
{ "k", UniformType::Vec4, offsetof(UniformBlock, LensDistortionCoefficient) },
|
|
||||||
{ "kcube", UniformType::Vec4, offsetof(UniformBlock, CubicDistortionValue) }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ShaderUniforms<UniformBlock, POSTPROCESS_BINDINGPOINT> Uniforms;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<IShaderProgram> mShader;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -25,19 +25,17 @@ void PPBloom::UpdateTextures(int width, int height)
|
||||||
|
|
||||||
for (int i = 0; i < NumBloomLevels; i++)
|
for (int i = 0; i < NumBloomLevels; i++)
|
||||||
{
|
{
|
||||||
FString vtexture, htexture;
|
|
||||||
vtexture.Format("Bloom.VTexture.%d", i);
|
|
||||||
htexture.Format("Bloom.HTexture.%d", i);
|
|
||||||
|
|
||||||
auto &level = levels[i];
|
auto &level = levels[i];
|
||||||
|
level.VTexture.Format("Bloom.VTexture.%d", i);
|
||||||
|
level.HTexture.Format("Bloom.HTexture.%d", i);
|
||||||
level.Viewport.left = 0;
|
level.Viewport.left = 0;
|
||||||
level.Viewport.top = 0;
|
level.Viewport.top = 0;
|
||||||
level.Viewport.width = (bloomWidth + 1) / 2;
|
level.Viewport.width = (bloomWidth + 1) / 2;
|
||||||
level.Viewport.height = (bloomHeight + 1) / 2;
|
level.Viewport.height = (bloomHeight + 1) / 2;
|
||||||
|
|
||||||
PPTextureDesc texture = { level.Viewport.width, level.Viewport.height, PixelFormat::Rgba16f };
|
PPTextureDesc texture = { level.Viewport.width, level.Viewport.height, PixelFormat::Rgba16f };
|
||||||
hw_postprocess.Textures[vtexture] = texture;
|
hw_postprocess.Textures[level.VTexture] = texture;
|
||||||
hw_postprocess.Textures[htexture] = texture;
|
hw_postprocess.Textures[level.HTexture] = texture;
|
||||||
|
|
||||||
bloomWidth = level.Viewport.width;
|
bloomWidth = level.Viewport.width;
|
||||||
bloomHeight = level.Viewport.height;
|
bloomHeight = level.Viewport.height;
|
||||||
|
@ -65,6 +63,7 @@ void PPBloom::UpdateSteps(int fixedcm)
|
||||||
// Extract blooming pixels from scene texture:
|
// Extract blooming pixels from scene texture:
|
||||||
step.Viewport = level0.Viewport;
|
step.Viewport = level0.Viewport;
|
||||||
step.SetInputCurrent(0, PPFilterMode::Linear);
|
step.SetInputCurrent(0, PPFilterMode::Linear);
|
||||||
|
step.SetInputTexture(1, "ExposureTexture");
|
||||||
step.ShaderName = "BloomExtract";
|
step.ShaderName = "BloomExtract";
|
||||||
step.Uniforms.Set(extractUniforms);
|
step.Uniforms.Set(extractUniforms);
|
||||||
step.SetOutputTexture(level0.VTexture);
|
step.SetOutputTexture(level0.VTexture);
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
Data = nullptr;
|
Data = nullptr;
|
||||||
Size = 0;
|
Size = 0;
|
||||||
|
|
||||||
Data = new uint8_t[Size];
|
Data = new uint8_t[sizeof(T)];
|
||||||
Size = sizeof(T);
|
Size = sizeof(T);
|
||||||
memcpy(Data, &v, Size);
|
memcpy(Data, &v, Size);
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ class PPStep
|
||||||
public:
|
public:
|
||||||
void SetInputTexture(int index, PPTextureName texture, PPFilterMode filter = PPFilterMode::Nearest)
|
void SetInputTexture(int index, PPTextureName texture, PPFilterMode filter = PPFilterMode::Nearest)
|
||||||
{
|
{
|
||||||
if ((int)Textures.Size() < index)
|
if ((int)Textures.Size() < index + 1)
|
||||||
Textures.Resize(index + 1);
|
Textures.Resize(index + 1);
|
||||||
auto &tex = Textures[index];
|
auto &tex = Textures[index];
|
||||||
tex.Filter = filter;
|
tex.Filter = filter;
|
||||||
|
@ -103,7 +103,7 @@ public:
|
||||||
|
|
||||||
void SetInputCurrent(int index, PPFilterMode filter = PPFilterMode::Nearest)
|
void SetInputCurrent(int index, PPFilterMode filter = PPFilterMode::Nearest)
|
||||||
{
|
{
|
||||||
if ((int)Textures.Size() < index)
|
if ((int)Textures.Size() < index + 1)
|
||||||
Textures.Resize(index + 1);
|
Textures.Resize(index + 1);
|
||||||
auto &tex = Textures[index];
|
auto &tex = Textures[index];
|
||||||
tex.Filter = filter;
|
tex.Filter = filter;
|
||||||
|
|
Loading…
Reference in a new issue