Merge remote-tracking branch 'origin/custom_postprocess'

This commit is contained in:
Rachael Alexanderson 2017-07-02 19:56:57 -04:00
commit edb45cd70d
3 changed files with 174 additions and 48 deletions

View file

@ -42,6 +42,7 @@
#include "r_utility.h" #include "r_utility.h"
#include "p_local.h" #include "p_local.h"
#include "colormatcher.h" #include "colormatcher.h"
#include "w_wad.h"
#include "gl/gl_functions.h" #include "gl/gl_functions.h"
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/system/gl_framebuffer.h" #include "gl/system/gl_framebuffer.h"
@ -152,6 +153,14 @@ EXTERN_CVAR(Float, vid_contrast)
EXTERN_CVAR(Float, vid_saturation) EXTERN_CVAR(Float, vid_saturation)
EXTERN_CVAR(Int, gl_satformula) EXTERN_CVAR(Int, gl_satformula)
class PostProcessShaderInstance
{
public:
FShaderProgram Program;
FBufferedUniformSampler InputTexture;
FBufferedUniformSampler CustomTexture;
FHardwareTexture *HWTexture = nullptr;
};
void FGLRenderer::RenderScreenQuad() void FGLRenderer::RenderScreenQuad()
{ {
@ -169,6 +178,75 @@ void FGLRenderer::PostProcessScene(int fixedcm)
ColormapScene(fixedcm); ColormapScene(fixedcm);
LensDistortScene(); LensDistortScene();
ApplyFXAA(); ApplyFXAA();
RunCustomPostProcessShaders("screen");
}
void FGLRenderer::RunCustomPostProcessShaders(FString target)
{
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();
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();
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -42,6 +42,7 @@ class FPresent3DRowShader;
class F2DDrawer; class F2DDrawer;
class FHardwareTexture; class FHardwareTexture;
class FShadowMapShader; class FShadowMapShader;
class PostProcessShaderInstance;
inline float DEG2RAD(float deg) inline float DEG2RAD(float deg)
{ {
@ -85,6 +86,17 @@ enum
DM_SKYPORTAL DM_SKYPORTAL
}; };
struct PostProcessShader
{
FString Target;
FString ShaderLumpName;
int ShaderVersion = 0;
FTexture *Texture = nullptr;
std::shared_ptr<PostProcessShaderInstance> Instance;
};
extern TArray<PostProcessShader> PostProcessShaders;
class FGLRenderer class FGLRenderer
{ {
public: public:
@ -171,6 +183,7 @@ public:
void RenderScreenQuad(); void RenderScreenQuad();
void PostProcessScene(int fixedcm); void PostProcessScene(int fixedcm);
void RunCustomPostProcessShaders(FString target);
void AmbientOccludeScene(); void AmbientOccludeScene();
void UpdateCameraExposure(); void UpdateCameraExposure();
void BloomScene(int fixedcm); void BloomScene(int fixedcm);

View file

@ -669,63 +669,98 @@ void gl_DestroyUserShaders()
// //
//========================================================================== //==========================================================================
TArray<PostProcessShader> PostProcessShaders;
void gl_ParseHardwareShader(FScanner &sc, int deflump) void gl_ParseHardwareShader(FScanner &sc, int deflump)
{ {
int type = FTexture::TEX_Any;
bool disable_fullbright=false;
bool thiswad = false;
bool iwad = false;
int maplump = -1;
FString maplumpname;
float speed = 1.f;
sc.MustGetString(); sc.MustGetString();
if (sc.Compare("texture")) type = FTexture::TEX_Wall; if (sc.Compare("postprocess"))
else if (sc.Compare("flat")) type = FTexture::TEX_Flat;
else if (sc.Compare("sprite")) type = FTexture::TEX_Sprite;
else sc.UnGet();
sc.MustGetString();
FTextureID no = TexMan.CheckForTexture(sc.String, type);
FTexture *tex = TexMan[no];
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{ {
sc.MustGetString(); sc.MustGetString();
if (sc.Compare("shader"))
PostProcessShader shaderdesc;
shaderdesc.Target = sc.String;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{ {
sc.MustGetString(); sc.MustGetString();
maplumpname = sc.String; if (sc.Compare("shader"))
}
else if (sc.Compare("speed"))
{
sc.MustGetFloat();
speed = float(sc.Float);
}
}
if (!tex)
{
return;
}
if (maplumpname.IsNotEmpty())
{
if (tex->bWarped != 0)
{
Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars());
return;
}
tex->gl_info.shaderspeed = speed;
for(unsigned i=0;i<usershaders.Size();i++)
{
if (!usershaders[i].CompareNoCase(maplumpname))
{ {
tex->gl_info.shaderindex = i + FIRST_USER_SHADER; sc.MustGetString();
return; shaderdesc.ShaderLumpName = sc.String;
sc.MustGetNumber();
shaderdesc.ShaderVersion = sc.Number;
}
else if (sc.Compare("texture"))
{
sc.MustGetString();
FTextureID no = TexMan.CheckForTexture(sc.String, FTexture::TEX_Wall);
shaderdesc.Texture = TexMan[no];
} }
} }
tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER;
} PostProcessShaders.Push(shaderdesc);
}
else
{
int type = FTexture::TEX_Any;
if (sc.Compare("texture")) type = FTexture::TEX_Wall;
else if (sc.Compare("flat")) type = FTexture::TEX_Flat;
else if (sc.Compare("sprite")) type = FTexture::TEX_Sprite;
else sc.UnGet();
bool disable_fullbright = false;
bool thiswad = false;
bool iwad = false;
int maplump = -1;
FString maplumpname;
float speed = 1.f;
sc.MustGetString();
FTextureID no = TexMan.CheckForTexture(sc.String, type);
FTexture *tex = TexMan[no];
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
sc.MustGetString();
if (sc.Compare("shader"))
{
sc.MustGetString();
maplumpname = sc.String;
}
else if (sc.Compare("speed"))
{
sc.MustGetFloat();
speed = float(sc.Float);
}
}
if (!tex)
{
return;
}
if (maplumpname.IsNotEmpty())
{
if (tex->bWarped != 0)
{
Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars());
return;
}
tex->gl_info.shaderspeed = speed;
for (unsigned i = 0; i < usershaders.Size(); i++)
{
if (!usershaders[i].CompareNoCase(maplumpname))
{
tex->gl_info.shaderindex = i + FIRST_USER_SHADER;
return;
}
}
tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER;
}
}
} }