Merge branch 'custom_postprocess' into qzdoom

# Conflicts:
#	src/gl/renderer/gl_postprocess.cpp
This commit is contained in:
Magnus Norddahl 2017-07-06 05:41:16 +02:00
commit 69a3d10cb6
7 changed files with 237 additions and 155 deletions

View File

@ -1031,6 +1031,7 @@ set (PCH_SOURCES
gl/shaders/gl_shader.cpp
gl/shaders/gl_texshader.cpp
gl/shaders/gl_shaderprogram.cpp
gl/shaders/gl_postprocessshader.cpp
gl/shaders/gl_shadowmapshader.cpp
gl/shaders/gl_presentshader.cpp
gl/shaders/gl_present3dRowshader.cpp

View File

@ -42,7 +42,6 @@
#include "r_utility.h"
#include "p_local.h"
#include "colormatcher.h"
#include "w_wad.h"
#include "gl/gl_functions.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
@ -63,6 +62,7 @@
#include "gl/shaders/gl_lensshader.h"
#include "gl/shaders/gl_fxaashader.h"
#include "gl/shaders/gl_presentshader.h"
#include "gl/shaders/gl_postprocessshader.h"
#include "gl/renderer/gl_2ddrawer.h"
#include "gl/stereo3d/gl_stereo3d.h"
@ -155,15 +155,6 @@ EXTERN_CVAR(Float, vid_contrast)
EXTERN_CVAR(Float, vid_saturation)
EXTERN_CVAR(Int, gl_satformula)
class PostProcessShaderInstance
{
public:
FShaderProgram Program;
FBufferedUniformSampler InputTexture;
FBufferedUniformSampler CustomTexture;
FHardwareTexture *HWTexture = nullptr;
};
void FGLRenderer::RenderScreenQuad()
{
mVBO->BindVBO();
@ -175,135 +166,13 @@ void FGLRenderer::PostProcessScene(int fixedcm)
{
mBuffers->BlitSceneToTexture();
UpdateCameraExposure();
mCustomPostProcessShaders->Run("beforebloom");
BloomScene(fixedcm);
TonemapScene();
ColormapScene(fixedcm);
LensDistortScene();
ApplyFXAA();
RunCustomPostProcessShaders("scene");
}
#include "vm.h"
DEFINE_ACTION_FUNCTION(_Shader, SetUniform1f)
{
PARAM_PROLOGUE;
PARAM_STRING(shaderName);
PARAM_STRING(uniformName);
PARAM_FLOAT_DEF(value);
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
{
PostProcessShader &shader = PostProcessShaders[i];
if (shader.Name == shaderName)
shader.Uniform1f[uniformName] = value;
}
return 0;
}
DEFINE_ACTION_FUNCTION(_Shader, SetUniform1i)
{
PARAM_PROLOGUE;
PARAM_STRING(shaderName);
PARAM_STRING(uniformName);
PARAM_INT_DEF(value);
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
{
PostProcessShader &shader = PostProcessShaders[i];
if (shader.Name == shaderName)
shader.Uniform1i[uniformName] = value;
}
return 0;
}
void FGLRenderer::RunCustomPostProcessShaders(FString target)
{
if (!gl_custompost)
return;
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
{
PostProcessShader &shader = PostProcessShaders[i];
if (shader.Target != target)
continue;
if (!shader.Instance)
{
const char *lumpName = shader.ShaderLumpName.GetChars();
int lump = Wads.CheckNumForFullName(lumpName);
if (lump == -1) I_FatalError("Unable to load '%s'", lumpName);
FString code = Wads.ReadLump(lump).GetString().GetChars();
shader.Instance = std::make_shared<PostProcessShaderInstance>();
shader.Instance->Program.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); // Hmm, should this use shader.shaderversion?
shader.Instance->Program.Compile(FShaderProgram::Fragment, lumpName, code, "", shader.ShaderVersion);
shader.Instance->Program.SetFragDataLocation(0, "FragColor");
shader.Instance->Program.Link(shader.ShaderLumpName.GetChars());
shader.Instance->Program.SetAttribLocation(0, "PositionInProjection");
shader.Instance->InputTexture.Init(shader.Instance->Program, "InputTexture");
shader.Instance->CustomTexture.Init(shader.Instance->Program, "CustomTexture");
if (shader.Texture)
{
shader.Instance->HWTexture = new FHardwareTexture(shader.Texture->GetWidth(), shader.Texture->GetHeight(), false);
shader.Instance->HWTexture->CreateTexture((unsigned char*)shader.Texture->GetPixelsBgra(), shader.Texture->GetWidth(), shader.Texture->GetHeight(), 0, false, 0, "CustomTexture");
}
}
FGLDebug::PushGroup(shader.ShaderLumpName.GetChars());
FGLPostProcessState savedState;
savedState.SaveTextureBindings(2);
mBuffers->BindNextFB();
mBuffers->BindCurrentTexture(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
shader.Instance->Program.Bind();
TMap<FString, float>::Iterator it1f(shader.Uniform1f);
TMap<FString, float>::Pair *pair1f;
while (it1f.NextPair(pair1f))
{
int location = glGetUniformLocation(shader.Instance->Program, pair1f->Key.GetChars());
if (location != -1)
glUniform1f(location, pair1f->Value);
}
TMap<FString, int>::Iterator it1i(shader.Uniform1i);
TMap<FString, int>::Pair *pair1i;
while (it1i.NextPair(pair1i))
{
int location = glGetUniformLocation(shader.Instance->Program, pair1i->Key.GetChars());
if (location != -1)
glUniform1i(location, pair1i->Value);
}
shader.Instance->InputTexture.Set(0);
if (shader.Instance->HWTexture)
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shader.Instance->HWTexture->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);
shader.Instance->CustomTexture.Set(1);
}
RenderScreenQuad();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
mBuffers->NextTexture();
FGLDebug::PopGroup();
}
mCustomPostProcessShaders->Run("scene");
}
//-----------------------------------------------------------------------------
@ -952,7 +821,7 @@ void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma)
m2DDrawer->Draw(); // draw all pending 2D stuff before copying the buffer
m2DDrawer->Clear();
RunCustomPostProcessShaders("screen");
mCustomPostProcessShaders->Run("screen");
FGLDebug::PushGroup("CopyToBackbuffer");
if (FGLRenderBuffers::IsEnabled())

View File

@ -62,6 +62,7 @@
#include "gl/shaders/gl_presentshader.h"
#include "gl/shaders/gl_present3dRowshader.h"
#include "gl/shaders/gl_shadowmapshader.h"
#include "gl/shaders/gl_postprocessshader.h"
#include "gl/stereo3d/gl_stereo3d.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
@ -128,6 +129,7 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
mFXAAShader = nullptr;
mFXAALumaShader = nullptr;
mShadowMapShader = nullptr;
mCustomPostProcessShaders = nullptr;
}
void gl_LoadModels();
@ -157,6 +159,7 @@ void FGLRenderer::Initialize(int width, int height)
mPresent3dColumnShader = new FPresent3DColumnShader();
mPresent3dRowShader = new FPresent3DRowShader();
mShadowMapShader = new FShadowMapShader();
mCustomPostProcessShaders = new FCustomPostProcessShaders();
m2DDrawer = new F2DDrawer;
// needed for the core profile, because someone decided it was a good idea to remove the default VAO.
@ -232,6 +235,7 @@ FGLRenderer::~FGLRenderer()
if (mColormapShader) delete mColormapShader;
if (mLensShader) delete mLensShader;
if (mShadowMapShader) delete mShadowMapShader;
delete mCustomPostProcessShaders;
delete mFXAAShader;
delete mFXAALumaShader;
}

View File

@ -42,7 +42,7 @@ class FPresent3DRowShader;
class F2DDrawer;
class FHardwareTexture;
class FShadowMapShader;
class PostProcessShaderInstance;
class FCustomPostProcessShaders;
inline float DEG2RAD(float deg)
{
@ -86,22 +86,6 @@ enum
DM_SKYPORTAL
};
struct PostProcessShader
{
FString Target;
FString ShaderLumpName;
int ShaderVersion = 0;
FTexture *Texture = nullptr;
FString Name;
TMap<FString, int> Uniform1i;
TMap<FString, float> Uniform1f;
std::shared_ptr<PostProcessShaderInstance> Instance;
};
extern TArray<PostProcessShader> PostProcessShaders;
class FGLRenderer
{
public:
@ -143,6 +127,7 @@ public:
FPresent3DColumnShader *mPresent3dColumnShader;
FPresent3DRowShader *mPresent3dRowShader;
FShadowMapShader *mShadowMapShader;
FCustomPostProcessShaders *mCustomPostProcessShaders;
FShadowMap mShadowMap;
@ -188,7 +173,6 @@ public:
void RenderScreenQuad();
void PostProcessScene(int fixedcm);
void RunCustomPostProcessShaders(FString target);
void AmbientOccludeScene();
void UpdateCameraExposure();
void BloomScene(int fixedcm);

View File

@ -0,0 +1,145 @@
//
//---------------------------------------------------------------------------
//
// Copyright(C) 2017 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/
//
//--------------------------------------------------------------------------
//
#include "gl/system/gl_system.h"
#include "m_swap.h"
#include "v_video.h"
#include "gl/gl_functions.h"
#include "vectors.h"
#include "w_wad.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h"
#include "gl/system/gl_debug.h"
#include "gl/system/gl_cvars.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/renderer/gl_postprocessstate.h"
#include "gl/renderer/gl_renderbuffers.h"
#include "gl/shaders/gl_postprocessshader.h"
CVAR(Bool, gl_custompost, true, 0)
TArray<PostProcessShader> PostProcessShaders;
FCustomPostProcessShaders::FCustomPostProcessShaders()
{
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
{
mShaders.push_back(std::unique_ptr<PostProcessShaderInstance>(new PostProcessShaderInstance(&PostProcessShaders[i])));
}
}
FCustomPostProcessShaders::~FCustomPostProcessShaders()
{
}
void FCustomPostProcessShaders::Run(FString target)
{
if (!gl_custompost)
return;
for (auto &shader : mShaders)
{
if (shader->Desc->Target == target)
{
shader->Run();
}
}
}
/////////////////////////////////////////////////////////////////////////////
void PostProcessShaderInstance::Run()
{
if (!Program)
{
const char *lumpName = Desc->ShaderLumpName.GetChars();
int lump = Wads.CheckNumForFullName(lumpName);
if (lump == -1) I_FatalError("Unable to load '%s'", lumpName);
FString code = Wads.ReadLump(lump).GetString().GetChars();
Program.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); // Hmm, should this use shader.shaderversion?
Program.Compile(FShaderProgram::Fragment, lumpName, code, "", Desc->ShaderVersion);
Program.SetFragDataLocation(0, "FragColor");
Program.Link(Desc->ShaderLumpName.GetChars());
Program.SetAttribLocation(0, "PositionInProjection");
InputTexture.Init(Program, "InputTexture");
CustomTexture.Init(Program, "CustomTexture");
if (Desc->Texture)
{
HWTexture = new FHardwareTexture(Desc->Texture->GetWidth(), Desc->Texture->GetHeight(), false);
HWTexture->CreateTexture((unsigned char*)Desc->Texture->GetPixelsBgra(), Desc->Texture->GetWidth(), Desc->Texture->GetHeight(), 0, false, 0, "CustomTexture");
}
}
FGLDebug::PushGroup(Desc->ShaderLumpName.GetChars());
FGLPostProcessState savedState;
savedState.SaveTextureBindings(2);
GLRenderer->mBuffers->BindNextFB();
GLRenderer->mBuffers->BindCurrentTexture(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Program.Bind();
TMap<FString, float>::Iterator it1f(Desc->Uniform1f);
TMap<FString, float>::Pair *pair1f;
while (it1f.NextPair(pair1f))
{
int location = glGetUniformLocation(Program, pair1f->Key.GetChars());
if (location != -1)
glUniform1f(location, pair1f->Value);
}
TMap<FString, int>::Iterator it1i(Desc->Uniform1i);
TMap<FString, int>::Pair *pair1i;
while (it1i.NextPair(pair1i))
{
int location = glGetUniformLocation(Program, pair1i->Key.GetChars());
if (location != -1)
glUniform1i(location, pair1i->Value);
}
InputTexture.Set(0);
if (HWTexture)
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, HWTexture->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);
CustomTexture.Set(1);
}
GLRenderer->RenderScreenQuad();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
GLRenderer->mBuffers->NextTexture();
FGLDebug::PopGroup();
}

View File

@ -0,0 +1,48 @@
#pragma once
#include "gl_shaderprogram.h"
class PostProcessShaderInstance;
struct PostProcessShader
{
FString Target;
FString ShaderLumpName;
int ShaderVersion = 0;
FTexture *Texture = nullptr;
FString Name;
TMap<FString, int> Uniform1i;
TMap<FString, float> Uniform1f;
};
extern TArray<PostProcessShader> PostProcessShaders;
class PostProcessShaderInstance
{
public:
PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { }
void Run();
PostProcessShader *Desc;
FShaderProgram Program;
FBufferedUniformSampler InputTexture;
FBufferedUniformSampler CustomTexture;
FHardwareTexture *HWTexture = nullptr;
};
class FCustomPostProcessShaders
{
public:
FCustomPostProcessShaders();
~FCustomPostProcessShaders();
void Run(FString target);
private:
std::vector<std::unique_ptr<PostProcessShaderInstance>> mShaders;
FCustomPostProcessShaders(const FCustomPostProcessShaders &) = delete;
FCustomPostProcessShaders &operator=(const FCustomPostProcessShaders &) = delete;
};

View File

@ -36,6 +36,7 @@
#include "v_palette.h"
#include "sc_man.h"
#include "cmdlib.h"
#include "vm.h"
#include "gl/system/gl_interface.h"
#include "gl/system/gl_debug.h"
@ -46,6 +47,7 @@
#include "gl/system/gl_cvars.h"
#include "gl/shaders/gl_shader.h"
#include "gl/shaders/gl_shaderprogram.h"
#include "gl/shaders/gl_postprocessshader.h"
#include "gl/textures/gl_material.h"
#include "gl/dynlights/gl_lightbuffer.h"
@ -669,8 +671,6 @@ void gl_DestroyUserShaders()
//
//==========================================================================
TArray<PostProcessShader> PostProcessShaders;
void gl_ParseHardwareShader(FScanner &sc, int deflump)
{
sc.MustGetString();
@ -769,3 +769,34 @@ void gl_ParseHardwareShader(FScanner &sc, int deflump)
}
}
DEFINE_ACTION_FUNCTION(_Shader, SetUniform1f)
{
PARAM_PROLOGUE;
PARAM_STRING(shaderName);
PARAM_STRING(uniformName);
PARAM_FLOAT_DEF(value);
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
{
PostProcessShader &shader = PostProcessShaders[i];
if (shader.Name == shaderName)
shader.Uniform1f[uniformName] = value;
}
return 0;
}
DEFINE_ACTION_FUNCTION(_Shader, SetUniform1i)
{
PARAM_PROLOGUE;
PARAM_STRING(shaderName);
PARAM_STRING(uniformName);
PARAM_INT_DEF(value);
for (unsigned int i = 0; i < PostProcessShaders.Size(); i++)
{
PostProcessShader &shader = PostProcessShaders[i];
if (shader.Name == shaderName)
shader.Uniform1i[uniformName] = value;
}
return 0;
}