- 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; FRenderState gl_RenderState;
int FStateAttr::ChangeCounter; int FStateAttr::ChangeCounter;
extern FShader *FogboundaryShader; extern FShader *FogboundaryShader;
extern FShader *SpheremapShader;
@ -118,14 +119,23 @@ bool FRenderState::ApplyShader()
bool useshaders = false; bool useshaders = false;
FShader *activeShader = NULL; FShader *activeShader = NULL;
switch (mSpecialEffect)
if (mFogboundaryEnabled) // the fog boundary shader is special
{ {
case EFF_FOGBOUNDARY:
FogboundaryShader->Bind(0); FogboundaryShader->Bind(0);
activeShader = FogboundaryShader; activeShader = FogboundaryShader;
} break;
else
case EFF_SPHEREMAP:
if (gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_fog_shader))
{ {
SpheremapShader->Bind(0);
activeShader = SpheremapShader;
}
break;
default:
switch (gl.shadermodel) switch (gl.shadermodel)
{ {
case 2: case 2:
@ -142,7 +152,6 @@ bool FRenderState::ApplyShader()
break; break;
case 4: case 4:
// useshaders = true;
useshaders = ( useshaders = (
mEffectState != 0 || // special shaders mEffectState != 0 || // special shaders
(mFogEnabled && gl_fogmode != 0) || // fog requires a shader (mFogEnabled && gl_fogmode != 0) || // fog requires a shader
@ -167,6 +176,7 @@ bool FRenderState::ApplyShader()
} }
} }
} }
if (activeShader) if (activeShader)
{ {
int fogset = 0; int fogset = 0;
@ -262,6 +272,33 @@ void FRenderState::Apply(bool forcenoshader)
ffFogDensity=mFogDensity; 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 class FRenderState
{ {
bool mTextureEnabled; bool mTextureEnabled;
@ -44,7 +52,7 @@ class FRenderState
bool mGlowEnabled; bool mGlowEnabled;
bool mLightEnabled; bool mLightEnabled;
bool mBrightmapEnabled; bool mBrightmapEnabled;
bool mFogboundaryEnabled; int mSpecialEffect;
int mTextureMode; int mTextureMode;
float mLightParms[2]; float mLightParms[2];
@ -60,6 +68,7 @@ class FRenderState
bool ffTextureEnabled; bool ffTextureEnabled;
bool ffFogEnabled; bool ffFogEnabled;
int ffTextureMode; int ffTextureMode;
int ffSpecialEffect;
PalEntry ffFogColor; PalEntry ffFogColor;
float ffFogDensity; float ffFogDensity;
@ -73,8 +82,9 @@ public:
void Reset() void Reset()
{ {
mFogboundaryEnabled = mTextureEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false; mTextureEnabled = mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false;
ffTextureEnabled = ffFogEnabled = false; ffTextureEnabled = ffFogEnabled = false;
mSpecialEffect = ffSpecialEffect = EFF_NONE;
mFogColor.d = ffFogColor.d = -1; mFogColor.d = ffFogColor.d = -1;
mFogDensity = ffFogDensity = 0; mFogDensity = ffFogDensity = 0;
mTextureMode = ffTextureMode = -1; mTextureMode = ffTextureMode = -1;
@ -98,9 +108,9 @@ public:
mFogEnabled = on; mFogEnabled = on;
} }
void EnableFogboundary(bool on) void SetEffect(int eff)
{ {
mFogboundaryEnabled = on; mSpecialEffect = eff;
} }
void EnableGlow(bool on) void EnableGlow(bool on)

View file

@ -203,11 +203,11 @@ void GLWall::RenderFogBoundary()
{ {
int rel = rellight + (extralight * gl_weaponlight); int rel = rellight + (extralight * gl_weaponlight);
gl_SetFog(lightlevel, rel, &Colormap, false); gl_SetFog(lightlevel, rel, &Colormap, false);
gl_RenderState.EnableFogboundary(true); gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
gl.Disable(GL_ALPHA_TEST); gl.Disable(GL_ALPHA_TEST);
RenderWall(0, NULL); RenderWall(0, NULL);
gl.Enable(GL_ALPHA_TEST); gl.Enable(GL_ALPHA_TEST);
gl_RenderState.EnableFogboundary(false); gl_RenderState.SetEffect(EFF_NONE);
} }
else else
{ {
@ -254,11 +254,12 @@ void GLWall::RenderMirrorSurface()
{ {
if (GLRenderer->mirrortexture == NULL) return; 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 // Use sphere mapping for this
gl.Enable(GL_TEXTURE_GEN_T); gl_RenderState.SetEffect(EFF_SPHEREMAP);
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_SetColor(lightlevel, 0, &Colormap ,0.1f); gl_SetColor(lightlevel, 0, &Colormap ,0.1f);
gl.BlendFunc(GL_SRC_ALPHA,GL_ONE); gl.BlendFunc(GL_SRC_ALPHA,GL_ONE);
@ -270,11 +271,10 @@ void GLWall::RenderMirrorSurface()
pat->BindPatch(Colormap.colormap, 0); pat->BindPatch(Colormap.colormap, 0);
flags &= ~GLWF_GLOW; flags &= ~GLWF_GLOW;
flags |= GLWF_NOSHADER; //flags |= GLWF_NOSHADER;
RenderWall(0,NULL); RenderWall(0,NULL);
gl.Disable(GL_TEXTURE_GEN_T); gl_RenderState.SetEffect(EFF_NONE);
gl.Disable(GL_TEXTURE_GEN_S);
// Restore the defaults for the translucent pass // Restore the defaults for the translucent pass
gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View file

@ -369,6 +369,7 @@ static FDefaultShader defaultshaders[]=
static TArray<FShaderContainer *> AllContainers; static TArray<FShaderContainer *> AllContainers;
FShader *FogboundaryShader; FShader *FogboundaryShader;
FShader *SpheremapShader;
//========================================================================== //==========================================================================
// //
@ -428,6 +429,13 @@ void GLShader::Initialize()
delete FogboundaryShader; delete FogboundaryShader;
FogboundaryShader = NULL; 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() void GLShader::Clear()
@ -443,6 +451,7 @@ void GLShader::Clear()
AllContainers.Clear(); AllContainers.Clear();
AllShaders.Clear(); AllShaders.Clear();
delete FogboundaryShader; delete FogboundaryShader;
delete SpheremapShader;
} }
GLShader *GLShader::Find(const char * shn) 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
}