- added a shader for the sphere map effect on mirrors.

git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@529 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-10-06 21:14:59 +00:00
parent 15a05205ee
commit c99241c60e
5 changed files with 110 additions and 19 deletions

View file

@ -47,6 +47,7 @@
FRenderState gl_RenderState;
int FStateAttr::ChangeCounter;
extern FShader *FogboundaryShader;
extern FShader *SpheremapShader;
@ -118,14 +119,23 @@ bool FRenderState::ApplyShader()
bool useshaders = false;
FShader *activeShader = NULL;
if (mFogboundaryEnabled) // the fog boundary shader is special
switch (mSpecialEffect)
{
case EFF_FOGBOUNDARY:
FogboundaryShader->Bind(0);
activeShader = FogboundaryShader;
}
else
{
break;
case EFF_SPHEREMAP:
if (gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_fog_shader))
{
SpheremapShader->Bind(0);
activeShader = SpheremapShader;
}
break;
default:
switch (gl.shadermodel)
{
case 2:
@ -142,7 +152,6 @@ bool FRenderState::ApplyShader()
break;
case 4:
// useshaders = true;
useshaders = (
mEffectState != 0 || // special shaders
(mFogEnabled && gl_fogmode != 0) || // fog requires a shader
@ -167,6 +176,7 @@ bool FRenderState::ApplyShader()
}
}
}
if (activeShader)
{
int fogset = 0;
@ -262,6 +272,33 @@ void FRenderState::Apply(bool forcenoshader)
ffFogDensity=mFogDensity;
}
}
if (mSpecialEffect != ffSpecialEffect)
{
switch (ffSpecialEffect)
{
case EFF_SPHEREMAP:
gl.Disable(GL_TEXTURE_GEN_T);
gl.Disable(GL_TEXTURE_GEN_S);
default:
break;
}
switch (mSpecialEffect)
{
case EFF_SPHEREMAP:
// Use sphere mapping for this
gl.Enable(GL_TEXTURE_GEN_T);
gl.Enable(GL_TEXTURE_GEN_S);
gl.TexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
gl.TexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
break;
default:
break;
}
ffSpecialEffect = mSpecialEffect;
}
}
}

View file

@ -37,6 +37,14 @@ struct FStateVec3 : public FStateAttr
}
};
enum EEffect
{
EFF_NONE,
EFF_FOGBOUNDARY,
EFF_SPHEREMAP,
};
class FRenderState
{
bool mTextureEnabled;
@ -44,7 +52,7 @@ class FRenderState
bool mGlowEnabled;
bool mLightEnabled;
bool mBrightmapEnabled;
bool mFogboundaryEnabled;
int mSpecialEffect;
int mTextureMode;
float mLightParms[2];
@ -60,6 +68,7 @@ class FRenderState
bool ffTextureEnabled;
bool ffFogEnabled;
int ffTextureMode;
int ffSpecialEffect;
PalEntry ffFogColor;
float ffFogDensity;
@ -73,8 +82,9 @@ public:
void Reset()
{
mFogboundaryEnabled = mTextureEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false;
mTextureEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false;
ffTextureEnabled = ffFogEnabled = false;
mSpecialEffect = ffSpecialEffect = EFF_NONE;
mFogColor.d = ffFogColor.d = -1;
mFogDensity = ffFogDensity = 0;
mTextureMode = ffTextureMode = -1;
@ -98,9 +108,9 @@ public:
mFogEnabled = on;
}
void EnableFogboundary(bool on)
void SetEffect(int eff)
{
mFogboundaryEnabled = on;
mSpecialEffect = eff;
}
void EnableGlow(bool on)

View file

@ -203,11 +203,11 @@ void GLWall::RenderFogBoundary()
{
int rel = rellight + (extralight * gl_weaponlight);
gl_SetFog(lightlevel, rel, &Colormap, false);
gl_RenderState.EnableFogboundary(true);
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
gl.Disable(GL_ALPHA_TEST);
RenderWall(0, NULL);
gl.Enable(GL_ALPHA_TEST);
gl_RenderState.EnableFogboundary(false);
gl_RenderState.SetEffect(EFF_NONE);
}
else
{
@ -254,11 +254,12 @@ void GLWall::RenderMirrorSurface()
{
if (GLRenderer->mirrortexture == NULL) return;
Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1);
v.Normalize();
glNormal3fv(&v[0]);
// Use sphere mapping for this
gl.Enable(GL_TEXTURE_GEN_T);
gl.Enable(GL_TEXTURE_GEN_S);
gl.TexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
gl.TexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
gl_RenderState.SetEffect(EFF_SPHEREMAP);
gl_SetColor(lightlevel, 0, &Colormap ,0.1f);
gl.BlendFunc(GL_SRC_ALPHA,GL_ONE);
@ -270,11 +271,10 @@ void GLWall::RenderMirrorSurface()
pat->BindPatch(Colormap.colormap, 0);
flags &= ~GLWF_GLOW;
flags |= GLWF_NOSHADER;
//flags |= GLWF_NOSHADER;
RenderWall(0,NULL);
gl.Disable(GL_TEXTURE_GEN_T);
gl.Disable(GL_TEXTURE_GEN_S);
gl_RenderState.SetEffect(EFF_NONE);
// Restore the defaults for the translucent pass
gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View file

@ -369,6 +369,7 @@ static FDefaultShader defaultshaders[]=
static TArray<FShaderContainer *> AllContainers;
FShader *FogboundaryShader;
FShader *SpheremapShader;
//==========================================================================
//
@ -428,6 +429,13 @@ void GLShader::Initialize()
delete FogboundaryShader;
FogboundaryShader = NULL;
}
SpheremapShader = new FShader();
if (!SpheremapShader->Load("spheremap", "shaders/glsl/main_spheremap.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define NO_GLOW\n#define NO_DESATURATE\n"))
{
delete SpheremapShader;
SpheremapShader = NULL;
}
}
void GLShader::Clear()
@ -443,6 +451,7 @@ void GLShader::Clear()
AllContainers.Clear();
AllShaders.Clear();
delete FogboundaryShader;
delete SpheremapShader;
}
GLShader *GLShader::Find(const char * shn)

View file

@ -0,0 +1,35 @@
#ifndef NO_FOG
varying vec4 pixelpos;
#endif
#ifndef NO_GLOW
varying vec2 glowdist;
attribute vec2 glowdistance;
#endif
void main()
{
vec4 eyeCoordPos = gl_ModelViewMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
#ifndef NO_FOG
pixelpos.xyz = gl_Vertex.xyz;
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
#endif
#ifndef NO_GLOW
glowdist = glowdistance;
#endif
vec3 u = normalize(eyeCoordPos.xyz);
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
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) );
gl_TexCoord[0].st = vec2(r.x/m + 0.5, r.y/m + 0.5);
gl_Position = ftransform();
#ifdef __GLSL_CG_DATA_TYPES
gl_ClipVertex = eyeCoordPos;
#endif
}