mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 04:51:19 +00:00
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:
parent
98cc7eeb99
commit
4d005bdfa0
28 changed files with 722 additions and 830 deletions
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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!
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
5
wadsrc/static/shaders/glsl/func_defaultlight.fp
Normal file
5
wadsrc/static/shaders/glsl/func_defaultlight.fp
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
vec4 ProcessLight(vec4 color)
|
||||
{
|
||||
return color;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
return color*objectcolor;
|
||||
return desaturate(uObjectColor);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in a new issue