mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Fix HWR_SplitWall and sloped midtextures
- Fix bugs with HWR_SplitWall and sloped midtextures - Clean up HWR_ProcessSeg and HWR_SplitWall - Determine if the midtexture is visible earlier - Ensure opaque midtextures always use PF_Masked
This commit is contained in:
parent
fb038a8387
commit
4558cc1c1f
1 changed files with 275 additions and 297 deletions
|
@ -840,15 +840,10 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
|
|||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// HWR_SplitWall
|
||||
//
|
||||
// SoM: split up and light walls according to the lightlist.
|
||||
// This may also include leaving out parts of the wall that can't be seen
|
||||
static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags)
|
||||
{
|
||||
/* SoM: split up and light walls according to the
|
||||
lightlist. This may also include leaving out parts
|
||||
of the wall that can't be seen */
|
||||
|
||||
float realtop, realbot, top, bot;
|
||||
float pegt, pegb, pegmul;
|
||||
float height = 0.0f, bheight = 0.0f;
|
||||
|
@ -857,38 +852,51 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
float endpegt, endpegb, endpegmul;
|
||||
float endheight = 0.0f, endbheight = 0.0f;
|
||||
|
||||
// compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly
|
||||
// use this as a temp var to store P_GetSlopeZAt's return value each time
|
||||
fixed_t temp;
|
||||
float diff;
|
||||
|
||||
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
|
||||
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
|
||||
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
|
||||
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
|
||||
fixed_t v1x = FloatToFixed(wallVerts[0].x);
|
||||
fixed_t v1y = FloatToFixed(wallVerts[0].z);
|
||||
fixed_t v2x = FloatToFixed(wallVerts[1].x);
|
||||
fixed_t v2y = FloatToFixed(wallVerts[1].z);
|
||||
|
||||
INT32 solid, i;
|
||||
lightlist_t * list = sector->lightlist;
|
||||
const UINT8 alpha = Surf->PolyColor.s.alpha;
|
||||
FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y);
|
||||
extracolormap_t *colormap = NULL;
|
||||
|
||||
realtop = top = wallVerts[3].y;
|
||||
realbot = bot = wallVerts[0].y;
|
||||
diff = top - bot;
|
||||
|
||||
pegt = wallVerts[3].t;
|
||||
pegb = wallVerts[0].t;
|
||||
pegmul = (pegb - pegt) / (top - bot);
|
||||
|
||||
// Lactozilla: If both heights of a side lay on the same position, then this wall is a triangle.
|
||||
// To avoid division by zero, which would result in a NaN, we check if the vertical difference
|
||||
// between the two vertices is not zero.
|
||||
if (fpclassify(diff) == FP_ZERO)
|
||||
pegmul = 0.0;
|
||||
else
|
||||
pegmul = (pegb - pegt) / diff;
|
||||
|
||||
endrealtop = endtop = wallVerts[2].y;
|
||||
endrealbot = endbot = wallVerts[1].y;
|
||||
diff = endtop - endbot;
|
||||
|
||||
endpegt = wallVerts[2].t;
|
||||
endpegb = wallVerts[1].t;
|
||||
endpegmul = (endpegb - endpegt) / (endtop - endbot);
|
||||
|
||||
for (i = 0; i < sector->numlights; i++)
|
||||
if (fpclassify(diff) == FP_ZERO)
|
||||
endpegmul = 0.0;
|
||||
else
|
||||
endpegmul = (endpegb - endpegt) / diff;
|
||||
|
||||
for (INT32 i = 0; i < sector->numlights; i++)
|
||||
{
|
||||
if (endtop < endrealbot && top < realbot)
|
||||
return;
|
||||
|
||||
lightlist_t *list = sector->lightlist;
|
||||
|
||||
if (!(list[i].flags & FOF_NOSHADE))
|
||||
{
|
||||
if (pfloor && (pfloor->fofflags & FOF_FOG))
|
||||
|
@ -903,7 +911,7 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
}
|
||||
}
|
||||
|
||||
solid = false;
|
||||
boolean solid = false;
|
||||
|
||||
if ((sector->lightlist[i].flags & FOF_CUTSOLIDS) && !(cutflag & FOF_EXTRA))
|
||||
solid = true;
|
||||
|
@ -920,16 +928,12 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
else
|
||||
solid = false;
|
||||
|
||||
temp = P_GetLightZAt(&list[i], v1x, v1y);
|
||||
height = FIXED_TO_FLOAT(temp);
|
||||
temp = P_GetLightZAt(&list[i], v2x, v2y);
|
||||
endheight = FIXED_TO_FLOAT(temp);
|
||||
height = FixedToFloat(P_GetLightZAt(&list[i], v1x, v1y));
|
||||
endheight = FixedToFloat(P_GetLightZAt(&list[i], v2x, v2y));
|
||||
if (solid)
|
||||
{
|
||||
temp = P_GetFFloorBottomZAt(list[i].caster, v1x, v1y);
|
||||
bheight = FIXED_TO_FLOAT(temp);
|
||||
temp = P_GetFFloorBottomZAt(list[i].caster, v2x, v2y);
|
||||
endbheight = FIXED_TO_FLOAT(temp);
|
||||
bheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v1x, v1y));
|
||||
endbheight = FixedToFloat(P_GetFFloorBottomZAt(list[i].caster, v2x, v2y));
|
||||
}
|
||||
|
||||
if (endheight >= endtop && height >= top)
|
||||
|
@ -942,10 +946,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
|
||||
if (i + 1 < sector->numlights)
|
||||
{
|
||||
temp = P_GetLightZAt(&list[i+1], v1x, v1y);
|
||||
bheight = FIXED_TO_FLOAT(temp);
|
||||
temp = P_GetLightZAt(&list[i+1], v2x, v2y);
|
||||
endbheight = FIXED_TO_FLOAT(temp);
|
||||
bheight = FixedToFloat(P_GetLightZAt(&list[i+1], v1x, v1y));
|
||||
endbheight = FixedToFloat(P_GetLightZAt(&list[i+1], v2x, v2y));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -953,19 +955,10 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
|
|||
endbheight = endrealbot;
|
||||
}
|
||||
|
||||
if (endbheight >= endtop && bheight >= top)
|
||||
continue;
|
||||
|
||||
//Found a break;
|
||||
bot = bheight;
|
||||
|
||||
if (bot < realbot)
|
||||
bot = realbot;
|
||||
|
||||
endbot = endbheight;
|
||||
|
||||
if (endbot < endrealbot)
|
||||
endbot = endrealbot;
|
||||
// Found a break
|
||||
// The heights are clamped to ensure the polygon doesn't cross itself.
|
||||
bot = min(max(bheight, realbot), top);
|
||||
endbot = min(max(endbheight, endrealbot), endtop);
|
||||
|
||||
Surf->PolyColor.s.alpha = alpha;
|
||||
|
||||
|
@ -1034,6 +1027,42 @@ static void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf)
|
|||
// PF_Occlude is set in HWR_ProjectWall to draw into the depth buffer
|
||||
}
|
||||
|
||||
// Returns true if the midtexture is visible, and false if... it isn't...
|
||||
static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
|
||||
{
|
||||
FUINT blendmode = PF_Masked;
|
||||
|
||||
pSurf->PolyColor.s.alpha = 0xFF;
|
||||
|
||||
if (!gl_curline->polyseg)
|
||||
{
|
||||
if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
|
||||
{
|
||||
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
|
||||
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
|
||||
else
|
||||
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
|
||||
}
|
||||
else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
|
||||
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
|
||||
}
|
||||
else if (gl_curline->polyseg->translucency > 0)
|
||||
{
|
||||
// Polyobject translucency is done differently
|
||||
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
|
||||
return false;
|
||||
else
|
||||
blendmode = HWR_TranstableToAlpha(gl_curline->polyseg->translucency, pSurf);
|
||||
}
|
||||
|
||||
if (blendmode != PF_Masked && pSurf->PolyColor.s.alpha == 0x00)
|
||||
return false;
|
||||
|
||||
pSurf->PolyFlags = blendmode;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// HWR_ProcessSeg
|
||||
// A portion or all of a wall segment will be drawn, from startfrac to endfrac,
|
||||
|
@ -1052,16 +1081,9 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
fixed_t worldhighslope = 0, worldlowslope = 0;
|
||||
fixed_t v1x, v1y, v2x, v2y;
|
||||
|
||||
GLMapTexture_t *grTex = NULL;
|
||||
float cliplow = 0.0f, cliphigh = 0.0f;
|
||||
INT32 gl_midtexture;
|
||||
fixed_t h, l; // 3D sides and 2s middle textures
|
||||
fixed_t hS, lS;
|
||||
|
||||
FUINT lightnum = 0; // shut up compiler
|
||||
extracolormap_t *colormap;
|
||||
FSurfaceInfo Surf;
|
||||
|
||||
gl_sidedef = gl_curline->sidedef;
|
||||
gl_linedef = gl_curline->linedef;
|
||||
|
||||
|
@ -1095,22 +1117,25 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
wallVerts[2].z = wallVerts[1].z = ve.y;
|
||||
|
||||
// x offset the texture
|
||||
{
|
||||
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset;
|
||||
cliplow = (float)texturehpeg;
|
||||
cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
|
||||
}
|
||||
fixed_t texturehpeg = gl_sidedef->textureoffset + gl_curline->offset;
|
||||
float cliplow = (float)texturehpeg;
|
||||
float cliphigh = (float)(texturehpeg + (gl_curline->flength*FRACUNIT));
|
||||
|
||||
lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
colormap = gl_frontsector->extra_colormap;
|
||||
FUINT lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y);
|
||||
extracolormap_t *colormap = gl_frontsector->extra_colormap;
|
||||
|
||||
if (gl_frontsector)
|
||||
Surf.PolyColor.s.alpha = 255;
|
||||
FSurfaceInfo Surf;
|
||||
Surf.PolyColor.s.alpha = 255;
|
||||
|
||||
INT32 gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
|
||||
GLMapTexture_t *grTex = NULL;
|
||||
|
||||
// two sided line
|
||||
if (gl_backsector)
|
||||
{
|
||||
INT32 gl_toptexture = 0, gl_bottomtexture = 0;
|
||||
// two sided line
|
||||
fixed_t texturevpeg;
|
||||
|
||||
boolean bothceilingssky = false; // turned on if both back and front ceilings are sky
|
||||
boolean bothfloorssky = false; // likewise, but for floors
|
||||
|
||||
|
@ -1140,51 +1165,47 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// check TOP TEXTURE
|
||||
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
|
||||
{
|
||||
// PEGGING
|
||||
if (gl_linedef->flags & ML_DONTPEGTOP)
|
||||
texturevpeg = 0;
|
||||
else if (gl_linedef->flags & ML_SKEWTD)
|
||||
texturevpeg = worldhigh + textureheight[gl_toptexture] - worldtop;
|
||||
else
|
||||
texturevpeg = gl_backsector->ceilingheight + textureheight[gl_toptexture] - gl_frontsector->ceilingheight;
|
||||
|
||||
texturevpeg += gl_sidedef->rowoffset;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpeg %= textureheight[gl_toptexture];
|
||||
|
||||
grTex = HWR_GetTexture(gl_toptexture);
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
{
|
||||
fixed_t texturevpegtop; // top
|
||||
|
||||
grTex = HWR_GetTexture(gl_toptexture);
|
||||
|
||||
// PEGGING
|
||||
if (gl_linedef->flags & ML_DONTPEGTOP)
|
||||
texturevpegtop = 0;
|
||||
else if (gl_linedef->flags & ML_SKEWTD)
|
||||
texturevpegtop = worldhigh + textureheight[gl_sidedef->toptexture] - worldtop;
|
||||
else
|
||||
texturevpegtop = gl_backsector->ceilingheight + textureheight[gl_sidedef->toptexture] - gl_frontsector->ceilingheight;
|
||||
|
||||
texturevpegtop += gl_sidedef->rowoffset;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpegtop %= (textures[gl_toptexture]->height)<<FRACBITS;
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpegtop * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
{
|
||||
// Unskewed
|
||||
wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY;
|
||||
}
|
||||
else if (gl_linedef->flags & ML_DONTPEGTOP)
|
||||
{
|
||||
// Skewed by top
|
||||
wallVerts[0].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpegtop + worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by bottom
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegtop + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
// Unskewed
|
||||
wallVerts[3].t -= (worldtop - gl_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[2].t -= (worldtopslope - gl_frontsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[0].t -= (worldhigh - gl_backsector->ceilingheight) * grTex->scaleY;
|
||||
wallVerts[1].t -= (worldhighslope - gl_backsector->ceilingheight) * grTex->scaleY;
|
||||
}
|
||||
else if (gl_linedef->flags & ML_DONTPEGTOP)
|
||||
{
|
||||
// Skewed by top
|
||||
wallVerts[0].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpeg + worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by bottom
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[3].t = wallVerts[0].t - (worldtop - worldhigh) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * grTex->scaleY;
|
||||
}
|
||||
|
||||
// set top/bottom coords
|
||||
|
@ -1202,55 +1223,48 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
|
||||
// check BOTTOM TEXTURE
|
||||
if ((
|
||||
worldlowslope > worldbottomslope ||
|
||||
worldlow > worldbottom) && gl_bottomtexture) //only if VISIBLE!!!
|
||||
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
|
||||
{
|
||||
// PEGGING
|
||||
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
|
||||
texturevpeg = 0;
|
||||
else if (gl_linedef->flags & ML_SKEWTD)
|
||||
texturevpeg = worldbottom - worldlow;
|
||||
else
|
||||
texturevpeg = gl_frontsector->floorheight - gl_backsector->floorheight;
|
||||
|
||||
texturevpeg += gl_sidedef->rowoffset;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpeg %= textureheight[gl_bottomtexture];
|
||||
|
||||
grTex = HWR_GetTexture(gl_bottomtexture);
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
{
|
||||
fixed_t texturevpegbottom = 0; // bottom
|
||||
|
||||
grTex = HWR_GetTexture(gl_bottomtexture);
|
||||
|
||||
// PEGGING
|
||||
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
|
||||
texturevpegbottom = 0;
|
||||
else if (gl_linedef->flags & ML_SKEWTD)
|
||||
texturevpegbottom = worldbottom - worldlow;
|
||||
else
|
||||
texturevpegbottom = gl_frontsector->floorheight - gl_backsector->floorheight;
|
||||
|
||||
texturevpegbottom += gl_sidedef->rowoffset;
|
||||
|
||||
// This is so that it doesn't overflow and screw up the wall, it doesn't need to go higher than the texture's height anyway
|
||||
texturevpegbottom %= (textures[gl_bottomtexture]->height)<<FRACBITS;
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpegbottom * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + gl_backsector->floorheight - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// Adjust t value for sloped walls
|
||||
if (!(gl_linedef->flags & ML_SKEWTD))
|
||||
{
|
||||
// Unskewed
|
||||
wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY;
|
||||
}
|
||||
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
// Skewed by bottom
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
|
||||
//wallVerts[3].t = wallVerts[0].t - (worldlow - worldbottom) * grTex->scaleY; // no need, [3] is already this
|
||||
wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by top
|
||||
wallVerts[0].t = (texturevpegbottom + worldlow - worldbottom) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpegbottom + worldlowslope - worldbottomslope) * grTex->scaleY;
|
||||
}
|
||||
// Unskewed
|
||||
wallVerts[0].t -= (worldbottom - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[1].t -= (worldbottomslope - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[3].t -= (worldlow - gl_backsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[2].t -= (worldlowslope - gl_backsector->floorheight) * grTex->scaleY;
|
||||
}
|
||||
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
// Skewed by bottom
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t - (worldlowslope - worldbottomslope) * grTex->scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skewed by top
|
||||
wallVerts[0].t = (texturevpeg + worldlow - worldbottom) * grTex->scaleY;
|
||||
wallVerts[1].t = (texturevpeg + worldlowslope - worldbottomslope) * grTex->scaleY;
|
||||
}
|
||||
|
||||
// set top/bottom coords
|
||||
|
@ -1267,13 +1281,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||
}
|
||||
|
||||
gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
|
||||
if (gl_midtexture)
|
||||
// Render midtexture if there's one. Determine if it's visible first, though
|
||||
if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf))
|
||||
{
|
||||
FBITFIELD blendmode;
|
||||
sector_t *front, *back;
|
||||
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
|
||||
fixed_t texturevpeg = 0;
|
||||
INT32 repeats;
|
||||
|
||||
if (gl_linedef->frontsector->heightsec != -1)
|
||||
|
@ -1302,57 +1313,77 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
else
|
||||
low = back->floorheight;
|
||||
|
||||
repeats = (high - low)/textureheight[gl_sidedef->midtexture];
|
||||
if ((high-low)%textureheight[gl_sidedef->midtexture])
|
||||
repeats = (high - low) / textureheight[gl_midtexture];
|
||||
if ((high - low) % textureheight[gl_midtexture])
|
||||
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
|
||||
}
|
||||
else
|
||||
repeats = 1;
|
||||
|
||||
// SoM: a little note: This code re-arranging will
|
||||
// fix the bug in Nimrod map02. popentop and popenbottom
|
||||
// SoM: a little note: popentop and popenbottom
|
||||
// record the limits the texture can be displayed in.
|
||||
// polytop and polybottom, are the ideal (i.e. unclipped)
|
||||
// heights of the polygon, and h & l, are the final (clipped)
|
||||
// poly coords.
|
||||
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
|
||||
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
|
||||
|
||||
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
|
||||
// you must use the linedef's backsector to be correct
|
||||
// From CB
|
||||
if (gl_curline->polyseg)
|
||||
{
|
||||
popentop = back->ceilingheight;
|
||||
popenbottom = back->floorheight;
|
||||
popentop = popentopslope = back->ceilingheight;
|
||||
popenbottom = popenbottomslope = back->floorheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
popentop = min(worldtop, worldhigh);
|
||||
popenbottom = max(worldbottom, worldlow);
|
||||
popentopslope = min(worldtopslope, worldhighslope);
|
||||
popenbottomslope = max(worldbottomslope, worldlowslope);
|
||||
}
|
||||
|
||||
// Find the wall's coordinates
|
||||
fixed_t midtexheight = textureheight[gl_midtexture] * repeats;
|
||||
|
||||
// Texture is not skewed
|
||||
if (gl_linedef->flags & ML_NOSKEW)
|
||||
{
|
||||
// Peg it to the floor
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = max(front->floorheight, back->floorheight) + gl_sidedef->rowoffset;
|
||||
polytop = polybottom + textureheight[gl_midtexture]*repeats;
|
||||
polytop = polybottom + midtexheight;
|
||||
}
|
||||
// Peg it to the ceiling
|
||||
else
|
||||
{
|
||||
polytop = min(front->ceilingheight, back->ceilingheight) + gl_sidedef->rowoffset;
|
||||
polybottom = polytop - textureheight[gl_midtexture]*repeats;
|
||||
polybottom = polytop - midtexheight;
|
||||
}
|
||||
|
||||
// The right side's coordinates are the the same as the left side
|
||||
polytopslope = polytop;
|
||||
polybottomslope = polybottom;
|
||||
}
|
||||
// Skew the texture, but peg it to the floor
|
||||
else if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
polybottom = popenbottom + gl_sidedef->rowoffset;
|
||||
polytop = polybottom + textureheight[gl_midtexture]*repeats;
|
||||
polytop = polybottom + midtexheight;
|
||||
polybottomslope = popenbottomslope + gl_sidedef->rowoffset;
|
||||
polytopslope = polybottomslope + midtexheight;
|
||||
}
|
||||
// Skew it according to the ceiling's slope
|
||||
else
|
||||
{
|
||||
polytop = popentop + gl_sidedef->rowoffset;
|
||||
polybottom = polytop - textureheight[gl_midtexture]*repeats;
|
||||
polybottom = polytop - midtexheight;
|
||||
polytopslope = popentopslope + gl_sidedef->rowoffset;
|
||||
polybottomslope = polytopslope - midtexheight;
|
||||
}
|
||||
|
||||
// CB
|
||||
// NOTE: With polyobjects, whenever you need to check the properties of the polyobject sector it belongs to,
|
||||
// you must use the linedef's backsector to be correct
|
||||
|
@ -1360,105 +1391,59 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
{
|
||||
lowcut = polybottom;
|
||||
highcut = polytop;
|
||||
lowcutslope = polybottomslope;
|
||||
highcutslope = polytopslope;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The cut-off values of a linedef can always be constant, since every line has an absoulute front and or back sector
|
||||
lowcut = popenbottom;
|
||||
highcut = popentop;
|
||||
lowcutslope = popenbottomslope;
|
||||
highcutslope = popentopslope;
|
||||
}
|
||||
|
||||
h = min(highcut, polytop);
|
||||
l = max(polybottom, lowcut);
|
||||
hS = min(highcutslope, polytopslope);
|
||||
lS = max(polybottomslope, lowcutslope);
|
||||
|
||||
// PEGGING
|
||||
fixed_t texturevpegslope;
|
||||
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
// PEGGING
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom;
|
||||
else
|
||||
texturevpeg = polytop - h;
|
||||
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
texturevpeg = midtexheight - h + polybottom;
|
||||
texturevpegslope = midtexheight - hS + polybottomslope;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturevpeg = polytop - h;
|
||||
texturevpegslope = polytopslope - hS;
|
||||
}
|
||||
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
|
||||
// Left side
|
||||
wallVerts[3].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = (h - l + texturevpeg) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
|
||||
// Right side
|
||||
wallVerts[2].t = texturevpegslope * grTex->scaleY;
|
||||
wallVerts[1].t = (hS - lS + texturevpegslope) * grTex->scaleY;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// set top/bottom coords
|
||||
// Take the texture peg into account, rather than changing the offsets past
|
||||
// where the polygon might not be.
|
||||
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(h);
|
||||
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(l);
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(h);
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(l);
|
||||
wallVerts[2].y = FIXED_TO_FLOAT(hS);
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(lS);
|
||||
|
||||
// Correct to account for slopes
|
||||
{
|
||||
fixed_t midtextureslant;
|
||||
|
||||
if (gl_linedef->flags & ML_NOSKEW)
|
||||
midtextureslant = 0;
|
||||
else if (gl_linedef->flags & ML_MIDPEG)
|
||||
midtextureslant = worldlow < worldbottom
|
||||
? worldbottomslope-worldbottom
|
||||
: worldlowslope-worldlow;
|
||||
else
|
||||
midtextureslant = worldtop < worldhigh
|
||||
? worldtopslope-worldtop
|
||||
: worldhighslope-worldhigh;
|
||||
|
||||
polytop += midtextureslant;
|
||||
polybottom += midtextureslant;
|
||||
|
||||
highcut += worldtop < worldhigh
|
||||
? worldtopslope-worldtop
|
||||
: worldhighslope-worldhigh;
|
||||
lowcut += worldlow < worldbottom
|
||||
? worldbottomslope-worldbottom
|
||||
: worldlowslope-worldlow;
|
||||
|
||||
// Texture stuff
|
||||
h = min(highcut, polytop);
|
||||
l = max(polybottom, lowcut);
|
||||
|
||||
{
|
||||
// PEGGING
|
||||
if (gl_linedef->flags & ML_MIDPEG)
|
||||
texturevpeg = textureheight[gl_sidedef->midtexture]*repeats - h + polybottom;
|
||||
else
|
||||
texturevpeg = polytop - h;
|
||||
wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[1].t = (h - l + texturevpeg) * grTex->scaleY;
|
||||
}
|
||||
|
||||
wallVerts[2].y = FIXED_TO_FLOAT(h);
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(l);
|
||||
}
|
||||
|
||||
// set alpha for transparent walls
|
||||
// ooops ! this do not work at all because render order we should render it in backtofront order
|
||||
if (gl_linedef->blendmode && gl_linedef->blendmode != AST_FOG)
|
||||
{
|
||||
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
|
||||
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
|
||||
else
|
||||
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
|
||||
}
|
||||
else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
|
||||
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
|
||||
else
|
||||
blendmode = PF_Masked;
|
||||
|
||||
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
|
||||
{
|
||||
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn
|
||||
{
|
||||
Surf.PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode
|
||||
blendmode = PF_Masked;
|
||||
}
|
||||
else
|
||||
blendmode = HWR_TranstableToAlpha(gl_curline->polyseg->translucency, &Surf);
|
||||
}
|
||||
// TODO: Actually use the surface's flags so that I don't have to do this
|
||||
FUINT blendmode = Surf.PolyFlags;
|
||||
|
||||
// Render midtextures on two-sided lines with a z-buffer offset.
|
||||
// This will cause the midtexture appear on top, if a FOF overlaps with it.
|
||||
|
@ -1481,66 +1466,60 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
// No longer so much a mess as before!
|
||||
if (!gl_curline->polyseg) // Don't do it for polyobjects
|
||||
{
|
||||
if (gl_frontsector->ceilingpic == skyflatnum)
|
||||
if (gl_frontsector->ceilingpic == skyflatnum
|
||||
&& gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky
|
||||
{
|
||||
if (gl_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky
|
||||
{
|
||||
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
|
||||
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||
}
|
||||
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space
|
||||
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
|
||||
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
|
||||
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||
}
|
||||
|
||||
if (gl_frontsector->floorpic == skyflatnum)
|
||||
if (gl_frontsector->floorpic == skyflatnum
|
||||
&& gl_backsector->floorpic != skyflatnum) // same thing here
|
||||
{
|
||||
if (gl_backsector->floorpic != skyflatnum) // don't cull if back sector is also sky
|
||||
{
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
|
||||
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space
|
||||
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||
}
|
||||
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
|
||||
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space
|
||||
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Single sided line... Deal only with the middletexture (if one exists)
|
||||
gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
|
||||
if (gl_midtexture && gl_linedef->special != 41) // (Ignore horizon line for OGL)
|
||||
if (gl_midtexture && gl_linedef->special != HORIZONSPECIAL) // (Ignore horizon line for OGL)
|
||||
{
|
||||
{
|
||||
fixed_t texturevpeg;
|
||||
// PEGGING
|
||||
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW))
|
||||
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset;
|
||||
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
|
||||
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset;
|
||||
else
|
||||
// top of texture at top
|
||||
texturevpeg = gl_sidedef->rowoffset;
|
||||
fixed_t texturevpeg;
|
||||
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
// PEGGING
|
||||
if ((gl_linedef->flags & (ML_DONTPEGBOTTOM|ML_NOSKEW)) == (ML_DONTPEGBOTTOM|ML_NOSKEW))
|
||||
texturevpeg = gl_frontsector->floorheight + textureheight[gl_sidedef->midtexture] - gl_frontsector->ceilingheight + gl_sidedef->rowoffset;
|
||||
else if (gl_linedef->flags & ML_DONTPEGBOTTOM)
|
||||
texturevpeg = worldbottom + textureheight[gl_sidedef->midtexture] - worldtop + gl_sidedef->rowoffset;
|
||||
else
|
||||
// top of texture at top
|
||||
texturevpeg = gl_sidedef->rowoffset;
|
||||
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
grTex = HWR_GetTexture(gl_midtexture);
|
||||
|
||||
// Texture correction for slopes
|
||||
if (gl_linedef->flags & ML_NOSKEW) {
|
||||
wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY;
|
||||
wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY;
|
||||
wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY;
|
||||
wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY;
|
||||
} else if (gl_linedef->flags & ML_DONTPEGBOTTOM) {
|
||||
wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY;
|
||||
} else {
|
||||
wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY;
|
||||
wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY;
|
||||
}
|
||||
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
|
||||
wallVerts[0].t = wallVerts[1].t = (texturevpeg + gl_frontsector->ceilingheight - gl_frontsector->floorheight) * grTex->scaleY;
|
||||
wallVerts[0].s = wallVerts[3].s = cliplow * grTex->scaleX;
|
||||
wallVerts[2].s = wallVerts[1].s = cliphigh * grTex->scaleX;
|
||||
|
||||
// Texture correction for slopes
|
||||
if (gl_linedef->flags & ML_NOSKEW) {
|
||||
wallVerts[3].t += (gl_frontsector->ceilingheight - worldtop) * grTex->scaleY;
|
||||
wallVerts[2].t += (gl_frontsector->ceilingheight - worldtopslope) * grTex->scaleY;
|
||||
wallVerts[0].t += (gl_frontsector->floorheight - worldbottom) * grTex->scaleY;
|
||||
wallVerts[1].t += (gl_frontsector->floorheight - worldbottomslope) * grTex->scaleY;
|
||||
} else if (gl_linedef->flags & ML_DONTPEGBOTTOM) {
|
||||
wallVerts[3].t = wallVerts[0].t + (worldbottom-worldtop) * grTex->scaleY;
|
||||
wallVerts[2].t = wallVerts[1].t + (worldbottomslope-worldtopslope) * grTex->scaleY;
|
||||
} else {
|
||||
wallVerts[0].t = wallVerts[3].t - (worldbottom-worldtop) * grTex->scaleY;
|
||||
wallVerts[1].t = wallVerts[2].t - (worldbottomslope-worldtopslope) * grTex->scaleY;
|
||||
}
|
||||
|
||||
//Set textures properly on single sided walls that are sloped
|
||||
|
@ -1580,9 +1559,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//Hurdler: 3d-floors test
|
||||
if (gl_frontsector && gl_backsector && !Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags) && (gl_backsector->ffloors || gl_frontsector->ffloors))
|
||||
if (gl_backsector && !Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags) && (gl_backsector->ffloors || gl_frontsector->ffloors))
|
||||
{
|
||||
ffloor_t * rover;
|
||||
fixed_t highcut = 0, lowcut = 0;
|
||||
|
|
Loading…
Reference in a new issue