mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
- Support binding textures for custom PP shaders
This commit is contained in:
parent
6a5bad0beb
commit
d5733f515c
3 changed files with 78 additions and 0 deletions
|
@ -34,6 +34,8 @@
|
||||||
#include "gl/renderer/gl_postprocessstate.h"
|
#include "gl/renderer/gl_postprocessstate.h"
|
||||||
#include "gl/renderer/gl_renderbuffers.h"
|
#include "gl/renderer/gl_renderbuffers.h"
|
||||||
#include "gl/shaders/gl_postprocessshader.h"
|
#include "gl/shaders/gl_postprocessshader.h"
|
||||||
|
#include "textures/textures.h"
|
||||||
|
#include "textures/bitmap.h"
|
||||||
|
|
||||||
CVAR(Bool, gl_custompost, true, 0)
|
CVAR(Bool, gl_custompost, true, 0)
|
||||||
|
|
||||||
|
@ -67,6 +69,12 @@ void FCustomPostProcessShaders::Run(FString target)
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PostProcessShaderInstance::~PostProcessShaderInstance()
|
||||||
|
{
|
||||||
|
for (const auto &it : mTextureHandles)
|
||||||
|
glDeleteTextures(1, (GLuint*)&it.second);
|
||||||
|
}
|
||||||
|
|
||||||
void PostProcessShaderInstance::Run()
|
void PostProcessShaderInstance::Run()
|
||||||
{
|
{
|
||||||
if (!IsShaderSupported())
|
if (!IsShaderSupported())
|
||||||
|
@ -80,6 +88,7 @@ void PostProcessShaderInstance::Run()
|
||||||
FGLDebug::PushGroup(Desc->ShaderLumpName.GetChars());
|
FGLDebug::PushGroup(Desc->ShaderLumpName.GetChars());
|
||||||
|
|
||||||
FGLPostProcessState savedState;
|
FGLPostProcessState savedState;
|
||||||
|
savedState.SaveTextureBindings(1 + Desc->Textures.CountUsed());
|
||||||
|
|
||||||
GLRenderer->mBuffers->BindNextFB();
|
GLRenderer->mBuffers->BindNextFB();
|
||||||
GLRenderer->mBuffers->BindCurrentTexture(0);
|
GLRenderer->mBuffers->BindCurrentTexture(0);
|
||||||
|
@ -89,11 +98,13 @@ void PostProcessShaderInstance::Run()
|
||||||
mProgram.Bind();
|
mProgram.Bind();
|
||||||
|
|
||||||
UpdateUniforms();
|
UpdateUniforms();
|
||||||
|
BindTextures();
|
||||||
|
|
||||||
mInputTexture.Set(0);
|
mInputTexture.Set(0);
|
||||||
|
|
||||||
GLRenderer->RenderScreenQuad();
|
GLRenderer->RenderScreenQuad();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
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_MAG_FILTER, GL_NEAREST);
|
||||||
GLRenderer->mBuffers->NextTexture();
|
GLRenderer->mBuffers->NextTexture();
|
||||||
|
@ -145,6 +156,13 @@ void PostProcessShaderInstance::CompileShader()
|
||||||
FString uniformTextures;
|
FString uniformTextures;
|
||||||
uniformTextures += "uniform sampler2D InputTexture;\n";
|
uniformTextures += "uniform sampler2D InputTexture;\n";
|
||||||
|
|
||||||
|
TMap<FString, FString>::Iterator itTextures(Desc->Textures);
|
||||||
|
TMap<FString, FString>::Pair *pairTextures;
|
||||||
|
while (itTextures.NextPair(pairTextures))
|
||||||
|
{
|
||||||
|
uniformTextures.AppendFormat("uniform sampler2D %s;\n", pairTextures->Key.GetChars());
|
||||||
|
}
|
||||||
|
|
||||||
// Setup pipeline
|
// Setup pipeline
|
||||||
FString pipelineInOut;
|
FString pipelineInOut;
|
||||||
pipelineInOut += "in vec2 TexCoord;\n";
|
pipelineInOut += "in vec2 TexCoord;\n";
|
||||||
|
@ -191,4 +209,49 @@ void PostProcessShaderInstance::UpdateUniforms()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glUniform1i(glGetUniformLocation(mProgram, "SillyTexture"), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PostProcessShaderInstance::BindTextures()
|
||||||
|
{
|
||||||
|
int textureUnit = 1;
|
||||||
|
TMap<FString, FString>::Iterator it(Desc->Textures);
|
||||||
|
TMap<FString, FString>::Pair *pair;
|
||||||
|
while (it.NextPair(pair))
|
||||||
|
{
|
||||||
|
int location = glGetUniformLocation(mProgram, pair->Key.GetChars());
|
||||||
|
if (location == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FString name = pair->Value;
|
||||||
|
FTexture *tex = TexMan(TexMan.CheckForTexture(name, FTexture::TEX_Any));
|
||||||
|
if (tex && tex->UseType != FTexture::TEX_Null)
|
||||||
|
{
|
||||||
|
glUniform1i(location, textureUnit);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + 1);
|
||||||
|
auto it = mTextureHandles.find(tex);
|
||||||
|
if (it == mTextureHandles.end())
|
||||||
|
{
|
||||||
|
FBitmap bitmap;
|
||||||
|
bitmap.Create(tex->GetWidth(), tex->GetHeight());
|
||||||
|
tex->CopyTrueColorPixels(&bitmap, 0, 0);
|
||||||
|
|
||||||
|
GLuint handle = 0;
|
||||||
|
glGenTextures(1, &handle);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, handle);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex->GetWidth(), tex->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap.GetPixels());
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
mTextureHandles[tex] = handle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
textureUnit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gl_shaderprogram.h"
|
#include "gl_shaderprogram.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class PostProcessShaderInstance;
|
class PostProcessShaderInstance;
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ struct PostProcessShader
|
||||||
bool Enabled = false;
|
bool Enabled = false;
|
||||||
|
|
||||||
TMap<FString, PostProcessUniformValue> Uniforms;
|
TMap<FString, PostProcessUniformValue> Uniforms;
|
||||||
|
TMap<FString, FString> Textures;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TArray<PostProcessShader> PostProcessShaders;
|
extern TArray<PostProcessShader> PostProcessShaders;
|
||||||
|
@ -37,6 +39,7 @@ class PostProcessShaderInstance
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { }
|
PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { }
|
||||||
|
~PostProcessShaderInstance();
|
||||||
|
|
||||||
void Run();
|
void Run();
|
||||||
|
|
||||||
|
@ -46,9 +49,11 @@ private:
|
||||||
bool IsShaderSupported();
|
bool IsShaderSupported();
|
||||||
void CompileShader();
|
void CompileShader();
|
||||||
void UpdateUniforms();
|
void UpdateUniforms();
|
||||||
|
void BindTextures();
|
||||||
|
|
||||||
FShaderProgram mProgram;
|
FShaderProgram mProgram;
|
||||||
FBufferedUniformSampler mInputTexture;
|
FBufferedUniformSampler mInputTexture;
|
||||||
|
std::map<FTexture*, int> mTextureHandles;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FCustomPostProcessShaders
|
class FCustomPostProcessShaders
|
||||||
|
|
|
@ -734,6 +734,16 @@ void gl_ParseHardwareShader(FScanner &sc, int deflump)
|
||||||
if (parsedType != PostProcessUniformType::Undefined)
|
if (parsedType != PostProcessUniformType::Undefined)
|
||||||
shaderdesc.Uniforms[uniformName].Type = parsedType;
|
shaderdesc.Uniforms[uniformName].Type = parsedType;
|
||||||
}
|
}
|
||||||
|
else if (sc.Compare("texture"))
|
||||||
|
{
|
||||||
|
sc.MustGetString();
|
||||||
|
FString textureName = sc.String;
|
||||||
|
|
||||||
|
sc.MustGetString();
|
||||||
|
FString textureSource = sc.String;
|
||||||
|
|
||||||
|
shaderdesc.Textures[textureName] = textureSource;
|
||||||
|
}
|
||||||
else if (sc.Compare("enabled"))
|
else if (sc.Compare("enabled"))
|
||||||
{
|
{
|
||||||
shaderdesc.Enabled = true;
|
shaderdesc.Enabled = true;
|
||||||
|
|
Loading…
Reference in a new issue