mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-27 04:41:23 +00:00
Merge branch 'opengl_match_software_wallclip' into 'master'
OpenGL: Try and Match Software Wallclipping Better See merge request KartKrew/Kart-Public!150
This commit is contained in:
commit
e276faf819
1 changed files with 183 additions and 136 deletions
|
@ -1319,7 +1319,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
|
|||
|
||||
// HWR_DrawSkyWalls
|
||||
// Draw walls into the depth buffer so that anything behind is culled properly
|
||||
static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top)
|
||||
static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf)
|
||||
{
|
||||
HWD.pfnSetTexture(NULL);
|
||||
// no texture
|
||||
|
@ -1327,9 +1327,6 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b
|
|||
wallVerts[0].t = wallVerts[1].t = 0;
|
||||
wallVerts[0].s = wallVerts[3].s = 0;
|
||||
wallVerts[2].s = wallVerts[1].s = 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_Clip|PF_NoTexture, 255, NULL);
|
||||
// PF_Invisible so it's not drawn into the colour buffer
|
||||
// PF_NoTexture for no texture
|
||||
|
@ -1462,6 +1459,111 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
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)
|
||||
#ifdef ESLOPE
|
||||
&& (worldhighslope <= worldtopslope)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#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)
|
||||
#ifdef ESLOPE
|
||||
&& (worldlowslope >= worldbottomslope)
|
||||
#endif
|
||||
&& !(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 &&
|
||||
|
@ -1914,85 +2016,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
Surf.FlatColor.rgba = 0xffffffff;
|
||||
}*/
|
||||
}
|
||||
|
||||
// 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
|
||||
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2060,13 +2083,52 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
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
|
||||
HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX);
|
||||
{
|
||||
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)
|
||||
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom);
|
||||
{
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2381,7 +2443,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac)
|
|||
// e6y: Check whether the player can look beyond this line
|
||||
//
|
||||
#ifdef NEWCLIP
|
||||
boolean checkforemptylines = true;
|
||||
static boolean checkforemptylines = true;
|
||||
// Don't modify anything here, just check
|
||||
// Kalaron: Modified for sloped linedefs
|
||||
static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector)
|
||||
|
@ -2421,55 +2483,38 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
|
|||
backc1 = backc2 = abacksector->ceilingheight;
|
||||
}
|
||||
|
||||
// now check for closed sectors!
|
||||
if (backc1 <= frontf1 && backc2 <= frontf2)
|
||||
if (viewsector != abacksector && viewsector != afrontsector)
|
||||
{
|
||||
boolean mydoorclosed = false; // My door? Closed!? (doorclosed is actually otherwise unused in openGL)
|
||||
|
||||
// If the sector behind the line blocks all kinds of view past it
|
||||
// (back ceiling is lower than close floor, or back floor is higher than close ceiling)
|
||||
if ((backc1 <= frontf1 && backc2 <= frontf2)
|
||||
|| (backf1 >= frontc1 && backf2 >= frontc2))
|
||||
{
|
||||
checkforemptylines = false;
|
||||
if (!seg->sidedef->toptexture)
|
||||
return false;
|
||||
|
||||
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (backf1 >= frontc1 && backf2 >= frontc2)
|
||||
// The door is closed if:
|
||||
// backsector is 0 height or less and
|
||||
// back ceiling is higher than close ceiling or we need to render a top texture and
|
||||
// back floor is lower than close floor or we need to render a bottom texture and
|
||||
// neither front or back sectors are using the sky ceiling
|
||||
mydoorclosed = (backc1 <= backf1 && backc2 <= backf2
|
||||
&& ((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture)
|
||||
&& ((backf1 <= frontf1 && backf2 >= frontf2) || seg->sidedef->bottomtexture)
|
||||
&& (abacksector->ceilingpic != skyflatnum || afrontsector->ceilingpic != skyflatnum));
|
||||
|
||||
if (mydoorclosed)
|
||||
{
|
||||
checkforemptylines = false;
|
||||
if (!seg->sidedef->bottomtexture)
|
||||
return false;
|
||||
|
||||
// properly render skies (consider door "open" if both floors are sky):
|
||||
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (backc1 <= backf1 && backc2 <= backf2)
|
||||
{
|
||||
checkforemptylines = false;
|
||||
// preserve a kind of transparent door/lift special effect:
|
||||
if (backc1 < frontc1 || backc2 < frontc2)
|
||||
{
|
||||
if (!seg->sidedef->toptexture)
|
||||
return false;
|
||||
}
|
||||
if (backf1 > frontf1 || backf2 > frontf2)
|
||||
{
|
||||
if (!seg->sidedef->bottomtexture)
|
||||
return false;
|
||||
}
|
||||
if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum)
|
||||
return false;
|
||||
|
||||
if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Window.
|
||||
// We know it's a window when the above isn't true and the back and front sectors don't match
|
||||
if (backc1 != frontc1 || backc2 != frontc2
|
||||
|| backf1 != frontf1 || backf2 != frontf2)
|
||||
{
|
||||
|
@ -2477,6 +2522,8 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
|
|||
return false;
|
||||
}
|
||||
|
||||
// In this case we just need to check whether there is actually a need to render any lines, so checkforempty lines
|
||||
// stays true
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
|
|
Loading…
Reference in a new issue