mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-12 07:34:50 +00:00
- 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:
parent
849ee50689
commit
7b99c883e1
5 changed files with 45 additions and 29 deletions
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ private:
|
|||
DAngle savedAngle;
|
||||
AActor * savedviewactor;
|
||||
area_t savedviewarea;
|
||||
bool savedshowviewer;
|
||||
ActorRenderFlags savedvisibility;
|
||||
DVector3 savedviewpath[2];
|
||||
GLPortal *PrevPortal;
|
||||
GLPortal *PrevClipPortal;
|
||||
|
|
|
@ -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(¤tmapsection[0], 0, currentmapsection.Size());
|
||||
currentmapsection[mapsection>>3] |= 1 << (mapsection & 7);
|
||||
DrawScene(toscreen);
|
||||
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
|
||||
FDrawInfo::EndDrawInfo();
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue