Fix skywalls in ogl. Similar to c3f6f263 in master.

This commit is contained in:
Hannu Hanhi 2020-04-19 18:19:16 +03:00
parent 8001bb4154
commit ff98d3b28a
2 changed files with 152 additions and 88 deletions

View file

@ -854,7 +854,7 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa
// HWR_DrawSkyWalls
// Draw walls into the depth buffer so that anything behind is culled properly
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top)
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf)
{
HWD.pfnSetTexture(NULL);
// no texture
@ -863,12 +863,6 @@ void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom,
wallVerts[0].s = wallVerts[3].s = 0;
wallVerts[2].s = wallVerts[1].s = 0;
if (bottom != 0 || top != 0)
{
// set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall
}
HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_NoTexture, 255, NULL);
// PF_Invisible so it's not drawn into the colour buffer
// PF_NoTexture for no texture
@ -976,6 +970,109 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
worldlow = gr_backsector->floorheight;
#endif
// Sky culling
if (!gr_curline->polyseg) // Don't do it for polyobjects
{
// Sky Ceilings
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX);
if (gr_frontsector->ceilingpic == skyflatnum)
{
if (gr_backsector->ceilingpic == skyflatnum)
{
// Both front and back sectors are sky, needs skywall from the frontsector's ceiling, but only if the
// backsector is lower
if ((worldhigh <= worldtop && worldhighslope <= worldtopslope)// Assuming ESLOPE is always on with my changes
&& (worldhigh != worldtop || worldhighslope != worldtopslope))
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
{
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldhigh);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else
{
// Only the frontsector is sky, just draw a skywall from the front ceiling
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else if (gr_backsector->ceilingpic == skyflatnum)
{
// Only the backsector is sky, just draw a skywall from the front ceiling
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
// Sky Floors
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN);
if (gr_frontsector->floorpic == skyflatnum)
{
if (gr_backsector->floorpic == skyflatnum)
{
// Both front and back sectors are sky, needs skywall from the backsector's floor, but only if the
// it's higher, also needs to check for bottomtexture as the floors don't usually move down
// when both sides are sky floors
if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope)
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
&& !(gr_sidedef->bottomtexture))
{
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else
{
// Only the backsector has sky, just draw a skywall from the back floor
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
else if ((gr_backsector->floorpic == skyflatnum) && !(gr_sidedef->bottomtexture))
{
// Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
// hack to allow height changes in outdoor areas
// This is what gets rid of the upper textures if there should be sky
if (gr_frontsector->ceilingpic == skyflatnum &&
@ -1421,86 +1518,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
// Isn't this just the most lovely mess
if (!gr_curline->polyseg) // Don't do it for polyobjects
{
if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum)
{
fixed_t depthwallheight;
if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn
depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
else
depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
{
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
{
if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX);
else
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX);
}
// behind sector is not a thok barrier
else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
// gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on
}
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
{
if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height
|| gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height
|| gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
}
else // neither sectors are thok barriers
{
if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower
|| gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
}
}
// And now for sky floors!
if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum)
{
fixed_t depthwallheight;
if (!gr_sidedef->bottomtexture)
depthwallheight = worldbottom > worldlow ? worldbottom : worldlow;
else
depthwallheight = worldbottom < worldlow ? worldbottom : worldlow;
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
{
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
{
if (!gr_sidedef->toptexture) // Only extend up if there's no texture
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh);
else
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh);
}
// behind sector is not a thok barrier
else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
{
if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height
|| gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height
|| gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
else // neither sectors are thok barriers
{
if (((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher
|| gr_backsector->floorpic != skyflatnum) // behind sector is not a sky
&& ABS(gr_backsector->floorheight - gr_frontsector->floorheight) > FRACUNIT*3/2) // don't draw sky walls for VERY thin differences, this makes for horrible looking slopes sometimes!
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
}
}
}
}
else
{
@ -1568,6 +1585,53 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
}
}
else
{
#ifdef ESLOPE
//Set textures properly on single sided walls that are sloped
wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
#else
// set top/bottom coords
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom);
#endif
// When there's no midtexture, draw a skywall to prevent rendering behind it
HWR_DrawSkyWall(wallVerts, &Surf);
}
// Single sided lines are simple for skywalls, just need to draw from the top or bottom of the sector if there's
// a sky flat
if (!gr_curline->polyseg)
{
if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector
{
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX);
#ifdef ESLOPE
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
#else
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
#endif
HWR_DrawSkyWall(wallVerts, &Surf);
}
if (gr_frontsector->floorpic == skyflatnum)
{
#ifdef ESLOPE
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
#else
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom);
#endif
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN);
HWR_DrawSkyWall(wallVerts, &Surf);
}
}
}

View file

@ -102,7 +102,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor);
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top);
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
void HWR_DrawSkyBackground(void);
#ifdef POLYOBJECTS