- basics of hardware shader framework complete. The implementation in the shader manager still needs to be done, though.

Conflicts:
	src/gl/textures/gl_material.cpp
This commit is contained in:
Christoph Oelckers 2014-10-26 13:02:09 +01:00
parent f852f46a96
commit 298b2bae7c
9 changed files with 260 additions and 110 deletions

View file

@ -71,6 +71,7 @@ void gl_ParseHardwareShader(FScanner &sc, int deflump);
void gl_ParseSkybox(FScanner &sc);
void gl_ParseDetailTexture(FScanner &sc);
void gl_ParseVavoomSkybox();
void gl_ParseShaderDef(FScanner &sc, bool islight);
//==========================================================================
//
@ -857,6 +858,8 @@ static const char *CoreKeywords[]=
"disable_fullbright",
"hardwareshader",
"detail",
"texelshader",
"lightshader",
"#include",
NULL
};
@ -879,6 +882,8 @@ enum
TAG_DISABLE_FB,
TAG_HARDWARESHADER,
TAG_DETAIL,
TAG_TEXELSHADER,
TAG_LIGHTSHADER,
TAG_INCLUDE,
};
@ -1270,6 +1275,12 @@ void gl_DoParseDefs(FScanner &sc, int workingLump)
case TAG_DETAIL:
gl_ParseDetailTexture(sc);
break;
case TAG_TEXELSHADER:
gl_ParseShaderDef(sc, false);
break;
case TAG_LIGHTSHADER:
gl_ParseShaderDef(sc, true);
break;
case TAG_DISABLE_FB:
{
/* not implemented.

View file

@ -10,6 +10,13 @@
#include "r_defs.h"
#include "r_data/r_translate.h"
enum
{
SHADER_NOTEXTURE = 0,
SHADER_DEFAULT = 1,
SHADER_FUZZ = 2
};
class FVertexBuffer;
class FShader;
extern TArray<VSMatrix> gl_MatrixStack;

View file

@ -749,7 +749,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
{
// Todo: implement shader selection here
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
OverrideShader = gl_fuzztype + 4;
OverrideShader = gl_fuzztype + SHADER_FUZZ;
trans = 0.99f; // trans may not be 1 here
hw_styleflags |= STYLEHW_NoAlphaTest;
}

View file

@ -59,13 +59,16 @@
#include "gl/textures/gl_material.h"
#include "gl/dynlights/gl_lightbuffer.h"
TArray<FShaderDefinition *> TexelShaders;
TArray<FShaderDefinition *> LightShaders;
//==========================================================================
//
//
//
//==========================================================================
bool FShader::Load(const char * name, const char * vert_prog_lump, const char * frag_prog_lump, const char * proc_prog_lump, const char * defines)
bool FShader::Load(const char * name, const char * vert_prog_lump, const char * frag_prog_lump, const char * tex_proc_lump, const char *lite_proc_lump, const char * defines)
{
static char buffer[10000];
FString error;
@ -114,12 +117,12 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
vp_comb << vp_data.GetString().GetChars() << "\n";
fp_comb << fp_data.GetString().GetChars() << "\n";
if (proc_prog_lump != NULL)
if (tex_proc_lump != NULL)
{
if (*proc_prog_lump != '#')
if (*tex_proc_lump != '#')
{
int pp_lump = Wads.CheckNumForFullName(proc_prog_lump);
if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump);
int pp_lump = Wads.CheckNumForFullName(tex_proc_lump);
if (pp_lump == -1) I_Error("Unable to load '%s'", tex_proc_lump);
FMemLump pp_data = Wads.ReadLump(pp_lump);
if (pp_data.GetString().IndexOf("ProcessTexel") < 0)
@ -131,21 +134,21 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
}
fp_comb << pp_data.GetString().GetChars();
fp_comb.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders.
if (pp_data.GetString().IndexOf("ProcessLight") < 0)
{
int pl_lump = Wads.CheckNumForFullName("shaders/glsl/func_defaultlight.fp");
if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultlight.fp");
FMemLump pl_data = Wads.ReadLump(pl_lump);
fp_comb << "\n" << pl_data.GetString().GetChars();
}
}
else
{
// Proc_prog_lump is not a lump name but the source itself (from generated shaders)
fp_comb << proc_prog_lump + 1;
fp_comb << tex_proc_lump + 1;
}
}
if (lite_proc_lump != NULL)
{
int pp_lump = Wads.CheckNumForFullName(lite_proc_lump);
if (pp_lump == -1) I_Error("Unable to load '%s'", lite_proc_lump);
FMemLump pp_data = Wads.ReadLump(pp_lump);
fp_comb << pp_data.GetString().GetChars();
}
hVertProg = glCreateShader(GL_VERTEX_SHADER);
hFragProg = glCreateShader(GL_FRAGMENT_SHADER);
@ -280,7 +283,7 @@ bool FShader::Bind()
//
//==========================================================================
FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard)
FShader *FShaderManager::Compile (const char *ShaderName, const char *TexShaderPath, const char *LightShaderPath, bool usediscard)
{
FString defines;
// this can't be in the shader code due to ATI strangeness.
@ -291,7 +294,7 @@ FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath
try
{
shader = new FShader(ShaderName);
if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, defines.GetChars()))
if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", TexShaderPath, LightShaderPath, defines.GetChars()))
{
I_FatalError("Unable to load shader %s\n", ShaderName);
}
@ -324,32 +327,6 @@ void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
//
//
//==========================================================================
struct FDefaultShader
{
const char * ShaderName;
const char * gettexelfunc;
};
// Note: the FIRST_USER_SHADER constant in gl_shader.h needs
// to be updated whenever the size of this array is modified.
static const FDefaultShader defaultshaders[]=
{
{"Default", "shaders/glsl/func_normal.fp"},
{"Warp 1", "shaders/glsl/func_warp1.fp"},
{"Warp 2", "shaders/glsl/func_warp2.fp"},
{"Brightmap","shaders/glsl/func_brightmap.fp"},
{"No Texture", "shaders/glsl/func_notexture.fp"},
{"Basic Fuzz", "shaders/glsl/fuzz_standard.fp"},
{"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp"},
{"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp"},
{"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp"},
{"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp"},
{"Noise Fuzz", "shaders/glsl/fuzz_noise.fp"},
{"Smooth Noise Fuzz", "shaders/glsl/fuzz_smoothnoise.fp"},
{NULL,NULL}
};
static TArray<FString> usershaders;
struct FEffectShader
{
@ -391,12 +368,57 @@ FShaderManager::~FShaderManager()
Clean();
}
//==========================================================================
//
// Initializes the shaders that are being used by the current texture set
//
//==========================================================================
void FShaderManager::FindAllUsedShaders()
{
for (int i = 0; i < TexMan.NumTextures(); i++)
{
FTexture *tex = TexMan.ByIndex(i);
if (tex->bWarped == 1) tex->gl_info.texelShader = "Warp 1";
else if (tex->bWarped == 2) tex->gl_info.texelShader = "Warp 2";
GLRenderer->mShaderManager->GetShaderIndex(tex->gl_info.texelShader, tex->gl_info.lightShader);
}
}
//==========================================================================
//
//
//
//==========================================================================
unsigned int FShaderManager::GetShaderIndex(FName tex, FName lite)
{
return 0;
}
//==========================================================================
//
//
//
//==========================================================================
static const char *defShaderNames[] =
{
"No Texture",
"None",
"Fuzz Standard",
"Fuzz Smooth",
"Fuzz Swirly",
"Fuzz Translucent",
"Fuzz Jagged",
"Fuzz Noise",
"Fuzz Smooth Noise",
NULL
};
void FShaderManager::CompileShaders()
{
mActiveShader = NULL;
@ -408,6 +430,7 @@ void FShaderManager::CompileShaders()
mEffectShaders[i] = NULL;
}
/*
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
{
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true);
@ -418,21 +441,19 @@ void FShaderManager::CompileShaders()
mTextureEffectsNAT.Push(shc);
}
}
*/
for(unsigned i = 0; i < usershaders.Size(); i++)
// load the ones the engine accesses directly in order first. The rest gets set up on a need to use basis.
for (int i = 0; defShaderNames[i]; i++)
{
FString name = ExtractFileBase(usershaders[i]);
FName sfn = name;
FShader *shc = Compile(sfn, usershaders[i], true);
mTextureEffects.Push(shc);
GetShaderIndex(defShaderNames[i], NAME_None);
}
for(int i=0;i<MAX_EFFECTS;i++)
{
FShader *eff = new FShader(effectshaders[i].ShaderName);
if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
effectshaders[i].fp2, effectshaders[i].defines))
effectshaders[i].fp2, NULL, effectshaders[i].defines))
{
delete eff;
}
@ -474,6 +495,7 @@ void FShaderManager::Clean()
//
//==========================================================================
/*
int FShaderManager::Find(const char * shn)
{
FName sfn = shn;
@ -487,6 +509,7 @@ int FShaderManager::Find(const char * shn)
}
return -1;
}
*/
//==========================================================================
//
@ -564,7 +587,27 @@ void gl_DestroyUserShaders()
//==========================================================================
//
// Parses a shader definition
// Find a shader definition
//
//==========================================================================
static unsigned int FindShaderDef(TArray<FShaderDefinition *> &defarray, FName name)
{
for (unsigned int i = 0; i < defarray.Size(); i++)
{
if (defarray[i]->mName == name)
{
return i;
}
}
return UINT_MAX;
}
//==========================================================================
//
// Parses an old hardware shader definition
// This feature is deprecated so its functionality is intentionally
// limited to what it was before.
//
//==========================================================================
@ -587,6 +630,10 @@ void gl_ParseHardwareShader(FScanner &sc, int deflump)
sc.MustGetString();
FTextureID no = TexMan.CheckForTexture(sc.String, type);
FTexture *tex = TexMan[no];
if (!tex)
{
sc.ScriptMessage("Texture '%s' not found\n", sc.String);
}
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
@ -596,6 +643,7 @@ void gl_ParseHardwareShader(FScanner &sc, int deflump)
{
sc.MustGetString();
maplumpname = sc.String;
maplumpname.ToLower();
}
else if (sc.Compare("speed"))
{
@ -612,19 +660,95 @@ void gl_ParseHardwareShader(FScanner &sc, int deflump)
{
if (tex->bWarped != 0)
{
Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars());
sc.ScriptMessage("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++)
FShaderDefinition *def;
FName nm = maplumpname + "@@@";
unsigned int defindex = FindShaderDef(TexelShaders, nm);
if (defindex == UINT_MAX)
{
if (!usershaders[i].CompareNoCase(maplumpname))
{
tex->gl_info.shaderindex = i + FIRST_USER_SHADER;
return;
}
def = new FShaderDefinition;
def->mName = nm;
def->mCoreLump = false;
def->mNoLightShader = true;
def->mSourceFile = maplumpname;
TexelShaders.Push(def);
}
tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER;
else
{
def = TexelShaders[defindex];
def->mName = nm;
def->mCoreLump = false;
def->mNoLightShader = true;
def->mSourceFile = maplumpname;
}
}
}
void gl_ParseShaderDef(FScanner &sc, bool isLight)
{
FShaderDefinition *def = new FShaderDefinition;
bool CoreLump = false;
sc.SetCMode(true);
sc.MustGetString();
FName shadername = sc.String;
sc.MustGetStringName("{");
sc.MustGetString();
if (sc.Compare("source"))
{
sc.MustGetString();
def->mSourceFile = sc.String;
while (sc.CheckString(","))
{
sc.MustGetString();
if (sc.Compare("corelump"))
{
CoreLump = true;
def->mCoreLump = true;
}
}
}
else if (sc.Compare("nolightshader"))
{
def->mNoLightShader = true;
}
else if (sc.Compare("requirealphatest"))
{
def->bRequireAlphaTest = true;
}
// parse other stuff here.
sc.MustGetStringName("}");
int lumpnum = Wads.CheckNumForFullName(def->mSourceFile);
if (lumpnum < 0)
{
sc.ScriptMessage("Unable to find shader source '%s'", def->mSourceFile);
}
else if (CoreLump)
{
int wadnum = Wads.GetLumpFile(lumpnum);
if (wadnum > FWadCollection::IWAD_FILENUM)
{
I_FatalError("File %s is overriding core lump %s.",
Wads.GetWadFullName(wadnum), def->mSourceFile);
}
}
TArray<FShaderDefinition*> *pArr = isLight ? &LightShaders : &TexelShaders;
unsigned int defindex = FindShaderDef(*pArr, def->mName);
if (defindex != UINT_MAX)
{
// replacing core shaders is prohibited.
if ((*pArr)[defindex]->mCoreLump)
{
sc.ScriptError("Shader %s is overriding core shader", def->mName.GetChars());
}
pArr->Delete(defindex);
}
pArr->Push(def);
}

View file

@ -250,7 +250,7 @@ public:
~FShader();
bool Load(const char * name, const char * vert_prog_lump, const char * fragprog, const char * fragprog2, const char *defines);
bool Load(const char * name, const char * vert_prog_lump, const char * fragprog, const char * fragprog2, const char *fragprog3, const char *defines);
void SetColormapColor(float r, float g, float b, float r1, float g1, float b1);
void SetGlowParams(float *topcolors, float topheight, float *bottomcolors, float bottomheight);
@ -278,15 +278,18 @@ class FShaderManager
void Clean();
void CompileShaders();
void FindAllUsedShaders();
public:
FShaderManager();
~FShaderManager();
FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard);
int Find(const char *mame);
FShader *Compile(const char *ShaderName, const char *TexShaderPath, const char *LightShaderPath, bool usediscard);
//int Find(const char *mame);
FShader *BindEffect(int effect);
void SetActiveShader(FShader *sh);
void ApplyMatrices(VSMatrix *proj, VSMatrix *view);
unsigned int GetShaderIndex(FName tex, FName light);
FShader *GetActiveShader() const
{
return mActiveShader;
@ -326,5 +329,26 @@ enum
LIGHTBUF_BINDINGPOINT = 1
};
struct FShaderDefinition
{
FName mName;
FString mSourceFile;
bool mNoLightShader;
bool mCoreLump;
bool bRequireAlphaTest;
FShaderDefinition()
{
mNoLightShader = false;
mCoreLump = false;
bRequireAlphaTest = false;
}
};
extern TArray<FShaderDefinition *> TexelShaders;
extern TArray<FShaderDefinition *> LightShaders;
#endif

View file

@ -411,38 +411,17 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
mShaderIndex = 0;
tex = tx;
// TODO: apply custom shader object here
/* if (tx->CustomShaderDefinition)
{
}
else
*/
if (tx->bWarped)
{
mShaderIndex = tx->bWarped;
tx->gl_info.shaderspeed = static_cast<FWarpTexture*>(tx)->GetSpeed();
}
else if (tx->bHasCanvas)
{
}
else
{
if (tx->gl_info.shaderindex >= FIRST_USER_SHADER)
{
mShaderIndex = tx->gl_info.shaderindex;
}
else
{
tx->CreateDefaultBrightmap();
mShaderIndex = GLRenderer->mShaderManager->GetShaderIndex(tx->gl_info.texelShader, tx->gl_info.lightShader);
// this must later be replaced with the layers array.
if (tx->gl_info.Brightmap != NULL)
{
ValidateSysTexture(tx->gl_info.Brightmap, expanded);
FTextureLayer layer = {tx->gl_info.Brightmap, false};
mTextureLayers.Push(layer);
mShaderIndex = 3;
}
}
}
mBaseLayer = ValidateSysTexture(tx, expanded);
@ -793,7 +772,8 @@ again:
{
if (expand)
{
if (tex->bWarped || tex->bHasCanvas || tex->gl_info.shaderindex >= FIRST_USER_SHADER)
// since we have no idea what a shader might do to the texture, adding an outer frame for sprites needs to be disabled if we got a texel shader assigned to this texture
if (tex->gl_info.texelShader != NAME_None)
{
tex->gl_info.bNoExpand = true;
goto again;

View file

@ -50,6 +50,7 @@
#include "gl/system/gl_interface.h"
#include "gl/renderer/gl_renderer.h"
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.h"
@ -240,7 +241,6 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
areacount = 0;
mIsTransparent = -1;
shaderspeed = 1.f;
shaderindex = 0;
precacheTime = 0;
Material[1] = Material[0] = NULL;
@ -275,6 +275,7 @@ void FTexture::CreateDefaultBrightmap()
{
if (!gl_info.bBrightmapChecked)
{
gl_info.bBrightmapChecked = 1;
// Check for brightmaps
if (UseBasePalette() && HasGlobalBrightmap &&
UseType != TEX_Decal && UseType != TEX_MiscPatch && UseType != TEX_FontChar &&
@ -293,24 +294,17 @@ void FTexture::CreateDefaultBrightmap()
// Create a brightmap
DPrintf("brightmap created for texture '%s'\n", Name.GetChars());
gl_info.Brightmap = new FBrightmapTexture(this);
gl_info.bBrightmapChecked = 1;
TexMan.AddTexture(gl_info.Brightmap);
gl_info.lightShader = "Brightmap";
return;
}
}
// No bright pixels found
DPrintf("No bright pixels found in texture '%s'\n", Name.GetChars());
gl_info.bBrightmapChecked = 1;
}
else
{
// does not have one so set the flag to 'done'
gl_info.bBrightmapChecked = 1;
}
}
}
//==========================================================================
//
// Precaches a GL texture
@ -703,13 +697,13 @@ void gl_ParseBrightmap(FScanner &sc, int deflump)
if (bmtex != NULL)
{
Printf("Multiple brightmap definitions in texture %s\n", tex? tex->Name.GetChars() : "(null)");
sc.ScriptMessage("Multiple brightmap definitions in texture %s\n", tex? tex->Name.GetChars() : "(null)");
}
bmtex = TexMan.FindTexture(sc.String, FTexture::TEX_Any, FTextureManager::TEXMAN_TryAny);
if (bmtex == NULL)
Printf("Brightmap '%s' not found in texture '%s'\n", sc.String, tex? tex->Name.GetChars() : "(null)");
sc.ScriptMessage("Brightmap '%s' not found in texture '%s'\n", sc.String, tex? tex->Name.GetChars() : "(null)");
}
}
if (!tex)
@ -731,14 +725,9 @@ void gl_ParseBrightmap(FScanner &sc, int deflump)
if (bmtex != NULL)
{
if (tex->bWarped != 0)
{
Printf("Cannot combine warping with brightmap on texture '%s'\n", tex->Name.GetChars());
return;
}
bmtex->bMasked = false;
tex->gl_info.Brightmap = bmtex;
tex->gl_info.lightShader = "Brightmap";
}
tex->gl_info.bDisableFullbright = disable_fullbright;
}

View file

@ -340,7 +340,8 @@ public:
int GlowHeight;
FloatRect *areas;
int areacount;
int shaderindex;
FName texelShader;
FName lightShader;
unsigned int precacheTime;
float shaderspeed;
int mIsTransparent:2;
@ -490,6 +491,7 @@ public:
FSwitchDef *FindSwitch (FTextureID texture);
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
unsigned int precacheTime;
private:

View file

@ -1,5 +1,4 @@
TexelShader "Normal"
TexelShader "None"
{
source "shaders/glsl/func_normal.fp", corelump
}
@ -27,38 +26,46 @@ TexelShader "Wave X"
TexelShader "Fuzz Jagged"
{
source "shaders/glsl/fuzz_jagged.fp", corelump
nolightshader
}
TexelShader "Fuzz Noise"
{
source "shaders/glsl/fuzz_noise.fp", corelump
nolightshader
}
TexelShader "Fuzz Smooth"
{
source "shaders/glsl/fuzz_smooth.fp", corelump
nolightshader
}
TexelShader "Fuzz Smooth Noise"
{
source "shaders/glsl/fuzz_smoothnoise.fp", corelump
nolightshader
}
TexelShader "Fuzz Smooth Translucent"
TexelShader "Fuzz Translucent"
{
source "shaders/glsl/fuzz_smoothtranslucent.fp", corelump
nolightshader
}
TexelShader "Fuzz Standard"
{
source "shaders/glsl/fuzz_standard.fp", corelump
nolightshader
}
TexelShader "Fuzz Swirly"
{
source "shaders/glsl/fuzz_swirly.fp", corelump
nolightshader
}
/* for now this is merely a reference for how later implementation should be done
TexelShader "Detail"
{
source "shaders/glsl/func_detail.fp", corelump
@ -77,9 +84,15 @@ TexelShader "Detail"
z "uScaleMax"
}
}
*/
LightShader "None"
{
source "shaders/glsl/func_defaultlight.fp", corelump
}
LightShader "Brightmap"
{
source "shaders/glsl/func_detail.fp", corelump
property Texture "texture2"
//property Texture "texture2" // will be implemented later.
}