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_DEFAULT=0, // untranslated
CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap
// special internal values for texture creation CM_FOGLAYER = 0x10000000, // Sprite shaped fog layer
CM_SHADE= 0x10000002, // alpha channel texture
// These are not to be passed to the texture manager // These are not to be passed to the texture manager
CM_LITE = 0x20000000, // special values to handle these items without excessive hacking CM_LITE = 0x20000000, // special values to handle these items without excessive hacking
CM_TORCH= 0x20000010, // These are not real color manipulations CM_TORCH= 0x20000010, // These are not real color manipulations
CM_FOGLAYER= 0x20000020, // Sprite shaped fog layer
}; };
#define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size()) #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_system.h"
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h" #include "gl/data/gl_data.h"
@ -51,7 +52,6 @@
void gl_SetTextureMode(int type); void gl_SetTextureMode(int type);
FRenderState gl_RenderState; FRenderState gl_RenderState;
int FStateAttr::ChangeCounter;
CVAR(Bool, gl_direct_state_change, true, 0) CVAR(Bool, gl_direct_state_change, true, 0)
@ -71,6 +71,7 @@ void FRenderState::Reset()
mFogColor.d = ffFogColor.d = -1; mFogColor.d = ffFogColor.d = -1;
mFogDensity = ffFogDensity = 0; mFogDensity = ffFogDensity = 0;
mTextureMode = ffTextureMode = -1; mTextureMode = ffTextureMode = -1;
mDesaturation = 0;
mSrcBlend = GL_SRC_ALPHA; mSrcBlend = GL_SRC_ALPHA;
mDstBlend = GL_ONE_MINUS_SRC_ALPHA; mDstBlend = GL_ONE_MINUS_SRC_ALPHA;
glSrcBlend = glDstBlend = -1; glSrcBlend = glDstBlend = -1;
@ -83,6 +84,7 @@ void FRenderState::Reset()
m2D = true; m2D = true;
mVertexBuffer = mCurrentVertexBuffer = NULL; mVertexBuffer = mCurrentVertexBuffer = NULL;
mColormapState = CM_DEFAULT; mColormapState = CM_DEFAULT;
mLightParms[3] = -1.f;
} }
@ -128,11 +130,12 @@ bool FRenderState::ApplyShader()
{ {
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect);
} }
FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4); FShader *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4);
if (shd != NULL) if (shd != NULL)
{ {
activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled); activeShader = shd;
shd->Bind();
} }
int fogset = 0; int fogset = 0;
@ -149,74 +152,93 @@ bool FRenderState::ApplyShader()
} }
} }
if (fogset != activeShader->currentfogenabled) glColor4fv(mColor.vec);
{
glUniform1i(activeShader->fogenabled_index, (activeShader->currentfogenabled = fogset)); activeShader->muDesaturation.Set(mDesaturation);
} activeShader->muFogEnabled.Set(fogset);
if (mTextureMode != activeShader->currenttexturemode) activeShader->muTextureMode.Set(mTextureMode);
{ activeShader->muCameraPos.Set(mCameraPos.vec);
glUniform1i(activeShader->texturemode_index, (activeShader->currenttexturemode = mTextureMode)); activeShader->muLightParms.Set(mLightParms);
} activeShader->muFogColor.Set(mFogColor);
if (activeShader->currentcamerapos.Update(&mCameraPos)) activeShader->muObjectColor.Set(mObjectColor);
{ activeShader->muDynLightColor.Set(mDynColor);
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;
glUniform4f (activeShader->fogcolor_index, mFogColor.r/255.f, mFogColor.g/255.f,
mFogColor.b/255.f, 0);
}
if (mGlowEnabled) if (mGlowEnabled)
{ {
glUniform4fv(activeShader->glowtopcolor_index, 1, mGlowTop.vec); activeShader->muGlowTopColor.Set(mGlowTop.vec);
glUniform4fv(activeShader->glowbottomcolor_index, 1, mGlowBottom.vec); activeShader->muGlowBottomColor.Set(mGlowBottom.vec);
glUniform4fv(activeShader->glowtopplane_index, 1, mGlowTopPlane.vec); activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec);
glUniform4fv(activeShader->glowbottomplane_index, 1, mGlowBottomPlane.vec); activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec);
activeShader->currentglowstate = 1; activeShader->currentglowstate = 1;
} }
else if (activeShader->currentglowstate) else if (activeShader->currentglowstate)
{ {
// if glowing is on, disable it. // if glowing is on, disable it.
glUniform4f(activeShader->glowtopcolor_index, 0.f, 0.f, 0.f, 0.f); static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
glUniform4f(activeShader->glowbottomcolor_index, 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; activeShader->currentglowstate = 0;
} }
if (mLightEnabled) if (mLightEnabled)
{ {
glUniform3iv(activeShader->lightrange_index, 1, mNumLights); activeShader->muLightRange.Set(mNumLights);
glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData); glUniform4fv(activeShader->lights_index, mNumLights[3], mLightData);
} }
if (mObjectColor != activeShader->currentobjectcolor) else
{ {
activeShader->currentobjectcolor = mObjectColor; static const int nulint[] = { 0, 0, 0, 0 };
glUniform4f(activeShader->objectcolor_index, mObjectColor.r / 255.f, mObjectColor.g / 255.f, mObjectColor.b / 255.f, mObjectColor.a / 255.f); activeShader->muLightRange.Set(nulint);
}
if (mDynColor != activeShader->currentdlightcolor)
{
activeShader->currentobjectcolor = mObjectColor;
glUniform4f(activeShader->dlightcolor_index, mDynColor.r / 255.f, mDynColor.g / 255.f, mDynColor.b / 255.f, 0);
} }
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 true;
} }
return false; return false;
@ -326,6 +348,14 @@ void FRenderState::Apply(bool forcenoshader)
} }
ffSpecialEffect = mSpecialEffect; 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 <string.h>
#include "gl/system/gl_interface.h" #include "gl/system/gl_interface.h"
#include "gl/data/gl_data.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "r_defs.h" #include "r_defs.h"
@ -10,81 +11,29 @@ class FVertexBuffer;
EXTERN_CVAR(Bool, gl_direct_state_change) EXTERN_CVAR(Bool, gl_direct_state_change)
struct FStateAttr struct FStateVec4
{
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
{ {
float vec[4]; 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) void Set(float r, float g, float b, float a)
{ {
vec[0] = r; vec[0] = r;
vec[1] = g; vec[1] = g;
vec[2] = b; vec[2] = b;
vec[3] = a; vec[3] = a;
mLastChange = ++ChangeCounter;
} }
}; };
enum EEffect enum EEffect
{ {
EFF_NONE, EFF_NONE=-1,
EFF_FOGBOUNDARY, EFF_FOGBOUNDARY,
EFF_SPHEREMAP, EFF_SPHEREMAP,
EFF_BURN,
EFF_STENCIL,
MAX_EFFECTS
}; };
class FRenderState class FRenderState
@ -96,9 +45,10 @@ class FRenderState
bool mBrightmapEnabled; bool mBrightmapEnabled;
int mSpecialEffect; int mSpecialEffect;
int mTextureMode; int mTextureMode;
int mDesaturation;
int mSoftLight; int mSoftLight;
float mLightParms[2]; float mLightParms[4];
int mNumLights[3]; int mNumLights[4];
float *mLightData; float *mLightData;
int mSrcBlend, mDstBlend; int mSrcBlend, mDstBlend;
int mAlphaFunc; int mAlphaFunc;
@ -109,7 +59,7 @@ class FRenderState
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
FStateVec4 mColor; FStateVec4 mColor;
FStateVec3 mCameraPos; FStateVec4 mCameraPos;
FStateVec4 mGlowTop, mGlowBottom; FStateVec4 mGlowTop, mGlowBottom;
FStateVec4 mGlowTopPlane, mGlowBottomPlane; FStateVec4 mGlowTopPlane, mGlowBottomPlane;
PalEntry mFogColor; PalEntry mFogColor;
@ -155,25 +105,25 @@ public:
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0) void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
{ {
mColor.Set(r, g, b, a); mColor.Set(r, g, b, a);
glColor4fv(mColor.vec); mDesaturation = desat;
} }
void SetColor(PalEntry pe, int desat = 0) 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); 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) 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); mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, alpha);
glColor4fv(mColor.vec); mDesaturation = desat;
} }
void ResetColor() void ResetColor()
{ {
mColor.Set(1,1,1,1); mColor.Set(1,1,1,1);
glColor4fv(mColor.vec); mDesaturation = 0;
} }
void SetTextureMode(int mode) void SetTextureMode(int mode)
@ -213,7 +163,7 @@ public:
void SetCameraPos(float x, float y, float z) 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) void SetGlowParams(float *t, float *b)
@ -224,7 +174,8 @@ public:
void SetSoftLightLevel(int level) 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) void SetGlowPlanes(const secplane_t &top, const secplane_t &bottom)
@ -235,7 +186,7 @@ public:
void SetDynLight(float r, float g, float b) 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) void SetDynLight(PalEntry pe)
@ -250,21 +201,23 @@ public:
void SetFog(PalEntry c, float d) void SetFog(PalEntry c, float d)
{ {
const float LOG2E = 1.442692f; // = 1/log(2)
mFogColor = c; mFogColor = c;
if (d >= 0.0f) mFogDensity = d; if (d >= 0.0f) mLightParms[2] = d * (-LOG2E / 64000.f);
} }
void SetLightParms(float f, float d) void SetLightParms(float f, float d)
{ {
mLightParms[0] = f; mLightParms[1] = f;
mLightParms[1] = d; mLightParms[0] = d;
} }
void SetLights(int *numlights, float *lightdata) void SetLights(int *numlights, float *lightdata)
{ {
mNumLights[0] = numlights[0]; mNumLights[0] = 0;
mNumLights[1] = numlights[1]; mNumLights[1] = numlights[0];
mNumLights[2] = numlights[2]; mNumLights[2] = numlights[1];
mNumLights[3] = numlights[2];
mLightData = lightdata; // caution: the data must be preserved by the caller until the 'apply' call! 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); DrawPlayerSprites (viewsector, false);
} }
gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.SetSoftLightLevel(-1);
DrawTargeterSprites(); DrawTargeterSprites();
DrawBlend(viewsector); 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); FieldOfView * 360.0f / FINEANGLES, 1.6f, 1.6f, true, false);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
gl_RenderState.SetFixedColormap(CM_DEFAULT); gl_RenderState.SetFixedColormap(CM_DEFAULT);
gl_RenderState.SetSoftLightLevel(-1);
screen->Begin2D(false); screen->Begin2D(false);
DrawBlend(viewsector); DrawBlend(viewsector);
glFlush(); 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. // If we get here we know that we have colored fog and no fixed colormap.
gl_SetFog(foglevel, rel, &Colormap, additivefog); 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.BlendEquation(GL_FUNC_ADD);
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl_RenderState.Apply(); gl_RenderState.Apply();
@ -308,7 +308,7 @@ void GLSprite::Draw(int pass)
glVertex3fv(&v4[0]); glVertex3fv(&v4[0]);
} }
glEnd(); glEnd();
gl_RenderState.SetFixedColormap(CM_DEFAULT);
} }
} }
else 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; PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
ThingColor.a = 255;
visstyle_t vis; visstyle_t vis;

View file

@ -57,17 +57,6 @@
#include "gl/shaders/gl_shader.h" #include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_material.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()) 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); int vp_lump = Wads.CheckNumForFullName(vert_prog_lump);
if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump); if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump);
FMemLump vp_data = Wads.ReadLump(vp_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); 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"; vp_comb << vp_data.GetString().GetChars() << "\n";
fp_comb << fp_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); if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump);
FMemLump pp_data = Wads.ReadLump(pp_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(); 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) // 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, hVertProg);
glAttachShader(hShader, hFragProg); glAttachShader(hShader, hFragProg);
glBindAttribLocation(hShader, VATTR_FOGPARAMS, "fogparams");
glBindAttribLocation(hShader, VATTR_LIGHTLEVEL, "lightlevel_in"); // Korshun.
glLinkProgram(hShader); glLinkProgram(hShader);
glGetShaderInfoLog(hVertProg, 10000, NULL, buffer); 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"; error << "Linking:\n" << buffer << "\n";
} }
int linked; int linked;
glGetShaderiv(hShader, GL_LINK_STATUS, &linked); glGetProgramiv(hShader, GL_LINK_STATUS, &linked);
if (linked == 0) if (linked == 0)
{ {
// only print message if there's an error. // 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"); muDesaturation.Init(hShader, "uDesaturationFactor");
glowbottomplane_index = glGetUniformLocation(hShader, "glowbottomplane"); muFogEnabled.Init(hShader, "uFogEnabled");
glowtopplane_index = glGetUniformLocation(hShader, "glowtopplane"); 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); glUseProgram(hShader);
@ -203,9 +218,12 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
FShader::~FShader() FShader::~FShader()
{ {
glDeleteProgram(hShader); if (gl.hasGLSL())
glDeleteShader(hVertProg); {
glDeleteShader(hFragProg); glDeleteProgram(hShader);
glDeleteShader(hVertProg);
glDeleteShader(hFragProg);
}
} }
@ -215,202 +233,41 @@ FShader::~FShader()
// //
//========================================================================== //==========================================================================
bool FShader::Bind(float Speed) bool FShader::Bind()
{ {
GLRenderer->mShaderManager->SetActiveShader(this); GLRenderer->mShaderManager->SetActiveShader(this);
if (timer_index >=0 && Speed > 0.f) glUniform1f(timer_index, gl_frameMS*Speed/1000.f);
return true; 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[] = { // this can't be in the shader code due to ATI strangeness.
"#define NO_GLOW\n#define NO_DESATURATE\n", const char *str = (gl.MaxLights() == 128)? "#define MAXLIGHTS128\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";
FShader *shader = NULL;
try try
{ {
shader_cm = new FShader; shader = new FShader(ShaderName);
if (!shader_cm->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main_colormap.fp", ShaderPath, "#define NO_FOG\n#define NO_GLOW\n")) if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str))
{ {
delete shader_cm; I_Error("Unable to load shader %s\n", ShaderName);
shader_cm = NULL;
} }
} }
catch(CRecoverableError &err) catch(CRecoverableError &err)
{ {
shader_cm = NULL; if (shader != NULL) delete shader;
I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage()); shader = NULL;
} I_Error("Unable to load shader %s:\n%s\n", ShaderName, 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());
}
} }
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[]= static const FEffectShader effectshaders[]=
{ {
{"fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "#define NO_GLOW\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 NO_GLOW\n#define NO_DESATURATE\n#define SPHEREMAP\n#define SPHEREMAP_0\n"} { "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() void FShaderManager::CompileShaders()
{ {
mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; try
if (gl.hasGLSL())
{ {
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); for (int i = 0; defaultshaders[i].ShaderName != NULL; i++)
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))
{ {
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() void FShaderManager::Clean()
{ {
SetActiveShader(NULL); if (gl.hasGLSL())
for(unsigned int i=0;i<mTextureEffects.Size();i++)
{ {
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++) for(unsigned int i=0;i<mTextureEffects.Size();i++)
{ {
if (mTextureEffects[i]->Name == sfn) if (mTextureEffects[i]->mName == sfn)
{ {
return i; return i;
} }
@ -569,26 +444,42 @@ int FShaderManager::Find(const char * shn)
void FShaderManager::SetActiveShader(FShader *sh) void FShaderManager::SetActiveShader(FShader *sh)
{ {
// shadermodel needs to be tested here because without it UseProgram will be NULL.
if (gl.hasGLSL() && mActiveShader != sh) if (gl.hasGLSL() && mActiveShader != sh)
{ {
glUseProgram(sh == NULL? 0 : sh->GetHandle()); glUseProgram(sh!= NULL? sh->GetHandle() : NULL);
mActiveShader = sh; 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) 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); mEffectShaders[effect]->Bind();
return mEffectShaders[effect-1]; return mEffectShaders[effect];
} }
return NULL; return NULL;
} }

View file

@ -7,80 +7,198 @@
extern bool gl_shaderactive; 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 class FShader
{ {
friend class FShaderContainer; friend class FShaderManager;
friend class FRenderState; friend class FRenderState;
unsigned int hShader; unsigned int hShader;
unsigned int hVertProg; unsigned int hVertProg;
unsigned int hFragProg; 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 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 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 currentglowstate;
int currentfogenabled; int currentfixedcolormap;
int currenttexturemode;
float currentlightfactor;
float currentlightdist;
PalEntry currentfogcolor;
float currentfogdensity;
FStateVec3 currentcamerapos;
public: public:
FShader() FShader(const char *name)
: mName(name)
{ {
hShader = hVertProg = hFragProg = 0; hShader = hVertProg = hFragProg = 0;
currentglowstate = currentfogenabled = currenttexturemode = 0; currentglowstate = 0;
currentlightfactor = currentlightdist = 0.0f; currentfixedcolormap = 0;
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;
} }
~FShader(); ~FShader();
@ -91,34 +209,10 @@ public:
void SetGlowParams(float *topcolors, float topheight, float *bottomcolors, float bottomheight); void SetGlowParams(float *topcolors, float topheight, float *bottomcolors, float bottomheight);
void SetLightRange(int start, int end, int forceadd); void SetLightRange(int start, int end, int forceadd);
bool Bind(float Speed); bool Bind();
unsigned int GetHandle() const { return hShader; } 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 class FShaderManager
{ {
enum TArray<FShader*> mTextureEffects;
{
NUM_EFFECTS = 2
};
TArray<FShaderContainer*> mTextureEffects;
FShader *mActiveShader; FShader *mActiveShader;
FShader *mEffectShaders[NUM_EFFECTS]; FShader *mEffectShaders[MAX_EFFECTS];
void Clean(); void Clean();
void CompileShaders(); void CompileShaders();
@ -144,11 +233,13 @@ class FShaderManager
public: public:
FShaderManager(); FShaderManager();
~FShaderManager(); ~FShaderManager();
FShader *Compile(const char *ShaderName, const char *ShaderPath);
int Find(const char *mame); int Find(const char *mame);
FShader *BindEffect(int effect); FShader *BindEffect(int effect);
void SetActiveShader(FShader *sh); 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 // indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom
if (eff < mTextureEffects.Size()) 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; 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) if (alphatex)
{ {
for(int i=0;i<256;i++) for(int i=0;i<256;i++)

View file

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

View file

@ -1,9 +1,12 @@
uniform sampler2D texture2; uniform sampler2D texture2;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec4 brightpix = desaturate(texture2D(texture2, gl_TexCoord[0].st)); return getTexel(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);
} }
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 getTexel(gl_TexCoord[0].st);
return pix * color;
} }

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; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; vec2 texCoord = gl_TexCoord[0].st;
@ -12,6 +12,6 @@ vec4 Process(vec4 color)
texCoord += offset; texCoord += offset;
return getTexel(texCoord) * color; return getTexel(texCoord);
} }

View file

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

View file

@ -1,6 +1,6 @@
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; 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; 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 //created by Evil Space Tomato
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; 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.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; 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 texX = sin(texCoord.x * 100.0 + timer*5.0);
float texY = cos(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 //created by Evil Space Tomato
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; 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.x = float( int(texCoord.x * 128.0) ) / 128.0;
texCoord.y = float( int(texCoord.y * 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 //created by Evil Space Tomato
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; vec2 texCoord = gl_TexCoord[0].st;
vec4 basicColor = getTexel(texCoord) * color; vec4 basicColor = getTexel(texCoord);
float texX = texCoord.x / 3.0 + 0.66; float texX = texCoord.x / 3.0 + 0.66;
float texY = 0.34 - texCoord.y / 3.0; float texY = 0.34 - texCoord.y / 3.0;

View file

@ -1,10 +1,10 @@
//created by Evil Space Tomato //created by Evil Space Tomato
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; 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 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; 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 //created by Evil Space Tomato
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; 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 texX = sin(texCoord.x * 100.0 + timer*5.0);
float texY = cos(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 //created by Evil Space Tomato
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; 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.x = float( int(texCoord.x * 128.0) ) / 128.0;
texCoord.y = float( int(texCoord.y * 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 //created by Evil Space Tomato
uniform float timer; uniform float timer;
vec4 Process(vec4 color) vec4 ProcessTexel()
{ {
vec2 texCoord = gl_TexCoord[0].st; 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 texX = sin(texCoord.x * 100.0 + timer*5.0);
float texY = cos(texCoord.x * 100.0 + timer*5.0); float texY = cos(texCoord.x * 100.0 + timer*5.0);

View file

@ -1,56 +1,93 @@
in vec4 pixelpos;
// Changing this constant gives results very similar to changing r_visibility. in vec2 glowdist;
// Default is 232, it seems to give exactly the same light bands as software renderer.
#define DOOMLIGHTFACTOR 232.0
#ifdef DYNLIGHT #ifdef SHADER_STORAGE_LIGHTS
layout(std430, binding = 3) buffer ParameterBuffer
// ATI does not like this inside an #ifdef so it will be prepended by the compiling code inside the .EXE now. {
//#version 120 vec4 lights[];
//#extension GL_EXT_gpu_shader4 : enable };
#elif defined MAXLIGHTS128
uniform ivec3 lightrange; uniform vec4 lights[256];
#ifndef MAXLIGHTS128
uniform vec4 lights[256];
#else #else
uniform vec4 lights[128]; uniform vec4 lights[128];
#endif
#endif #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; uniform sampler2D tex;
vec4 Process(vec4 color); 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. // Doom lighting equation ripped from EDGE.
// Big thanks to EDGE developers for making the only port // Big thanks to EDGE developers for making the only port
// that actually replicates software renderer's lighting in OpenGL. // that actually replicates software renderer's lighting in OpenGL.
// Float version. // Float version.
// Basically replace int with float and divide all constants by 31. // Basically replace int with float and divide all constants by 31.
//
//===========================================================================
float R_DoomLightingEquation(float light, float dist) 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 */ /* L in the range 0 to 63 */
float L = light * 63.0/31.0; 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) */ /* result is colormap index (0 bright .. 31 dark) */
return clamp(index, min_L, 1.0); 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 // 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 getLightColor(float fogdist, float fogfactor)
{ {
vec4 color = gl_Color; 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 (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
//color = vec4(color.rgb * (1.0 - fogfactor), color.a); if (uLightLevel >= 0.0)
{
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);
}
//
// apply light diminishing through fog equation
//
color.rgb = mix(vec3(0.0, 0.0, 0.0), color.rgb, fogfactor); color.rgb = mix(vec3(0.0, 0.0, 0.0), color.rgb, fogfactor);
} }
#endif
#ifndef NO_GLOW
// //
// handle glowing walls // 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); 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) color = ProcessLight(color);
{
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
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) 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() void main()
{ {
float fogdist = 0.0; vec4 frag = ProcessTexel();
float fogfactor = 0.0;
#ifndef NO_FOG switch (uFixedColormap)
//
// calculate fog factor
//
if (fogenabled != 0)
{ {
if (fogenabled == 1 || fogenabled == -1) case 0:
{ {
fogdist = pixelpos.w; float fogdist = 0.0;
float fogfactor = 0.0;
//
// 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);
}
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;
} }
else
case 1:
{ {
fogdist = max(16.0, distance(pixelpos.xyz, camerapos)); 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;
}
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;
} }
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);
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];
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.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)
{
frag = applyFog(frag, fogfactor);
}
#endif
gl_FragColor = frag; 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 out vec4 pixelpos;
attribute float lightlevel_in; out vec2 glowdist;
varying float lightlevel;
#endif
void main() void main()
{ {
#ifdef SOFTLIGHT vec4 worldcoord = ModelMatrix * gl_Vertex;
lightlevel = lightlevel_in; vec4 eyeCoordPos = ViewMatrix * worldcoord;
#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;
gl_FrontColor = gl_Color; gl_FrontColor = gl_Color;
#ifndef NO_FOG pixelpos.xyz = worldcoord.xyz;
pixelpos.xyz = worldcoord.xyz; pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
fogparm = fogparams;
#endif
#ifndef NO_GLOW glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y;
glowdist.x = -((glowtopplane.w + glowtopplane.x * worldcoord.x + glowtopplane.y * worldcoord.z) * glowtopplane.z) - worldcoord.y; glowdist.y = worldcoord.y + ((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z);
glowdist.y = worldcoord.y + ((glowbottomplane.w + glowbottomplane.x * worldcoord.x + glowbottomplane.y * worldcoord.z) * glowbottomplane.z);
#endif
#ifdef SPHEREMAP #ifdef SPHEREMAP
vec3 u = normalize(eyeCoordPos.xyz); vec3 u = normalize(eyeCoordPos.xyz);
@ -42,17 +21,10 @@ void main()
vec3 r = reflect(u, n); 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) ); 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); 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; gl_TexCoord[0].xy = sst;
#else
gl_TexCoord[0] = TextureMatrix * gl_MultiTexCoord0;
#endif #endif
gl_Position = gl_ModelViewProjectionMatrix * worldcoord; gl_Position = ProjectionMatrix * eyeCoordPos;
#ifdef __GLSL_CG_DATA_TYPES
gl_ClipVertex = eyeCoordPos;
#endif
} }

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);
}