shader rework

All those special shaders have been merged together.
Mostly working but the non-shader lighting seems a bit broken.
This commit is contained in:
Christoph Oelckers 2014-05-12 14:45:41 +02:00
parent 98cc7eeb99
commit 4d005bdfa0
28 changed files with 722 additions and 830 deletions

View file

@ -15,13 +15,11 @@ enum EColorManipulation
CM_DEFAULT=0, // untranslated
CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap
// special internal values for texture creation
CM_SHADE= 0x10000002, // alpha channel texture
CM_FOGLAYER = 0x10000000, // Sprite shaped fog layer
// These are not to be passed to the texture manager
CM_LITE = 0x20000000, // special values to handle these items without excessive hacking
CM_TORCH= 0x20000010, // These are not real color manipulations
CM_FOGLAYER= 0x20000020, // Sprite shaped fog layer
};
#define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size())

View file

@ -38,6 +38,7 @@
**
*/
#include "templates.h"
#include "gl/system/gl_system.h"
#include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
@ -51,7 +52,6 @@
void gl_SetTextureMode(int type);
FRenderState gl_RenderState;
int FStateAttr::ChangeCounter;
CVAR(Bool, gl_direct_state_change, true, 0)
@ -71,6 +71,7 @@ void FRenderState::Reset()
mFogColor.d = ffFogColor.d = -1;
mFogDensity = ffFogDensity = 0;
mTextureMode = ffTextureMode = -1;
mDesaturation = 0;
mSrcBlend = GL_SRC_ALPHA;
mDstBlend = GL_ONE_MINUS_SRC_ALPHA;
glSrcBlend = glDstBlend = -1;
@ -83,6 +84,7 @@ void FRenderState::Reset()
m2D = true;
mVertexBuffer = mCurrentVertexBuffer = NULL;
mColormapState = CM_DEFAULT;
mLightParms[3] = -1.f;
}
@ -128,11 +130,12 @@ bool FRenderState::ApplyShader()
{
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect);
}
FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4);
FShader *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4);
if (shd != NULL)
{
activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled);
activeShader = shd;
shd->Bind();
}
int fogset = 0;
@ -149,74 +152,93 @@ bool FRenderState::ApplyShader()
}
}
if (fogset != activeShader->currentfogenabled)
{
glUniform1i(activeShader->fogenabled_index, (activeShader->currentfogenabled = fogset));
}
if (mTextureMode != activeShader->currenttexturemode)
{
glUniform1i(activeShader->texturemode_index, (activeShader->currenttexturemode = mTextureMode));
}
if (activeShader->currentcamerapos.Update(&mCameraPos))
{
glUniform3fv(activeShader->camerapos_index, 1, mCameraPos.vec);
}
/*if (mLightParms[0] != activeShader->currentlightfactor ||
mLightParms[1] != activeShader->currentlightdist ||
mFogDensity != activeShader->currentfogdensity)*/
{
const float LOG2E = 1.442692f; // = 1/log(2)
//activeShader->currentlightdist = mLightParms[1];
//activeShader->currentlightfactor = mLightParms[0];
//activeShader->currentfogdensity = mFogDensity;
// premultiply the density with as much as possible here to reduce shader
// execution time.
glVertexAttrib4f(VATTR_FOGPARAMS, mLightParms[0], mLightParms[1], mFogDensity * (-LOG2E / 64000.f), 0);
}
if (mFogColor != activeShader->currentfogcolor)
{
activeShader->currentfogcolor = mFogColor;
glColor4fv(mColor.vec);
activeShader->muDesaturation.Set(mDesaturation);
activeShader->muFogEnabled.Set(fogset);
activeShader->muTextureMode.Set(mTextureMode);
activeShader->muCameraPos.Set(mCameraPos.vec);
activeShader->muLightParms.Set(mLightParms);
activeShader->muFogColor.Set(mFogColor);
activeShader->muObjectColor.Set(mObjectColor);
activeShader->muDynLightColor.Set(mDynColor);
glUniform4f (activeShader->fogcolor_index, mFogColor.r/255.f, mFogColor.g/255.f,
mFogColor.b/255.f, 0);
}
if (mGlowEnabled)
{
glUniform4fv(activeShader->glowtopcolor_index, 1, mGlowTop.vec);
glUniform4fv(activeShader->glowbottomcolor_index, 1, mGlowBottom.vec);
glUniform4fv(activeShader->glowtopplane_index, 1, mGlowTopPlane.vec);
glUniform4fv(activeShader->glowbottomplane_index, 1, mGlowBottomPlane.vec);
activeShader->muGlowTopColor.Set(mGlowTop.vec);
activeShader->muGlowBottomColor.Set(mGlowBottom.vec);
activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec);
activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec);
activeShader->currentglowstate = 1;
}
else if (activeShader->currentglowstate)
{
// if glowing is on, disable it.
glUniform4f(activeShader->glowtopcolor_index, 0.f, 0.f, 0.f, 0.f);
glUniform4f(activeShader->glowbottomcolor_index, 0.f, 0.f, 0.f, 0.f);
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
activeShader->muGlowTopColor.Set(nulvec);
activeShader->muGlowBottomColor.Set(nulvec);
activeShader->muGlowTopPlane.Set(nulvec);
activeShader->muGlowBottomPlane.Set(nulvec);
activeShader->currentglowstate = 0;
}
if (mLightEnabled)
{
glUniform3iv(activeShader->lightrange_index, 1, mNumLights);
glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData);
activeShader->muLightRange.Set(mNumLights);
glUniform4fv(activeShader->lights_index, mNumLights[3], mLightData);
}
if (mObjectColor != activeShader->currentobjectcolor)
else
{
activeShader->currentobjectcolor = mObjectColor;
glUniform4f(activeShader->objectcolor_index, mObjectColor.r / 255.f, mObjectColor.g / 255.f, mObjectColor.b / 255.f, mObjectColor.a / 255.f);
}
if (mDynColor != activeShader->currentdlightcolor)
{
activeShader->currentobjectcolor = mObjectColor;
glUniform4f(activeShader->dlightcolor_index, mDynColor.r / 255.f, mDynColor.g / 255.f, mDynColor.b / 255.f, 0);
static const int nulint[] = { 0, 0, 0, 0 };
activeShader->muLightRange.Set(nulint);
}
if (glset.lightmode == 8)
if (mColormapState != activeShader->currentfixedcolormap)
{
glVertexAttrib1f(VATTR_LIGHTLEVEL, mSoftLight / 255.f);
}
float r, g, b;
activeShader->currentfixedcolormap = mColormapState;
if (mColormapState == CM_DEFAULT)
{
activeShader->muFixedColormap.Set(0);
}
else if (mColormapState < CM_MAXCOLORMAP)
{
FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - CM_FIRSTSPECIALCOLORMAP];
float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0],
scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f };
activeShader->muFixedColormap.Set(1);
activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f);
activeShader->muColormapRange.Set(m);
}
else if (mColormapState == CM_FOGLAYER)
{
activeShader->muFixedColormap.Set(3);
}
else if (mColormapState == CM_LITE)
{
if (gl_enhanced_nightvision)
{
r = 0.375f, g = 1.0f, b = 0.375f;
}
else
{
r = g = b = 1.f;
}
activeShader->muFixedColormap.Set(2);
activeShader->muColormapStart.Set(r, g, b, 1.f);
}
else if (mColormapState >= CM_TORCH)
{
int flicker = mColormapState - CM_TORCH;
r = (0.8f + (7 - flicker) / 70.0f);
if (r > 1.0f) r = 1.0f;
b = g = r;
if (gl_enhanced_nightvision) b = g * 0.75f;
activeShader->muFixedColormap.Set(2);
activeShader->muColormapStart.Set(r, g, b, 1.f);
}
}
return true;
}
return false;
@ -326,6 +348,14 @@ void FRenderState::Apply(bool forcenoshader)
}
ffSpecialEffect = mSpecialEffect;
}
// Now compose the final color for this...
float realcolor[4];
realcolor[0] = clamp<float>((mColor.vec[0] + mDynColor.r / 255.f), 0.f, 1.f) * (mObjectColor.r / 255.f);
realcolor[1] = clamp<float>((mColor.vec[1] + mDynColor.g / 255.f), 0.f, 1.f) * (mObjectColor.g / 255.f);
realcolor[2] = clamp<float>((mColor.vec[2] + mDynColor.b / 255.f), 0.f, 1.f) * (mObjectColor.b / 255.f);
realcolor[3] = mColor.vec[3] * (mObjectColor.a / 255.f);
glColor4fv(realcolor);
}
}

View file

@ -3,6 +3,7 @@
#include <string.h>
#include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
#include "c_cvars.h"
#include "r_defs.h"
@ -10,81 +11,29 @@ class FVertexBuffer;
EXTERN_CVAR(Bool, gl_direct_state_change)
struct FStateAttr
{
static int ChangeCounter;
int mLastChange;
FStateAttr()
{
mLastChange = -1;
}
bool operator == (const FStateAttr &other)
{
return mLastChange == other.mLastChange;
}
bool operator != (const FStateAttr &other)
{
return mLastChange != other.mLastChange;
}
};
struct FStateVec3 : public FStateAttr
{
float vec[3];
bool Update(FStateVec3 *other)
{
if (mLastChange != other->mLastChange)
{
*this = *other;
return true;
}
return false;
}
void Set(float x, float y, float z)
{
vec[0] = x;
vec[1] = z;
vec[2] = y;
mLastChange = ++ChangeCounter;
}
};
struct FStateVec4 : public FStateAttr
struct FStateVec4
{
float vec[4];
bool Update(FStateVec4 *other)
{
if (mLastChange != other->mLastChange)
{
*this = *other;
return true;
}
return false;
}
void Set(float r, float g, float b, float a)
{
vec[0] = r;
vec[1] = g;
vec[2] = b;
vec[3] = a;
mLastChange = ++ChangeCounter;
}
};
enum EEffect
{
EFF_NONE,
EFF_NONE=-1,
EFF_FOGBOUNDARY,
EFF_SPHEREMAP,
EFF_BURN,
EFF_STENCIL,
MAX_EFFECTS
};
class FRenderState
@ -96,9 +45,10 @@ class FRenderState
bool mBrightmapEnabled;
int mSpecialEffect;
int mTextureMode;
int mDesaturation;
int mSoftLight;
float mLightParms[2];
int mNumLights[3];
float mLightParms[4];
int mNumLights[4];
float *mLightData;
int mSrcBlend, mDstBlend;
int mAlphaFunc;
@ -109,7 +59,7 @@ class FRenderState
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
FStateVec4 mColor;
FStateVec3 mCameraPos;
FStateVec4 mCameraPos;
FStateVec4 mGlowTop, mGlowBottom;
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
PalEntry mFogColor;
@ -155,25 +105,25 @@ public:
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
{
mColor.Set(r, g, b, a);
glColor4fv(mColor.vec);
mDesaturation = desat;
}
void SetColor(PalEntry pe, int desat = 0)
{
mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, pe.a/255.f);
glColor4fv(mColor.vec);
mDesaturation = desat;
}
void SetColorAlpha(PalEntry pe, float alpha = 1.f, int desat = 0)
{
mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, alpha);
glColor4fv(mColor.vec);
mDesaturation = desat;
}
void ResetColor()
{
mColor.Set(1,1,1,1);
glColor4fv(mColor.vec);
mDesaturation = 0;
}
void SetTextureMode(int mode)
@ -213,7 +163,7 @@ public:
void SetCameraPos(float x, float y, float z)
{
mCameraPos.Set(x,y,z);
mCameraPos.Set(x, z, y, 0);
}
void SetGlowParams(float *t, float *b)
@ -224,7 +174,8 @@ public:
void SetSoftLightLevel(int level)
{
mSoftLight = level;
if (glset.lightmode == 8) mLightParms[3] = level / 255.f;
else mLightParms[3] = -1.f;
}
void SetGlowPlanes(const secplane_t &top, const secplane_t &bottom)
@ -235,7 +186,7 @@ public:
void SetDynLight(float r, float g, float b)
{
mDynColor = PalEntry(xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255));
mDynColor = PalEntry(255, xs_CRoundToInt(r*255), xs_CRoundToInt(g*255), xs_CRoundToInt(b*255));
}
void SetDynLight(PalEntry pe)
@ -250,21 +201,23 @@ public:
void SetFog(PalEntry c, float d)
{
const float LOG2E = 1.442692f; // = 1/log(2)
mFogColor = c;
if (d >= 0.0f) mFogDensity = d;
if (d >= 0.0f) mLightParms[2] = d * (-LOG2E / 64000.f);
}
void SetLightParms(float f, float d)
{
mLightParms[0] = f;
mLightParms[1] = d;
mLightParms[1] = f;
mLightParms[0] = d;
}
void SetLights(int *numlights, float *lightdata)
{
mNumLights[0] = numlights[0];
mNumLights[1] = numlights[1];
mNumLights[2] = numlights[2];
mNumLights[0] = 0;
mNumLights[1] = numlights[0];
mNumLights[2] = numlights[1];
mNumLights[3] = numlights[2];
mLightData = lightdata; // caution: the data must be preserved by the caller until the 'apply' call!
}

View file

@ -842,6 +842,7 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)
DrawPlayerSprites (viewsector, false);
}
gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.SetSoftLightLevel(-1);
DrawTargeterSprites();
DrawBlend(viewsector);
@ -1059,6 +1060,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei
FieldOfView * 360.0f / FINEANGLES, 1.6f, 1.6f, true, false);
glDisable(GL_STENCIL_TEST);
gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.SetSoftLightLevel(-1);
screen->Begin2D(false);
DrawBlend(viewsector);
glFlush();

View file

@ -287,7 +287,7 @@ void GLSprite::Draw(int pass)
{
// If we get here we know that we have colored fog and no fixed colormap.
gl_SetFog(foglevel, rel, &Colormap, additivefog);
//gl_RenderState.SetFixedColormap(CM_FOGLAYER); fixme: does not work yet.
gl_RenderState.SetFixedColormap(CM_FOGLAYER);
gl_RenderState.BlendEquation(GL_FUNC_ADD);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.Apply();
@ -308,7 +308,7 @@ void GLSprite::Draw(int pass)
glVertex3fv(&v4[0]);
}
glEnd();
gl_RenderState.SetFixedColormap(CM_DEFAULT);
}
}
else

View file

@ -283,6 +283,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
}
PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
ThingColor.a = 255;
visstyle_t vis;

View file

@ -57,17 +57,6 @@
#include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_material.h"
// these will only have an effect on SM3 cards.
// For SM4 they are always on and for SM2 always off
CVAR(Bool, gl_warp_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
CVAR(Bool, gl_fog_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
CVAR(Bool, gl_colormap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
CVAR(Bool, gl_brightmap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
CVAR(Bool, gl_glow_shader, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
extern long gl_frameMS;
//==========================================================================
//
//
@ -81,6 +70,10 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
if (gl.hasGLSL())
{
int i_lump = Wads.CheckNumForFullName("shaders/glsl/shaderdefs.i");
if (i_lump == -1) I_Error("Unable to load 'shaders/glsl/shaderdefs.i'");
FMemLump i_data = Wads.ReadLump(i_lump);
int vp_lump = Wads.CheckNumForFullName(vert_prog_lump);
if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump);
FMemLump vp_data = Wads.ReadLump(vp_lump);
@ -90,12 +83,18 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
FMemLump fp_data = Wads.ReadLump(fp_lump);
FString vp_comb;
FString fp_comb;
vp_comb = defines;
fp_comb = vp_comb;
// This uses GetChars on the strings to get rid of terminating 0 characters.
//
// The following code uses GetChars on the strings to get rid of terminating 0 characters. Do not remove or the code may break!
//
FString vp_comb = "#version 130\n";
if (gl.glslversion >= 3.3f) vp_comb = "#version 330 compatibility\n"; // I can't shut up the deprecation warnings in GLSL 1.3 so if available use a version with compatibility profile.
// todo when using shader storage buffers, add
// "#version 400 compatibility\n#extension GL_ARB_shader_storage_buffer_object : require\n" instead.
vp_comb << defines << i_data.GetString().GetChars();
FString fp_comb = vp_comb;
vp_comb << vp_data.GetString().GetChars() << "\n";
fp_comb << fp_data.GetString().GetChars() << "\n";
@ -107,12 +106,27 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump);
FMemLump pp_data = Wads.ReadLump(pp_lump);
if (pp_data.GetString().IndexOf("ProcessTexel") < 0)
{
// this looks like an old custom hardware shader.
// We need to replace the ProcessTexel call to make it work.
fp_comb.Substitute("vec4 frag = ProcessTexel();", "vec4 frag = Process(vec4(1.0));");
}
fp_comb << pp_data.GetString().GetChars();
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
else
{
// Proc_prog_lump is not a lump name but the source itself (from generated shaders)
fp_comb << proc_prog_lump+1;
fp_comb << proc_prog_lump + 1;
}
}
@ -137,9 +151,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
glAttachShader(hShader, hVertProg);
glAttachShader(hShader, hFragProg);
glBindAttribLocation(hShader, VATTR_FOGPARAMS, "fogparams");
glBindAttribLocation(hShader, VATTR_LIGHTLEVEL, "lightlevel_in"); // Korshun.
glLinkProgram(hShader);
glGetShaderInfoLog(hVertProg, 10000, NULL, buffer);
@ -159,30 +170,34 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
error << "Linking:\n" << buffer << "\n";
}
int linked;
glGetShaderiv(hShader, GL_LINK_STATUS, &linked);
glGetProgramiv(hShader, GL_LINK_STATUS, &linked);
if (linked == 0)
{
// only print message if there's an error.
Printf("Init Shader '%s':\n%s\n", name, error.GetChars());
I_Error("Init Shader '%s':\n%s\n", name, error.GetChars());
}
timer_index = glGetUniformLocation(hShader, "timer");
desaturation_index = glGetUniformLocation(hShader, "desaturation_factor");
fogenabled_index = glGetUniformLocation(hShader, "fogenabled");
texturemode_index = glGetUniformLocation(hShader, "texturemode");
camerapos_index = glGetUniformLocation(hShader, "camerapos");
lightparms_index = glGetUniformLocation(hShader, "lightparms");
colormapstart_index = glGetUniformLocation(hShader, "colormapstart");
colormaprange_index = glGetUniformLocation(hShader, "colormaprange");
lightrange_index = glGetUniformLocation(hShader, "lightrange");
fogcolor_index = glGetUniformLocation(hShader, "fogcolor");
lights_index = glGetUniformLocation(hShader, "lights");
dlightcolor_index = glGetUniformLocation(hShader, "dlightcolor");
objectcolor_index = glGetUniformLocation(hShader, "objectcolor");
glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor");
glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor");
glowbottomplane_index = glGetUniformLocation(hShader, "glowbottomplane");
glowtopplane_index = glGetUniformLocation(hShader, "glowtopplane");
muDesaturation.Init(hShader, "uDesaturationFactor");
muFogEnabled.Init(hShader, "uFogEnabled");
muTextureMode.Init(hShader, "uTextureMode");
muCameraPos.Init(hShader, "uCameraPos");
muLightParms.Init(hShader, "uLightAttr");
muColormapStart.Init(hShader, "uFixedColormapStart");
muColormapRange.Init(hShader, "uFixedColormapRange");
muLightRange.Init(hShader, "uLightRange");
muFogColor.Init(hShader, "uFogColor");
muDynLightColor.Init(hShader, "uDynLightColor");
muObjectColor.Init(hShader, "uObjectColor");
muGlowBottomColor.Init(hShader, "uGlowBottomColor");
muGlowTopColor.Init(hShader, "uGlowTopColor");
muGlowBottomPlane.Init(hShader, "uGlowBottomPlane");
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
muFixedColormap.Init(hShader, "uFixedColormap");
timer_index = glGetUniformLocation(hShader, "timer");
lights_index = glGetUniformLocation(hShader, "lights");
glUseProgram(hShader);
@ -203,9 +218,12 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
FShader::~FShader()
{
glDeleteProgram(hShader);
glDeleteShader(hVertProg);
glDeleteShader(hFragProg);
if (gl.hasGLSL())
{
glDeleteProgram(hShader);
glDeleteShader(hVertProg);
glDeleteShader(hFragProg);
}
}
@ -215,202 +233,41 @@ FShader::~FShader()
//
//==========================================================================
bool FShader::Bind(float Speed)
bool FShader::Bind()
{
GLRenderer->mShaderManager->SetActiveShader(this);
if (timer_index >=0 && Speed > 0.f) glUniform1f(timer_index, gl_frameMS*Speed/1000.f);
return true;
}
//==========================================================================
//
//
// Since all shaders are REQUIRED, any error here needs to be fatal
//
//==========================================================================
FShaderContainer::FShaderContainer(const char *ShaderName, const char *ShaderPath)
FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath)
{
const char * shaderdefines[] = {
"#define NO_GLOW\n#define NO_DESATURATE\n",
"#define NO_DESATURATE\n",
"#define NO_GLOW\n",
"\n",
"#define NO_GLOW\n#define NO_DESATURATE\n#define DYNLIGHT\n",
"#define NO_DESATURATE\n#define DYNLIGHT\n",
"#define NO_GLOW\n#define DYNLIGHT\n",
"\n#define DYNLIGHT\n",
"#define NO_GLOW\n#define NO_DESATURATE\n#define SOFTLIGHT\n",
"#define NO_DESATURATE\n#define SOFTLIGHT\n",
"#define NO_GLOW\n#define SOFTLIGHT\n",
"\n#define SOFTLIGHT\n",
"#define NO_GLOW\n#define NO_DESATURATE\n#define DYNLIGHT\n#define SOFTLIGHT\n",
"#define NO_DESATURATE\n#define DYNLIGHT\n#define SOFTLIGHT\n",
"#define NO_GLOW\n#define DYNLIGHT\n#define SOFTLIGHT\n",
"\n#define DYNLIGHT\n#define SOFTLIGHT\n"
};
const char * shaderdesc[] = {
"::default",
"::glow",
"::desaturate",
"::glow+desaturate",
"::default+dynlight",
"::glow+dynlight",
"::desaturate+dynlight",
"::glow+desaturate+dynlight",
"::softlight",
"::glow+softlight",
"::desaturate+softlight",
"::glow+desaturate+softlight",
"::default+dynlight+softlight",
"::glow+dynlight+softlight",
"::desaturate+dynlight+softlight",
"::glow+desaturate+dynlight+softlight",
};
FString name;
name << ShaderName << "::colormap";
// this can't be in the shader code due to ATI strangeness.
const char *str = (gl.MaxLights() == 128)? "#define MAXLIGHTS128\n" : "";
FShader *shader = NULL;
try
{
shader_cm = new FShader;
if (!shader_cm->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main_colormap.fp", ShaderPath, "#define NO_FOG\n#define NO_GLOW\n"))
shader = new FShader(ShaderName);
if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str))
{
delete shader_cm;
shader_cm = NULL;
I_Error("Unable to load shader %s\n", ShaderName);
}
}
catch(CRecoverableError &err)
{
shader_cm = NULL;
I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage());
}
name << ShaderName << "::foglayer";
try
{
shader_fl = new FShader;
if (!shader_fl->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main_foglayer.fp", ShaderPath, "#define NO_GLOW\n"))
{
delete shader_fl;
shader_fl = NULL;
}
}
catch (CRecoverableError &err)
{
shader_fl = NULL;
I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage());
}
for(int i = 0;i < NUM_SHADERS; i++)
{
FString name;
name << ShaderName << shaderdesc[i];
try
{
FString str;
if ((i&4) != 0)
{
if (gl.maxuniforms < 1024)
{
shader[i] = NULL;
continue;
}
// this can't be in the shader code due to ATI strangeness.
str = "#version 120\n#extension GL_EXT_gpu_shader4 : enable\n";
if (gl.MaxLights() == 128) str += "#define MAXLIGHTS128\n";
}
str += shaderdefines[i];
shader[i] = new FShader;
if (!shader[i]->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str.GetChars()))
{
delete shader[i];
shader[i] = NULL;
}
}
catch(CRecoverableError &err)
{
shader[i] = NULL;
I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage());
}
if (shader != NULL) delete shader;
shader = NULL;
I_Error("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage());
}
return shader;
}
//==========================================================================
//
//
//
//==========================================================================
FShaderContainer::~FShaderContainer()
{
if (shader_cm != NULL) delete shader_cm;
if (shader_fl != NULL) delete shader_fl;
for (int i = 0; i < NUM_SHADERS; i++)
{
if (shader[i] != NULL)
{
delete shader[i];
shader[i] = NULL;
}
}
}
//==========================================================================
//
//
//
//==========================================================================
FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights)
{
FShader *sh=NULL;
if (cm == CM_FOGLAYER)
{
if (shader_fl)
{
shader_fl->Bind(Speed);
}
return shader_fl;
}
else if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_MAXCOLORMAP)
{
// these are never used with any kind of lighting or fog
sh = shader_cm;
// [BB] If there was a problem when loading the shader, sh is NULL here.
if( sh )
{
FSpecialColormap *map = &SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP];
sh->Bind(Speed);
float m[3]= {map->ColorizeEnd[0] - map->ColorizeStart[0],
map->ColorizeEnd[1] - map->ColorizeStart[1], map->ColorizeEnd[2] - map->ColorizeStart[2]};
glUniform3fv(sh->colormapstart_index, 1, map->ColorizeStart);
glUniform3fv(sh->colormaprange_index, 1, m);
}
}
else
{
bool desat = false;// cm >= CM_DESAT1 && cm <= CM_DESAT31;
sh = shader[glowing + 2*desat + 4*lights + (glset.lightmode & 8)];
// [BB] If there was a problem when loading the shader, sh is NULL here.
if( sh )
{
sh->Bind(Speed);
if (desat)
{
//glUniform1f(sh->desaturation_index, 1.f-float(cm-CM_DESAT0)/(CM_DESAT31-CM_DESAT0));
}
}
}
return sh;
}
//==========================================================================
//
//
@ -454,8 +311,10 @@ struct FEffectShader
static const FEffectShader effectshaders[]=
{
{"fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "#define NO_GLOW\n"},
{"spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define NO_GLOW\n#define NO_DESATURATE\n#define SPHEREMAP\n#define SPHEREMAP_0\n"}
{ "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "" },
{ "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define SPHEREMAP\n" },
{ "burn", "shaders/glsl/burn.vp", "shaders/glsl/burn.fp", NULL, "" },
{ "stencil", "shaders/glsl/stencil.vp", "shaders/glsl/stencil.fp", NULL, "" },
};
@ -489,35 +348,46 @@ FShaderManager::~FShaderManager()
void FShaderManager::CompileShaders()
{
mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL;
if (gl.hasGLSL())
try
{
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL;
if (gl.hasGLSL())
{
FShaderContainer * shc = new FShaderContainer(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc);
mTextureEffects.Push(shc);
}
for(unsigned i = 0; i < usershaders.Size(); i++)
{
FString name = ExtractFileBase(usershaders[i]);
FName sfn = name;
FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]);
mTextureEffects.Push(shc);
}
for(int i=0;i<NUM_EFFECTS;i++)
{
FShader *eff = new FShader();
if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
effectshaders[i].fp2, effectshaders[i].defines))
for (int i = 0; defaultshaders[i].ShaderName != NULL; i++)
{
delete eff;
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc);
mTextureEffects.Push(shc);
}
for (unsigned i = 0; i < usershaders.Size(); i++)
{
FString name = ExtractFileBase(usershaders[i]);
FName sfn = name;
FShader *shc = Compile(sfn, usershaders[i]);
mTextureEffects.Push(shc);
}
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))
{
delete eff;
}
else mEffectShaders[i] = eff;
}
else mEffectShaders[i] = eff;
}
}
catch (CRecoverableError &err)
{
// If shader compilation failed we can still run the fixed function mode so do that instead of aborting.
Printf("%s\n", err.GetMessage());
Printf(PRINT_HIGH, "Failed to compile shaders. Reverting to fixed function mode\n");
gl_usevbo = false;
gl.glslversion = 0.0;
}
}
//==========================================================================
@ -528,17 +398,22 @@ void FShaderManager::CompileShaders()
void FShaderManager::Clean()
{
SetActiveShader(NULL);
for(unsigned int i=0;i<mTextureEffects.Size();i++)
if (gl.hasGLSL())
{
if (mTextureEffects[i] != NULL) delete mTextureEffects[i];
glUseProgram(NULL);
mActiveShader = NULL;
for (unsigned int i = 0; i < mTextureEffects.Size(); i++)
{
if (mTextureEffects[i] != NULL) delete mTextureEffects[i];
}
for (int i = 0; i < MAX_EFFECTS; i++)
{
if (mEffectShaders[i] != NULL) delete mEffectShaders[i];
mEffectShaders[i] = NULL;
}
mTextureEffects.Clear();
}
for(int i=0;i<NUM_EFFECTS;i++)
{
if (mEffectShaders[i] != NULL) delete mEffectShaders[i];
mEffectShaders[i] = NULL;
}
mTextureEffects.Clear();
}
//==========================================================================
@ -553,7 +428,7 @@ int FShaderManager::Find(const char * shn)
for(unsigned int i=0;i<mTextureEffects.Size();i++)
{
if (mTextureEffects[i]->Name == sfn)
if (mTextureEffects[i]->mName == sfn)
{
return i;
}
@ -569,26 +444,42 @@ int FShaderManager::Find(const char * shn)
void FShaderManager::SetActiveShader(FShader *sh)
{
// shadermodel needs to be tested here because without it UseProgram will be NULL.
if (gl.hasGLSL() && mActiveShader != sh)
{
glUseProgram(sh == NULL? 0 : sh->GetHandle());
glUseProgram(sh!= NULL? sh->GetHandle() : NULL);
mActiveShader = sh;
}
}
//==========================================================================
//
// To avoid maintenance this will be set when a warped texture is bound
// because at that point the draw buffer needs to be flushed anyway.
//
//==========================================================================
void FShaderManager::SetWarpSpeed(unsigned int eff, float speed)
{
// indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom
if (eff < mTextureEffects.Size())
{
FShader *sh = mTextureEffects[eff];
float warpphase = gl_frameMS * speed / 1000.f;
glProgramUniform1f(sh->GetHandle(), sh->timer_index, warpphase);
}
}
//
//==========================================================================
FShader *FShaderManager::BindEffect(int effect)
{
if (effect > 0 && effect <= NUM_EFFECTS && mEffectShaders[effect-1] != NULL)
if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[effect] != NULL)
{
mEffectShaders[effect-1]->Bind(0);
return mEffectShaders[effect-1];
mEffectShaders[effect]->Bind();
return mEffectShaders[effect];
}
return NULL;
}

View file

@ -7,80 +7,198 @@
extern bool gl_shaderactive;
const int VATTR_FOGPARAMS = 14;
const int VATTR_LIGHTLEVEL = 13; // Korshun.
//==========================================================================
//
//
//==========================================================================
class FUniform1i
{
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
}
void Set(int newvalue)
{
glUniform1i(mIndex, newvalue);
}
};
class FBufferedUniform1i
{
int mBuffer;
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
mBuffer = 0;
}
void Set(int newvalue)
{
if (newvalue != mBuffer)
{
mBuffer = newvalue;
glUniform1i(mIndex, newvalue);
}
}
};
class FBufferedUniform4i
{
int mBuffer[4];
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
memset(mBuffer, 0, sizeof(mBuffer));
}
void Set(const int *newvalue)
{
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
{
memcpy(mBuffer, newvalue, sizeof(mBuffer));
glUniform4iv(mIndex, 1, newvalue);
}
}
};
class FBufferedUniform1f
{
int mBuffer;
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
mBuffer = 0;
}
void Set(float newvalue)
{
if (newvalue != mBuffer)
{
mBuffer = newvalue;
glUniform1f(mIndex, newvalue);
}
}
};
class FBufferedUniform4f
{
float mBuffer[4];
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
memset(mBuffer, 0, sizeof(mBuffer));
}
void Set(const float *newvalue)
{
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
{
memcpy(mBuffer, newvalue, sizeof(mBuffer));
glUniform4fv(mIndex, 1, newvalue);
}
}
};
class FUniform4f
{
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
}
void Set(const float *newvalue)
{
glUniform4fv(mIndex, 1, newvalue);
}
void Set(float a, float b, float c, float d)
{
glUniform4f(mIndex, a, b, c, d);
}
};
class FBufferedUniformPE
{
PalEntry mBuffer;
int mIndex;
public:
void Init(GLuint hShader, const GLchar *name)
{
mIndex = glGetUniformLocation(hShader, name);
mBuffer = 0;
}
void Set(PalEntry newvalue)
{
if (newvalue != mBuffer)
{
mBuffer = newvalue;
glUniform4f(mIndex, newvalue.r/255.f, newvalue.g/255.f, newvalue.b/255.f, newvalue.a/255.f);
}
}
};
//==========================================================================
//
//
//==========================================================================
class FShader
{
friend class FShaderContainer;
friend class FShaderManager;
friend class FRenderState;
unsigned int hShader;
unsigned int hVertProg;
unsigned int hFragProg;
FName mName;
FBufferedUniform1f muDesaturation;
FBufferedUniform1i muFogEnabled;
FBufferedUniform1i muTextureMode;
FBufferedUniform4f muCameraPos;
FBufferedUniform4f muLightParms;
FUniform1i muFixedColormap;
FUniform4f muColormapStart;
FUniform4f muColormapRange;
FBufferedUniform4i muLightRange;
FBufferedUniformPE muFogColor;
FBufferedUniformPE muDynLightColor;
FBufferedUniformPE muObjectColor;
FUniform4f muGlowBottomColor;
FUniform4f muGlowTopColor;
FUniform4f muGlowBottomPlane;
FUniform4f muGlowTopPlane;
int timer_index;
int desaturation_index;
int fogenabled_index;
int texturemode_index;
int camerapos_index;
int lightparms_index;
int colormapstart_index;
int colormaprange_index;
int lightrange_index;
int fogcolor_index;
int lights_index;
int dlightcolor_index;
int glowbottomcolor_index;
int glowtopcolor_index;
int glowbottomplane_index;
int glowtopplane_index;
int objectcolor_index;
PalEntry currentdlightcolor;
PalEntry currentobjectcolor;
int currentglowstate;
int currentfogenabled;
int currenttexturemode;
float currentlightfactor;
float currentlightdist;
PalEntry currentfogcolor;
float currentfogdensity;
FStateVec3 currentcamerapos;
int currentfixedcolormap;
public:
FShader()
FShader(const char *name)
: mName(name)
{
hShader = hVertProg = hFragProg = 0;
currentglowstate = currentfogenabled = currenttexturemode = 0;
currentlightfactor = currentlightdist = 0.0f;
currentfogdensity = -1;
currentdlightcolor = currentobjectcolor = currentfogcolor = 0;
timer_index = -1;
desaturation_index = -1;
fogenabled_index = -1;
texturemode_index = -1;
camerapos_index = -1;
lightparms_index = -1;
colormapstart_index = -1;
colormaprange_index = -1;
lightrange_index = -1;
fogcolor_index = -1;
lights_index = -1;
dlightcolor_index = -1;
objectcolor_index = -1;
glowtopplane_index = -1;
glowbottomplane_index = -1;
glowtopcolor_index = -1;
glowbottomcolor_index = -1;
currentglowstate = 0;
currentfixedcolormap = 0;
}
~FShader();
@ -91,34 +209,10 @@ public:
void SetGlowParams(float *topcolors, float topheight, float *bottomcolors, float bottomheight);
void SetLightRange(int start, int end, int forceadd);
bool Bind(float Speed);
bool Bind();
unsigned int GetHandle() const { return hShader; }
};
//==========================================================================
//
// This class contains the shaders for the different lighting modes
// that are required (e.g. special colormaps etc.)
//
//==========================================================================
class FShaderContainer
{
friend class FShaderManager;
FName Name;
enum { NUM_SHADERS = 16 };
FShader *shader[NUM_SHADERS];
FShader *shader_cm; // the shader for fullscreen colormaps
FShader *shader_fl; // the shader for the fog layer
public:
FShaderContainer(const char *ShaderName, const char *ShaderPath);
~FShaderContainer();
FShader *Bind(int cm, bool glowing, float Speed, bool lights);
};
@ -129,14 +223,9 @@ public:
//==========================================================================
class FShaderManager
{
enum
{
NUM_EFFECTS = 2
};
TArray<FShaderContainer*> mTextureEffects;
TArray<FShader*> mTextureEffects;
FShader *mActiveShader;
FShader *mEffectShaders[NUM_EFFECTS];
FShader *mEffectShaders[MAX_EFFECTS];
void Clean();
void CompileShaders();
@ -144,11 +233,13 @@ class FShaderManager
public:
FShaderManager();
~FShaderManager();
FShader *Compile(const char *ShaderName, const char *ShaderPath);
int Find(const char *mame);
FShader *BindEffect(int effect);
void SetActiveShader(FShader *sh);
void SetWarpSpeed(unsigned int eff, float speed);
FShaderContainer *Get(unsigned int eff)
FShader *Get(unsigned int eff)
{
// indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom
if (eff < mTextureEffects.Size())

View file

@ -136,7 +136,7 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
{
BYTE *buffer = GetPixels() + 4*originx + Pitch*originy;
// CM_SHADE is an alpha map with 0==transparent and 1==opaque
// alpha map with 0==transparent and 1==opaque
if (alphatex)
{
for(int i=0;i<256;i++)

View file

@ -1,8 +1,5 @@
uniform int fogenabled;
uniform vec4 fogcolor;
uniform vec3 camerapos;
varying vec4 pixelpos;
varying vec4 fogparm;
in vec4 pixelpos;
in vec2 glowdist;
//===========================================================================
//
@ -18,15 +15,15 @@ void main()
//
// calculate fog factor
//
if (fogenabled == -1)
if (uFogEnabled == -1)
{
fogdist = pixelpos.w;
}
else
{
fogdist = max(16.0, distance(pixelpos.xyz, camerapos));
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
}
fogfactor = exp2 (fogparm.z * fogdist);
gl_FragColor = vec4(fogcolor.rgb, 1.0 - fogfactor);
fogfactor = exp2 (uFogDensity * fogdist);
gl_FragColor = vec4(uFogColor.rgb, 1.0 - fogfactor);
}

View file

@ -1,9 +1,12 @@
uniform sampler2D texture2;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec4 brightpix = desaturate(texture2D(texture2, gl_TexCoord[0].st));
vec4 texel = getTexel(gl_TexCoord[0].st);
return vec4(texel.rgb * min (color.rgb + brightpix.rgb, 1.0), texel.a*color.a);
return getTexel(gl_TexCoord[0].st);
}
vec4 ProcessLight(vec4 color)
{
vec4 brightpix = desaturate(texture2D(texture2, gl_TexCoord[0].st));
return vec4(min (color.rgb + brightpix.rgb, 1.0), color.a);
}

View file

@ -0,0 +1,5 @@
vec4 ProcessLight(vec4 color)
{
return color;
}

View file

@ -1,7 +1,6 @@
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec4 pix = getTexel(gl_TexCoord[0].st);
return pix * color;
return getTexel(gl_TexCoord[0].st);
}

View file

@ -1,6 +1,6 @@
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
return color*objectcolor;
return desaturate(uObjectColor);
}

View file

@ -1,6 +1,6 @@
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
@ -12,6 +12,6 @@ vec4 Process(vec4 color)
texCoord += offset;
return getTexel(texCoord) * color;
return getTexel(texCoord);
}

View file

@ -1,6 +1,6 @@
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
@ -13,6 +13,6 @@ vec4 Process(vec4 color)
texCoord += offset;
return getTexel(texCoord) * color;
return getTexel(texCoord);
}

View file

@ -1,6 +1,6 @@
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
@ -8,6 +8,6 @@ vec4 Process(vec4 color)
texCoord.x += sin(pi * 2.0 * (texCoord.y + timer * 0.125)) * 0.1;
return getTexel(texCoord) * color;
return getTexel(texCoord);
}

View file

@ -1,7 +1,7 @@
//created by Evil Space Tomato
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
@ -10,7 +10,7 @@ vec4 Process(vec4 color)
texSplat.x = texCoord.x + mod(sin(pi * 2.0 * (texCoord.y + timer * 2.0)),0.1) * 0.1;
texSplat.y = texCoord.y + mod(cos(pi * 2.0 * (texCoord.x + timer * 2.0)),0.1) * 0.1;
vec4 basicColor = getTexel(texSplat) * color;
vec4 basicColor = getTexel(texSplat);
float texX = sin(texCoord.x * 100.0 + timer*5.0);
float texY = cos(texCoord.x * 100.0 + timer*5.0);

View file

@ -1,10 +1,10 @@
//created by Evil Space Tomato
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
vec4 basicColor = getTexel(texCoord) * color;
vec4 basicColor = getTexel(texCoord);
texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0;
texCoord.y = float( int(texCoord.y * 128.0) ) / 128.0;

View file

@ -1,10 +1,10 @@
//created by Evil Space Tomato
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
vec4 basicColor = getTexel(texCoord) * color;
vec4 basicColor = getTexel(texCoord);
float texX = texCoord.x / 3.0 + 0.66;
float texY = 0.34 - texCoord.y / 3.0;

View file

@ -1,10 +1,10 @@
//created by Evil Space Tomato
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
vec4 basicColor = getTexel(texCoord) * color;
vec4 basicColor = getTexel(texCoord);
float texX = sin(mod(texCoord.x * 100.0 + timer*5.0, 3.489)) + texCoord.x / 4.0;
float texY = cos(mod(texCoord.y * 100.0 + timer*5.0, 3.489)) + texCoord.y / 4.0;

View file

@ -1,10 +1,10 @@
//created by Evil Space Tomato
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
vec4 basicColor = getTexel(texCoord) * color;
vec4 basicColor = getTexel(texCoord);
float texX = sin(texCoord.x * 100.0 + timer*5.0);
float texY = cos(texCoord.x * 100.0 + timer*5.0);

View file

@ -1,10 +1,10 @@
//created by Evil Space Tomato
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
vec4 basicColor = getTexel(texCoord) * color;
vec4 basicColor = getTexel(texCoord);
texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0;
texCoord.y = float( int(texCoord.y * 128.0) ) / 128.0;

View file

@ -1,10 +1,10 @@
//created by Evil Space Tomato
uniform float timer;
vec4 Process(vec4 color)
vec4 ProcessTexel()
{
vec2 texCoord = gl_TexCoord[0].st;
vec4 basicColor = getTexel(texCoord) * color;
vec4 basicColor = getTexel(texCoord);
float texX = sin(texCoord.x * 100.0 + timer*5.0);
float texY = cos(texCoord.x * 100.0 + timer*5.0);

View file

@ -1,56 +1,93 @@
// Changing this constant gives results very similar to changing r_visibility.
// Default is 232, it seems to give exactly the same light bands as software renderer.
#define DOOMLIGHTFACTOR 232.0
in vec4 pixelpos;
in vec2 glowdist;
#ifdef DYNLIGHT
// ATI does not like this inside an #ifdef so it will be prepended by the compiling code inside the .EXE now.
//#version 120
//#extension GL_EXT_gpu_shader4 : enable
uniform ivec3 lightrange;
#ifndef MAXLIGHTS128
uniform vec4 lights[256];
#ifdef SHADER_STORAGE_LIGHTS
layout(std430, binding = 3) buffer ParameterBuffer
{
vec4 lights[];
};
#elif defined MAXLIGHTS128
uniform vec4 lights[256];
#else
uniform vec4 lights[128];
#endif
uniform vec4 lights[128];
#endif
uniform int fogenabled;
uniform vec4 fogcolor;
uniform vec4 objectcolor;
uniform vec4 dlightcolor;
uniform vec3 camerapos;
varying vec4 pixelpos;
varying vec4 fogparm;
//uniform vec2 lightparms;
uniform float desaturation_factor;
uniform vec4 topglowcolor;
uniform vec4 bottomglowcolor;
varying vec2 glowdist;
uniform int texturemode;
uniform sampler2D tex;
vec4 Process(vec4 color);
vec4 ProcessTexel();
vec4 ProcessLight(vec4 color);
varying float lightlevel;
//===========================================================================
//
// Desaturate a color
//
//===========================================================================
#ifdef SOFTLIGHT
vec4 desaturate(vec4 texel)
{
if (uDesaturationFactor > 0.0)
{
float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
return mix (vec4(gray,gray,gray,texel.a), texel, uDesaturationFactor);
}
else
{
return texel;
}
}
//===========================================================================
//
// This function is common for all (non-special-effect) fragment shaders
//
//===========================================================================
vec4 getTexel(vec2 st)
{
vec4 texel = texture2D(tex, st);
//
// Apply texture modes
//
switch (uTextureMode)
{
case 1:
texel.rgb = vec3(1.0,1.0,1.0);
break;
case 2:
texel.a = 1.0;
break;
case 3:
texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, texel.a);
break;
}
texel *= uObjectColor;
return desaturate(texel);
}
//===========================================================================
//
// Doom lighting equation ripped from EDGE.
// Big thanks to EDGE developers for making the only port
// that actually replicates software renderer's lighting in OpenGL.
// Float version.
// Basically replace int with float and divide all constants by 31.
//
//===========================================================================
float R_DoomLightingEquation(float light, float dist)
{
// Changing this constant gives results very similar to changing r_visibility.
// Default is 232, it seems to give exactly the same light bands as software renderer.
#define DOOMLIGHTFACTOR 232.0
/* L in the range 0 to 63 */
float L = light * 63.0/31.0;
@ -66,106 +103,97 @@ float R_DoomLightingEquation(float light, float dist)
/* result is colormap index (0 bright .. 31 dark) */
return clamp(index, min_L, 1.0);
}
#endif
//===========================================================================
//
// Desaturate a color
//
//===========================================================================
vec4 desaturate(vec4 texel)
{
#ifndef NO_DESATURATE
float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
return mix (vec4(gray,gray,gray,texel.a), texel, desaturation_factor);
#else
return texel;
#endif
}
//===========================================================================
//
// Calculate light
//
// It is important to note that the light color is not desaturated
// due to ZDoom's implementation weirdness. Everything that's added
// on top of it, e.g. dynamic lights and glows are, though, because
// the objects emitting these lights are also.
//
// This is making this a bit more complicated than it needs to
// because we can't just desaturate the final fragment color.
//
//===========================================================================
vec4 getLightColor(float fogdist, float fogfactor)
{
vec4 color = gl_Color;
#ifdef SOFTLIGHT
float newlightlevel = 1.0 - R_DoomLightingEquation(lightlevel, gl_FragCoord.z);
color.rgb *= clamp(vec3(newlightlevel), 0.0, 1.0);
#endif
#ifndef NO_FOG
//
// apply light diminishing
//
if (fogenabled > 0)
if (uLightLevel >= 0.0)
{
#if (defined(DOOMLIGHT)) && !defined SOFTLIGHT
// special lighting mode 'Doom' not available on older cards for performance reasons.
if (fogdist < fogparm.y)
{
color.rgb *= fogparm.x - (fogdist / fogparm.y) * (fogparm.x - 1.0);
}
#endif
float newlightlevel = 1.0 - R_DoomLightingEquation(uLightLevel, gl_FragCoord.z);
color.rgb *= newlightlevel;
}
else if (uFogEnabled > 0.0)
{
// brightening around the player for light mode 2
if (fogdist < uLightDist)
{
color.rgb *= uLightFactor - (fogdist / uLightDist) * (uLightFactor - 1.0);
}
//color = vec4(color.rgb * (1.0 - fogfactor), color.a);
//
// apply light diminishing through fog equation
//
color.rgb = mix(vec3(0.0, 0.0, 0.0), color.rgb, fogfactor);
}
#endif
#ifndef NO_GLOW
//
// handle glowing walls
//
if (topglowcolor.a > 0.0 && glowdist.x < topglowcolor.a)
if (uGlowTopColor.a > 0.0 && glowdist.x < uGlowTopColor.a)
{
color.rgb += desaturate(topglowcolor * (1.0 - glowdist.x / topglowcolor.a)).rgb;
color.rgb += desaturate(uGlowTopColor * (1.0 - glowdist.x / uGlowTopColor.a)).rgb;
}
if (bottomglowcolor.a > 0.0 && glowdist.y < bottomglowcolor.a)
if (uGlowBottomColor.a > 0.0 && glowdist.y < uGlowBottomColor.a)
{
color.rgb += desaturate(bottomglowcolor * (1.0 - glowdist.y / bottomglowcolor.a)).rgb;
color.rgb += desaturate(uGlowBottomColor * (1.0 - glowdist.y / uGlowBottomColor.a)).rgb;
}
color = min(color, 1.0);
#endif
// calculation of actual light color is complete.
return color;
}
//===========================================================================
//
// Gets a texel and performs common manipulations
//
//===========================================================================
vec4 getTexel(vec2 st)
{
vec4 texel = texture2D(tex, st);
#ifndef NO_TEXTUREMODE
//
// Apply texture modes
// apply brightmaps (or other light manipulation by custom shaders.
//
if (texturemode == 3)
{
texel *=objectcolor;
texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a);
return texel;
}
else if (texturemode == 2)
{
texel.a = 1.0;
}
else if (texturemode == 1)
{
texel.rgb = vec3(1.0,1.0,1.0);
}
#endif
color = ProcessLight(color);
return desaturate(texel * objectcolor);
//
// apply dynamic lights (except additive)
//
vec4 dynlight = uDynLightColor;
if (uLightRange.z > uLightRange.x)
{
//
// modulated lights
//
for(int i=uLightRange.x; i<uLightRange.y; i+=2)
{
vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1];
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
dynlight.rgb += lightcolor.rgb;
}
//
// subtractive lights
//
for(int i=uLightRange.y; i<uLightRange.z; i+=2)
{
vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1];
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
dynlight.rgb -= lightcolor.rgb;
}
}
color.rgb = clamp(color.rgb + desaturate(dynlight).rgb, 0.0, 1.4);
// prevent any unintentional messing around with the alpha.
return vec4(color.rgb, gl_Color.a);
}
//===========================================================================
@ -174,12 +202,10 @@ vec4 getTexel(vec2 st)
//
//===========================================================================
#ifndef NO_FOG
vec4 applyFog(vec4 frag, float fogfactor)
{
return vec4(mix(fogcolor.rgb, frag.rgb, fogfactor), frag.a);
return vec4(mix(uFogColor.rgb, frag.rgb, fogfactor), frag.a);
}
#endif
//===========================================================================
@ -190,72 +216,102 @@ vec4 applyFog(vec4 frag, float fogfactor)
void main()
{
float fogdist = 0.0;
float fogfactor = 0.0;
#ifndef NO_FOG
//
// calculate fog factor
//
if (fogenabled != 0)
vec4 frag = ProcessTexel();
switch (uFixedColormap)
{
if (fogenabled == 1 || fogenabled == -1)
case 0:
{
fogdist = pixelpos.w;
}
else
{
fogdist = max(16.0, distance(pixelpos.xyz, camerapos));
}
fogfactor = exp2 (fogparm.z * fogdist);
}
#endif
vec4 frag = getLightColor(fogdist, fogfactor);
#ifdef DYNLIGHT
vec4 dynlight = dlightcolor;
vec4 addlight = vec4(0.0,0.0,0.0,0.0);
float fogdist = 0.0;
float fogfactor = 0.0;
for(int i=0; i<lightrange.x; i+=2)
{
vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1];
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
dynlight += lightcolor;
}
for(int i=lightrange.x; i<lightrange.y; i+=2)
{
vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1];
//
// calculate fog factor
//
if (uFogEnabled != 0)
{
if (uFogEnabled == 1 || uFogEnabled == -1)
{
fogdist = pixelpos.w;
}
else
{
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
}
fogfactor = exp2 (uFogDensity * fogdist);
}
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
dynlight -= lightcolor;
}
for(int i=lightrange.y; i<lightrange.z; i+=2)
{
vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1];
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
addlight += lightcolor;
frag *= getLightColor(fogdist, fogfactor);
if (uLightRange.w > uLightRange.z)
{
vec4 addlight = vec4(0.0,0.0,0.0,0.0);
//
// additive lights - these can be done after the alpha test.
//
for(int i=uLightRange.z; i<uLightRange.w; i+=2)
{
vec4 lightpos = lights[i];
vec4 lightcolor = lights[i+1];
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
addlight.rgb += lightcolor.rgb;
}
frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0);
}
//
// colored fog
//
if (uFogEnabled < 0)
{
frag = applyFog(frag, fogfactor);
}
break;
}
frag.rgb = clamp(frag.rgb + desaturate(dynlight.rgb), 0.0, 1.4);
#endif
frag = Process(frag);
#ifdef DYNLIGHT
frag.rgb += desaturate(addlight.rgb);
#endif
#ifndef NO_FOG
if (fogenabled < 0)
case 1:
{
frag = applyFog(frag, fogfactor);
float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14);
vec4 cm = uFixedColormapStart + gray * uFixedColormapRange;
frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a*gl_Color.a);
break;
}
#endif
case 2:
{
frag = frag * uFixedColormapStart;
frag.a *= gl_Color.a;
break;
}
case 3:
{
float fogdist;
float fogfactor;
//
// calculate fog factor
//
if (uFogEnabled == -1)
{
fogdist = pixelpos.w;
}
else
{
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
}
fogfactor = exp2 (uFogDensity * fogdist);
frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * gl_Color.a);
break;
}
}
gl_FragColor = frag;
}

View file

@ -1,40 +1,19 @@
#ifndef NO_FOG
varying vec4 pixelpos;
attribute vec4 fogparams;
varying vec4 fogparm;
#endif
#ifndef NO_GLOW
varying vec2 glowdist;
uniform vec4 glowbottomplane, glowtopplane;
#endif
#ifdef SOFTLIGHT
attribute float lightlevel_in;
varying float lightlevel;
#endif
out vec4 pixelpos;
out vec2 glowdist;
void main()
{
#ifdef SOFTLIGHT
lightlevel = lightlevel_in;
#endif
// We use texture matrix 7 as the model matrix and the modelview matrix as the view matrix.
vec4 worldcoord = gl_TextureMatrix[7] * gl_Vertex;
vec4 eyeCoordPos = gl_ModelViewMatrix * worldcoord;
vec4 worldcoord = ModelMatrix * gl_Vertex;
vec4 eyeCoordPos = ViewMatrix * worldcoord;
gl_FrontColor = gl_Color;
#ifndef NO_FOG
pixelpos.xyz = worldcoord.xyz;
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
fogparm = fogparams;
#endif
#ifndef NO_GLOW
glowdist.x = -((glowtopplane.w + glowtopplane.x * worldcoord.x + glowtopplane.y * worldcoord.z) * glowtopplane.z) - worldcoord.y;
glowdist.y = worldcoord.y + ((glowbottomplane.w + glowbottomplane.x * worldcoord.x + glowbottomplane.y * worldcoord.z) * glowbottomplane.z);
#endif
pixelpos.xyz = worldcoord.xyz;
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y;
glowdist.y = worldcoord.y + ((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z);
#ifdef SPHEREMAP
vec3 u = normalize(eyeCoordPos.xyz);
@ -42,17 +21,10 @@ void main()
vec3 r = reflect(u, n);
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5);
#endif
#ifndef SPHEREMAP_0
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
#else
gl_TexCoord[0].xy = sst;
#else
gl_TexCoord[0] = TextureMatrix * gl_MultiTexCoord0;
#endif
gl_Position = gl_ModelViewProjectionMatrix * worldcoord;
#ifdef __GLSL_CG_DATA_TYPES
gl_ClipVertex = eyeCoordPos;
#endif
gl_Position = ProjectionMatrix * eyeCoordPos;
}

View file

@ -1,51 +0,0 @@
uniform int texturemode;
uniform sampler2D tex;
uniform vec4 objectcolor;
uniform vec3 colormapstart;
uniform vec3 colormaprange;
vec4 Process(vec4 color);
vec4 desaturate(vec4 texel)
{
return texel;
}
vec4 getTexel(vec2 st)
{
vec4 texel = texture2D(tex, st);
//
// Apply texture modes
//
if (texturemode == 3)
{
texel *=objectcolor;
texel = vec4(1.0-texel.r, 1.0-texel.g, 1.0-texel.b, texel.a);
return texel;
}
else if (texturemode == 2)
{
texel.a = 1.0;
}
else if (texturemode == 1)
{
texel.rgb = vec3(1.0,1.0,1.0);
}
return texel*objectcolor;
}
void main()
{
vec4 frag = Process(vec4(1.0,1.0,1.0,1.0));
float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14);
vec3 cm = colormapstart + gray * colormaprange;
gl_FragColor = vec4(clamp(cm, 0.0, 1.0), frag.a) * gl_Color;
}

View file

@ -1,55 +0,0 @@
uniform int fogenabled;
uniform vec4 fogcolor;
uniform vec3 camerapos;
varying vec4 pixelpos;
varying vec4 fogparm;
uniform sampler2D tex;
vec4 Process(vec4 color);
//===========================================================================
//
// Gets a texel and performs common manipulations
//
//===========================================================================
vec4 desaturate(vec4 texel)
{
return texel;
}
vec4 getTexel(vec2 st)
{
vec4 texel = texture2D(tex, st);
return texel;
}
//===========================================================================
//
// Main shader routine
//
//===========================================================================
void main()
{
float fogdist;
float fogfactor;
//
// calculate fog factor
//
if (fogenabled == -1)
{
fogdist = pixelpos.w;
}
else
{
fogdist = max(16.0, distance(pixelpos.xyz, camerapos));
}
fogfactor = exp2 (fogparm.z * fogdist);
vec4 frag = Process(vec4(1.0,1.0,1.0,1.0));
gl_FragColor = vec4(fogcolor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * gl_Color.a);
}