mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +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_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())
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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++)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
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 getTexel(gl_TexCoord[0].st);
|
||||||
return pix * color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
vec4 Process(vec4 color)
|
vec4 ProcessTexel()
|
||||||
{
|
{
|
||||||
return color*objectcolor;
|
return desaturate(uObjectColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
if (uLightLevel >= 0.0)
|
||||||
color.rgb *= clamp(vec3(newlightlevel), 0.0, 1.0);
|
|
||||||
#endif
|
|
||||||
#ifndef NO_FOG
|
|
||||||
//
|
|
||||||
// apply light diminishing
|
|
||||||
//
|
|
||||||
if (fogenabled > 0)
|
|
||||||
{
|
{
|
||||||
#if (defined(DOOMLIGHT)) && !defined SOFTLIGHT
|
float newlightlevel = 1.0 - R_DoomLightingEquation(uLightLevel, gl_FragCoord.z);
|
||||||
// special lighting mode 'Doom' not available on older cards for performance reasons.
|
color.rgb *= newlightlevel;
|
||||||
if (fogdist < fogparm.y)
|
}
|
||||||
{
|
else if (uFogEnabled > 0.0)
|
||||||
color.rgb *= fogparm.x - (fogdist / fogparm.y) * (fogparm.x - 1.0);
|
{
|
||||||
}
|
// brightening around the player for light mode 2
|
||||||
#endif
|
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);
|
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;
|
|
||||||
|
switch (uFixedColormap)
|
||||||
#ifndef NO_FOG
|
|
||||||
//
|
|
||||||
// calculate fog factor
|
|
||||||
//
|
|
||||||
if (fogenabled != 0)
|
|
||||||
{
|
{
|
||||||
if (fogenabled == 1 || fogenabled == -1)
|
case 0:
|
||||||
{
|
{
|
||||||
fogdist = pixelpos.w;
|
float fogdist = 0.0;
|
||||||
}
|
float fogfactor = 0.0;
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
// calculate fog factor
|
||||||
}
|
//
|
||||||
for(int i=lightrange.x; i<lightrange.y; i+=2)
|
if (uFogEnabled != 0)
|
||||||
{
|
{
|
||||||
vec4 lightpos = lights[i];
|
if (uFogEnabled == 1 || uFogEnabled == -1)
|
||||||
vec4 lightcolor = lights[i+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;
|
frag *= getLightColor(fogdist, fogfactor);
|
||||||
addlight += lightcolor;
|
|
||||||
|
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);
|
case 1:
|
||||||
|
|
||||||
#ifdef DYNLIGHT
|
|
||||||
frag.rgb += desaturate(addlight.rgb);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_FOG
|
|
||||||
if (fogenabled < 0)
|
|
||||||
{
|
{
|
||||||
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;
|
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
|
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.w = -eyeCoordPos.z/eyeCoordPos.w;
|
|
||||||
fogparm = fogparams;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NO_GLOW
|
pixelpos.xyz = worldcoord.xyz;
|
||||||
glowdist.x = -((glowtopplane.w + glowtopplane.x * worldcoord.x + glowtopplane.y * worldcoord.z) * glowtopplane.z) - worldcoord.y;
|
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
||||||
glowdist.y = worldcoord.y + ((glowbottomplane.w + glowbottomplane.x * worldcoord.x + glowbottomplane.y * worldcoord.z) * glowbottomplane.z);
|
|
||||||
#endif
|
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
|
#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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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