- for some reason using world coordinates for clipping in the shader is somewhat imprecise so the clip plane heights have to be adjusted a bit for it.

This commit is contained in:
Christoph Oelckers 2014-07-13 13:25:42 +02:00
parent 60dc2e1122
commit 00fcf4bc06
8 changed files with 52 additions and 27 deletions

View file

@ -83,7 +83,8 @@ void FRenderState::Reset()
mColormapState = CM_DEFAULT; mColormapState = CM_DEFAULT;
mLightParms[3] = -1.f; mLightParms[3] = -1.f;
mSpecialEffect = EFF_NONE; mSpecialEffect = EFF_NONE;
mClipHeight = 0.f; mClipHeightTop = 65536.f;
mClipHeightBottom = -65536.f;
} }
@ -145,7 +146,8 @@ bool FRenderState::ApplyShader()
activeShader->muObjectColor.Set(mObjectColor); activeShader->muObjectColor.Set(mObjectColor);
activeShader->muDynLightColor.Set(mDynColor.vec); activeShader->muDynLightColor.Set(mDynColor.vec);
activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muInterpolationFactor.Set(mInterpolationFactor);
activeShader->muClipHeight.Set(mClipHeight); activeShader->muClipHeightTop.Set(mClipHeightTop);
activeShader->muClipHeightBottom.Set(mClipHeightBottom);
if (mGlowEnabled) if (mGlowEnabled)
{ {

View file

@ -57,7 +57,7 @@ class FRenderState
int mBlendEquation; int mBlendEquation;
bool m2D; bool m2D;
float mInterpolationFactor; float mInterpolationFactor;
float mClipHeight; float mClipHeightTop, mClipHeightBottom;
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer; FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
FStateVec4 mColor; FStateVec4 mColor;
@ -101,14 +101,24 @@ public:
mCurrentVertexBuffer = NULL; mCurrentVertexBuffer = NULL;
} }
void SetClipHeight(float clip) void SetClipHeightTop(float clip)
{ {
mClipHeight = clip; mClipHeightTop = clip;
} }
float GetClipHeight() float GetClipHeightTop()
{ {
return mClipHeight; return mClipHeightTop;
}
void SetClipHeightBottom(float clip)
{
mClipHeightBottom = clip;
}
float GetClipHeightBottom()
{
return mClipHeightBottom;
} }
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)

View file

@ -287,8 +287,10 @@ bool GLPortal::Start(bool usestencil, bool doquery)
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
} }
} }
planestack.Push(gl_RenderState.GetClipHeight()); planestack.Push(gl_RenderState.GetClipHeightTop());
gl_RenderState.SetClipHeight(0.f); planestack.Push(gl_RenderState.GetClipHeightBottom());
gl_RenderState.SetClipHeightTop(65536.f);
gl_RenderState.SetClipHeightBottom(-65536.f);
// save viewpoint // save viewpoint
savedviewx=viewx; savedviewx=viewx;
@ -351,7 +353,9 @@ void GLPortal::End(bool usestencil)
float f; float f;
planestack.Pop(f); planestack.Pop(f);
gl_RenderState.SetClipHeight(f); gl_RenderState.SetClipHeightBottom(f);
planestack.Pop(f);
gl_RenderState.SetClipHeightTop(f);
if (usestencil) if (usestencil)
{ {
@ -790,9 +794,9 @@ void GLPlaneMirrorPortal::DrawContents()
validcount++; validcount++;
float f = FIXED2FLOAT(planez); float f = FIXED2FLOAT(planez);
if (PlaneMirrorMode < 0) f -= 65536.f; // ceiling mirror: clip everytihng with a z lower than the portal's ceiling // the coordinate fudging is needed because for some reason this is nowhere near precise and leaves gaps. Strange...
else f += 65536.f; // floor mirror: clip everything with a z higher than the portal's floor if (PlaneMirrorMode < 0) gl_RenderState.SetClipHeightTop(f+0.3f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling
gl_RenderState.SetClipHeight(f); else gl_RenderState.SetClipHeightBottom(f-0.3f); // floor mirror: clip everything with a z higher than the portal's floor
PlaneMirrorFlag++; PlaneMirrorFlag++;
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));

View file

@ -200,7 +200,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
muGlowTopPlane.Init(hShader, "uGlowTopPlane"); muGlowTopPlane.Init(hShader, "uGlowTopPlane");
muFixedColormap.Init(hShader, "uFixedColormap"); muFixedColormap.Init(hShader, "uFixedColormap");
muInterpolationFactor.Init(hShader, "uInterpolationFactor"); muInterpolationFactor.Init(hShader, "uInterpolationFactor");
muClipHeight.Init(hShader, "uClipHeight"); muClipHeightTop.Init(hShader, "uClipHeightTop");
muClipHeightBottom.Init(hShader, "uClipHeightBottom");
timer_index = glGetUniformLocation(hShader, "timer"); timer_index = glGetUniformLocation(hShader, "timer");
lights_index = glGetUniformLocation(hShader, "lights"); lights_index = glGetUniformLocation(hShader, "lights");
@ -249,16 +250,18 @@ bool FShader::Bind()
// //
//========================================================================== //==========================================================================
FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath) FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard)
{ {
FString defines;
// this can't be in the shader code due to ATI strangeness. // this can't be in the shader code due to ATI strangeness.
const char *str = (gl.MaxLights() == 128)? "#define MAXLIGHTS128\n" : ""; if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n";
if (!usediscard) defines += "#define NO_DISCARD\n";
FShader *shader = NULL; FShader *shader = NULL;
try try
{ {
shader = new FShader(ShaderName); shader = new FShader(ShaderName);
if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str)) if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, defines.GetChars()))
{ {
I_FatalError("Unable to load shader %s\n", ShaderName); I_FatalError("Unable to load shader %s\n", ShaderName);
} }
@ -352,11 +355,16 @@ FShaderManager::~FShaderManager()
void FShaderManager::CompileShaders() void FShaderManager::CompileShaders()
{ {
mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL; mActiveShader = NULL;
for (int i = 0; i < MAX_EFFECTS; i++)
{
mEffectShaders[i] = NULL;
}
for(int i=0;defaultshaders[i].ShaderName != NULL;i++) for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
{ {
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc); FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true);
mTextureEffects.Push(shc); mTextureEffects.Push(shc);
} }
@ -365,7 +373,7 @@ void FShaderManager::CompileShaders()
FString name = ExtractFileBase(usershaders[i]); FString name = ExtractFileBase(usershaders[i]);
FName sfn = name; FName sfn = name;
FShader *shc = Compile(sfn, usershaders[i]); FShader *shc = Compile(sfn, usershaders[i], true);
mTextureEffects.Push(shc); mTextureEffects.Push(shc);
} }

View file

@ -193,7 +193,8 @@ class FShader
FUniform4f muGlowBottomPlane; FUniform4f muGlowBottomPlane;
FUniform4f muGlowTopPlane; FUniform4f muGlowTopPlane;
FBufferedUniform1f muInterpolationFactor; FBufferedUniform1f muInterpolationFactor;
FBufferedUniform1f muClipHeight; FBufferedUniform1f muClipHeightTop;
FBufferedUniform1f muClipHeightBottom;
int timer_index; int timer_index;
int lights_index; int lights_index;
@ -244,7 +245,7 @@ class FShaderManager
public: public:
FShaderManager(); FShaderManager();
~FShaderManager(); ~FShaderManager();
FShader *Compile(const char *ShaderName, const char *ShaderPath); FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard);
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);

View file

@ -11,8 +11,8 @@ void main()
{ {
#ifndef NO_DISCARD #ifndef NO_DISCARD
// clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient.
if (pixelpos.y > uClipHeight + 65536.0) discard; if (pixelpos.y > uClipHeightTop) discard;
if (pixelpos.y < uClipHeight - 65536.0) discard; if (pixelpos.y < uClipHeightBottom) discard;
#endif #endif
float fogdist; float fogdist;

View file

@ -218,8 +218,8 @@ void main()
{ {
#ifndef NO_DISCARD #ifndef NO_DISCARD
// clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient. // clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient.
if (pixelpos.y > uClipHeight + 65536.0) discard; if (pixelpos.y > uClipHeightTop) discard;
if (pixelpos.y < uClipHeight - 65536.0) discard; if (pixelpos.y < uClipHeightBottom) discard;
#endif #endif
vec4 frag = ProcessTexel(); vec4 frag = ProcessTexel();

View file

@ -1,7 +1,7 @@
// This file contains common data definitions for both vertex and fragment shader // This file contains common data definitions for both vertex and fragment shader
uniform vec4 uCameraPos; uniform vec4 uCameraPos;
uniform float uClipHeight; uniform float uClipHeightTop, uClipHeightBottom;
uniform int uTextureMode; uniform int uTextureMode;