- use the exact same semantics and methods to handle player visibility as in the software renderer.

This fixes invisible player sprites in recursive line portals.
This commit is contained in:
Christoph Oelckers 2016-06-18 12:14:20 +02:00
parent 849ee50689
commit 7b99c883e1
5 changed files with 45 additions and 29 deletions

View file

@ -53,6 +53,12 @@ struct GL_IRECT
}
};
enum
{
DM_MAINVIEW,
DM_OFFSCREEN,
DM_PORTAL
};
class FGLRenderer
{
@ -106,7 +112,7 @@ public:
void RenderMultipassStuff();
void RenderScene(int recursion);
void RenderTranslucent();
void DrawScene(bool toscreen = false);
void DrawScene(int drawmode);
void DrawBlend(sector_t * viewsector);
void DrawPSprite (player_t * player,DPSprite *psp,float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture);

View file

@ -306,9 +306,10 @@ bool GLPortal::Start(bool usestencil, bool doquery)
savedAngle = ViewAngle;
savedviewactor=GLRenderer->mViewActor;
savedviewarea=in_area;
savedshowviewer = r_showviewer;
savedviewpath[0] = ViewPath[0];
savedviewpath[1] = ViewPath[1];
savedvisibility = camera ? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0);
PrevPortal = GLRenderer->mCurrentPortal;
PrevClipPortal = GLRenderer->mClipPortal;
@ -375,7 +376,7 @@ void GLPortal::End(bool usestencil)
ViewAngle = savedAngle;
GLRenderer->mViewActor=savedviewactor;
in_area=savedviewarea;
r_showviewer = savedshowviewer;
if (camera != nullptr) camera->renderflags = (camera->renderflags & ~RF_INVISIBLE) | savedvisibility;
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
{
@ -432,7 +433,7 @@ void GLPortal::End(bool usestencil)
ViewAngle = savedAngle;
GLRenderer->mViewActor=savedviewactor;
in_area=savedviewarea;
r_showviewer = savedshowviewer;
if (camera != nullptr) camera->renderflags |= savedvisibility;
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
// This draws a valid z-buffer into the stencil's contents to ensure it
@ -665,7 +666,7 @@ void GLSkyboxPortal::DrawContents()
SaveMapSection();
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
GLRenderer->DrawScene();
GLRenderer->DrawScene(DM_PORTAL);
portal->mFlags &= ~PORTSF_INSKYBOX;
inskybox = false;
gl_RenderState.SetDepthClamp(oldclamp);
@ -755,7 +756,7 @@ void GLSectorStackPortal::DrawContents()
SaveMapSection();
SetupCoverage();
ClearClipper();
GLRenderer->DrawScene();
GLRenderer->DrawScene(DM_PORTAL);
RestoreMapSection();
if (origin->plane != -1) instack[origin->plane]--;
@ -791,14 +792,13 @@ void GLPlaneMirrorPortal::DrawContents()
ViewPos.Z = 2 * planez - ViewPos.Z;
GLRenderer->mViewActor = NULL;
PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;
r_showviewer = true;
PlaneMirrorFlag++;
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
ClearClipper();
gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0? -1.f : 1.f);
GLRenderer->DrawScene();
GLRenderer->DrawScene(DM_PORTAL);
gl_RenderState.SetClipHeight(0.f, 0.f);
PlaneMirrorFlag--;
PlaneMirrorMode=old_pm;
@ -955,7 +955,6 @@ void GLMirrorPortal::DrawContents()
ViewAngle = linedef->Delta().Angle() * 2. - StartAngle;
GLRenderer->mViewActor = NULL;
r_showviewer = true;
MirrorFlag++;
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
@ -971,7 +970,7 @@ void GLMirrorPortal::DrawContents()
gl_RenderState.SetClipLine(linedef);
gl_RenderState.EnableClipLine(true);
GLRenderer->DrawScene();
GLRenderer->DrawScene(DM_PORTAL);
gl_RenderState.EnableClipLine(false);
MirrorFlag--;
@ -1009,7 +1008,7 @@ void GLLineToLinePortal::DrawContents()
P_TranslatePortalZ(origin, ViewPos.Z);
P_TranslatePortalXY(origin, ViewPath[0].X, ViewPath[0].Y);
P_TranslatePortalXY(origin, ViewPath[1].X, ViewPath[1].Y);
if (!r_showviewer)
if (!r_showviewer && camera != nullptr && P_PointOnLineSidePrecise(ViewPath[0], glport->lines[0]->mDestination) != P_PointOnLineSidePrecise(ViewPath[1], glport->lines[0]->mDestination))
{
double distp = (ViewPath[0] - ViewPath[1]).Length();
if (distp > EQUAL_EPSILON)
@ -1017,9 +1016,9 @@ void GLLineToLinePortal::DrawContents()
double dist1 = (ViewPos - ViewPath[0]).Length();
double dist2 = (ViewPos - ViewPath[1]).Length();
if (dist1 + dist2 > distp + 1)
if (dist1 + dist2 < distp + 1)
{
r_showviewer = true;
camera->renderflags |= RF_INVISIBLE;
}
}
}
@ -1044,7 +1043,7 @@ void GLLineToLinePortal::DrawContents()
ClearClipper();
gl_RenderState.SetClipLine(glport->lines[0]->mDestination);
gl_RenderState.EnableClipLine(true);
GLRenderer->DrawScene();
GLRenderer->DrawScene(DM_PORTAL);
gl_RenderState.EnableClipLine(false);
RestoreMapSection();
}

View file

@ -105,7 +105,7 @@ private:
DAngle savedAngle;
AActor * savedviewactor;
area_t savedviewarea;
bool savedshowviewer;
ActorRenderFlags savedvisibility;
DVector3 savedviewpath[2];
GLPortal *PrevPortal;
GLPortal *PrevClipPortal;

View file

@ -98,6 +98,7 @@ EXTERN_CVAR (Bool, r_deathcamera)
extern int viewpitch;
extern bool NoInterpolateView;
extern bool r_showviewer;
DWORD gl_fixedcolormap;
area_t in_area;
@ -501,16 +502,29 @@ void FGLRenderer::RenderTranslucent()
//-----------------------------------------------------------------------------
EXTERN_CVAR(Bool, gl_draw_sync)
void FGLRenderer::DrawScene(bool toscreen)
void FGLRenderer::DrawScene(int drawmode)
{
static int recursion=0;
CreateScene();
if (camera != nullptr)
{
ActorRenderFlags savedflags = camera->renderflags;
if (drawmode != DM_PORTAL && !r_showviewer)
{
camera->renderflags |= RF_INVISIBLE;
}
CreateScene();
camera->renderflags = savedflags;
}
else
{
CreateScene();
}
GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place.
// Up to this point in the main draw call no rendering is performed so we can wait
// with swapping the render buffer until now.
if (!gl_draw_sync && toscreen)
if (!gl_draw_sync && drawmode == DM_MAINVIEW)
{
All.Unclock();
static_cast<OpenGLFrameBuffer*>(screen)->Swap();
@ -734,7 +748,7 @@ void FGLRenderer::ProcessScene(bool toscreen)
int mapsection = R_PointInSubsector(ViewPos)->mapsection;
memset(&currentmapsection[0], 0, currentmapsection.Size());
currentmapsection[mapsection>>3] |= 1 << (mapsection & 7);
DrawScene(toscreen);
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
FDrawInfo::EndDrawInfo();
}

View file

@ -81,7 +81,6 @@ CUSTOM_CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE)
if (self < 0 || self > 7) self = 0;
}
extern bool r_showviewer;
EXTERN_CVAR (Float, transsouls)
extern TArray<spritedef_t> sprites;
@ -552,8 +551,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
{
sector_t rs;
sector_t * rendersector;
// don't draw the thing that's used as camera (for viewshifts during quakes!)
if (thing == GLRenderer->mViewActor || (thing == players[consoleplayer].camera && !r_showviewer)) return;
// Don't waste time projecting sprites that are definitely not visible.
if (thing == NULL || thing->sprite == 0 || !thing->IsVisibleToPlayer())
@ -561,6 +558,12 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
return;
}
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
{
if (!(thing->flags & MF_STEALTH) || !gl_fixedcolormap || !gl_enhanced_nightvision || thing == camera)
return;
}
int spritenum = thing->sprite;
DVector2 sprscale = thing->Scale;
if (thing->player != NULL)
@ -568,12 +571,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
P_CheckPlayerSprite(thing, spritenum, sprscale);
}
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
{
if (!(thing->flags & MF_STEALTH) || !gl_fixedcolormap || !gl_enhanced_nightvision)
return;
}
// If this thing is in a map section that's not in view it can't possibly be visible
if (!thruportal && !(currentmapsection[thing->subsector->mapsection >> 3] & (1 << (thing->subsector->mapsection & 7)))) return;