- Issues with negative texture scales in the OpenGL renderer
- Regression related to horizontal texture scaling
- Regression related to the rendering of vertically flipped textures
This commit is contained in:
Lactozilla 2024-01-22 21:16:46 -03:00
parent 7768e86cfb
commit a50e6bd769
3 changed files with 82 additions and 35 deletions

View file

@ -1167,10 +1167,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
{ {
grTex = HWR_GetTexture(gl_toptexture); grTex = HWR_GetTexture(gl_toptexture);
xscale = FixedToFloat(gl_sidedef->scalex_top); xscale = FixedToFloat(abs(gl_sidedef->scalex_top));
yscale = FixedToFloat(gl_sidedef->scaley_top); yscale = FixedToFloat(abs(gl_sidedef->scaley_top));
fixed_t texheight = FixedDiv(textureheight[gl_toptexture], gl_sidedef->scaley_top); fixed_t offsetx_top = gl_sidedef->offsetx_top;
float left = cliplow * xscale;
float right = cliphigh * xscale;
if (gl_sidedef->scalex_top < 0)
{
left = -left;
right = -right;
offsetx_top = -offsetx_top;
}
fixed_t texheight = FixedDiv(textureheight[gl_toptexture], abs(gl_sidedef->scaley_top));
// PEGGING // PEGGING
if (gl_linedef->flags & ML_DONTPEGTOP) if (gl_linedef->flags & ML_DONTPEGTOP)
@ -1182,15 +1193,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
texturevpeg *= yscale; texturevpeg *= yscale;
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top; if (gl_sidedef->scaley_top < 0)
texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_top;
else
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_top;
// 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 // 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 %= texheight; texturevpeg %= texheight;
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_frontsector->ceilingheight - gl_backsector->ceilingheight) * yscale) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = (left + offsetx_top) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_top) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = (right + offsetx_top) * grTex->scaleX;
// Adjust t value for sloped walls // Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD)) if (!(gl_linedef->flags & ML_SKEWTD))
@ -1215,6 +1229,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY; wallVerts[2].t = wallVerts[1].t - (worldtopslope - worldhighslope) * yscale * grTex->scaleY;
} }
if (gl_sidedef->scaley_top < 0)
{
wallVerts[0].t = -wallVerts[0].t;
wallVerts[1].t = -wallVerts[1].t;
wallVerts[2].t = -wallVerts[2].t;
wallVerts[3].t = -wallVerts[3].t;
}
// set top/bottom coords // set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(worldtop); wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh); wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
@ -1233,8 +1255,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
{ {
grTex = HWR_GetTexture(gl_bottomtexture); grTex = HWR_GetTexture(gl_bottomtexture);
xscale = FixedToFloat(gl_sidedef->scalex_bottom); xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom));
yscale = FixedToFloat(gl_sidedef->scaley_bottom); yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom));
fixed_t offsetx_bottom = gl_sidedef->offsetx_bottom;
float left = cliplow * xscale;
float right = cliphigh * xscale;
if (gl_sidedef->scalex_bottom < 0)
{
left = -left;
right = -right;
offsetx_bottom = -offsetx_bottom;
}
// PEGGING // PEGGING
if (!(gl_linedef->flags & ML_DONTPEGBOTTOM)) if (!(gl_linedef->flags & ML_DONTPEGBOTTOM))
@ -1246,15 +1279,18 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
texturevpeg *= yscale; texturevpeg *= yscale;
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom; if (gl_sidedef->scaley_bottom < 0)
texturevpeg -= gl_sidedef->rowoffset + gl_sidedef->offsety_bottom;
else
texturevpeg += gl_sidedef->rowoffset + gl_sidedef->offsety_bottom;
// 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 // 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 %= FixedDiv(textureheight[gl_bottomtexture], gl_sidedef->scaley_bottom); texturevpeg %= FixedDiv(textureheight[gl_bottomtexture], abs(gl_sidedef->scaley_bottom));
wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY; wallVerts[3].t = wallVerts[2].t = texturevpeg * grTex->scaleY;
wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_backsector->floorheight - gl_frontsector->floorheight) * yscale) * grTex->scaleY; wallVerts[0].t = wallVerts[1].t = (texturevpeg + (gl_backsector->floorheight - gl_frontsector->floorheight) * yscale) * grTex->scaleY;
wallVerts[0].s = wallVerts[3].s = ((cliplow * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX; wallVerts[0].s = wallVerts[3].s = (left + offsetx_bottom) * grTex->scaleX;
wallVerts[2].s = wallVerts[1].s = ((cliphigh * xscale) + gl_sidedef->offsetx_bottom) * grTex->scaleX; wallVerts[2].s = wallVerts[1].s = (right + offsetx_bottom) * grTex->scaleX;
// Adjust t value for sloped walls // Adjust t value for sloped walls
if (!(gl_linedef->flags & ML_SKEWTD)) if (!(gl_linedef->flags & ML_SKEWTD))
@ -1278,6 +1314,14 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY; wallVerts[1].t = (texturevpeg + (worldlowslope - worldbottomslope) * yscale) * grTex->scaleY;
} }
if (gl_sidedef->scaley_bottom < 0)
{
wallVerts[0].t = -wallVerts[0].t;
wallVerts[1].t = -wallVerts[1].t;
wallVerts[2].t = -wallVerts[2].t;
wallVerts[3].t = -wallVerts[3].t;
}
// set top/bottom coords // set top/bottom coords
wallVerts[3].y = FIXED_TO_FLOAT(worldlow); wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom); wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
@ -1296,7 +1340,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf))
{ {
sector_t *front, *back; sector_t *front, *back;
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid); fixed_t texheight = FixedDiv(textureheight[gl_midtexture], abs(gl_sidedef->scaley_mid));
INT32 repeats; INT32 repeats;
if (gl_linedef->frontsector->heightsec != -1) if (gl_linedef->frontsector->heightsec != -1)
@ -1363,7 +1407,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// Find the wall's coordinates // Find the wall's coordinates
fixed_t midtexheight = texheight * repeats; fixed_t midtexheight = texheight * repeats;
fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, gl_sidedef->scaley_mid); fixed_t rowoffset = FixedDiv(gl_sidedef->rowoffset + gl_sidedef->offsety_mid, abs(gl_sidedef->scaley_mid));
// Texture is not skewed // Texture is not skewed
if (gl_linedef->flags & ML_NOSKEW) if (gl_linedef->flags & ML_NOSKEW)

View file

@ -1424,20 +1424,20 @@ static void R_RenderSegLoop (void)
{ {
angle_t angle; angle_t angle;
fixed_t textureoffset; fixed_t textureoffset;
size_t pindex; size_t pindex;
INT32 yl; INT32 yl;
INT32 yh; INT32 yh;
INT32 mid; INT32 mid;
fixed_t texturecolumn = 0; fixed_t texturecolumn = 0;
fixed_t toptexturecolumn = 0; fixed_t toptexturecolumn = 0;
fixed_t bottomtexturecolumn = 0; fixed_t bottomtexturecolumn = 0;
fixed_t oldtexturecolumn = -1; fixed_t oldtexturecolumn = -1;
fixed_t oldtexturecolumn_top = -1; fixed_t oldtexturecolumn_top = -1;
fixed_t oldtexturecolumn_bottom = -1; fixed_t oldtexturecolumn_bottom = -1;
INT32 top; INT32 top;
INT32 bottom; INT32 bottom;
INT32 i; INT32 i;
fixed_t topscaley = rw_toptexturescaley; fixed_t topscaley = rw_toptexturescaley;
fixed_t midscaley = rw_midtexturescaley; fixed_t midscaley = rw_midtexturescaley;
@ -1838,8 +1838,11 @@ static void R_RenderSegLoop (void)
{ {
if (oldtexturecolumn != -1) if (oldtexturecolumn != -1)
{ {
rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); INT32 diff = oldtexturecolumn-texturecolumn;
rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); if (rw_invmidtexturescalex < 0)
diff = -diff;
rw_midtexturemid += FixedMul(rw_midtextureslide, diff);
rw_midtextureback += FixedMul(rw_midtexturebackslide, diff);
} }
oldtexturecolumn = texturecolumn; oldtexturecolumn = texturecolumn;
@ -1878,8 +1881,11 @@ static void R_RenderSegLoop (void)
if (oldoverlaycolumn[i] != -1) if (oldoverlaycolumn[i] != -1)
{ {
rw_overlay[i].mid += FixedMul(rw_overlay[i].slide, oldoverlaycolumn[i]-overlaycolumn[i]); INT32 diff = oldoverlaycolumn[i]-overlaycolumn[i];
rw_overlay[i].back += FixedMul(rw_overlay[i].backslide, oldoverlaycolumn[i]-overlaycolumn[i]); if (rw_overlay[i].scalex < 0)
diff = -diff;
rw_overlay[i].mid += FixedMul(rw_overlay[i].slide, diff);
rw_overlay[i].back += FixedMul(rw_overlay[i].backslide, diff);
} }
oldoverlaycolumn[i] = overlaycolumn[i]; oldoverlaycolumn[i] = overlaycolumn[i];
@ -2059,7 +2065,7 @@ static void R_AddOverlayTextures(fixed_t ceilingfrontslide, fixed_t floorfrontsl
rw_overlay[i].offsetx = sidedef->overlays[i].offsetx; rw_overlay[i].offsetx = sidedef->overlays[i].offsetx;
rw_overlay[i].offsety = sidedef->overlays[i].offsety; rw_overlay[i].offsety = sidedef->overlays[i].offsety;
rw_overlay[i].invscalex = FixedDiv(FRACUNIT, abs(rw_overlay[i].scalex)); rw_overlay[i].invscalex = FixedDiv(FRACUNIT, rw_overlay[i].scalex);
if (sidedef->flags & GET_SIDEFLAG_EDGENOSKEW(i)) if (sidedef->flags & GET_SIDEFLAG_EDGENOSKEW(i))
{ {
@ -2333,7 +2339,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_midtexturescalex = sidedef->scalex_mid; rw_midtexturescalex = sidedef->scalex_mid;
rw_midtexturescaley = sidedef->scaley_mid; rw_midtexturescaley = sidedef->scaley_mid;
rw_invmidtexturescalex = FixedDiv(FRACUNIT, abs(rw_midtexturescalex)); rw_invmidtexturescalex = FixedDiv(FRACUNIT, rw_midtexturescalex);
if (!backsector) if (!backsector)
{ {
@ -2578,7 +2584,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_toptexturescalex = sidedef->scalex_top; rw_toptexturescalex = sidedef->scalex_top;
rw_toptexturescaley = sidedef->scaley_top; rw_toptexturescaley = sidedef->scaley_top;
rw_invtoptexturescalex = FixedDiv(FRACUNIT, abs(rw_toptexturescalex)); rw_invtoptexturescalex = FixedDiv(FRACUNIT, rw_toptexturescalex);
if (rw_toptexturescaley < 0) if (rw_toptexturescaley < 0)
toprowoffset = -toprowoffset; toprowoffset = -toprowoffset;
@ -2618,7 +2624,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_bottomtexturescalex = sidedef->scalex_bottom; rw_bottomtexturescalex = sidedef->scalex_bottom;
rw_bottomtexturescaley = sidedef->scaley_bottom; rw_bottomtexturescaley = sidedef->scaley_bottom;
rw_invbottomtexturescalex = FixedDiv(FRACUNIT, abs(rw_bottomtexturescalex)); rw_invbottomtexturescalex = FixedDiv(FRACUNIT, rw_bottomtexturescalex);
if (rw_bottomtexturescaley < 0) if (rw_bottomtexturescaley < 0)
botrowoffset = -botrowoffset; botrowoffset = -botrowoffset;

View file

@ -704,8 +704,6 @@ static size_t flippedcolsize;
void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void)) void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void))
{ {
UINT8 *d, *s;
if (!length) if (!length)
return; return;
@ -717,8 +715,8 @@ void R_DrawFlippedPost(UINT8 *source, unsigned length, void (*drawcolfunc)(void)
dc_source = flippedcol; dc_source = flippedcol;
for (s = (UINT8 *)source+length, d = flippedcol; d < flippedcol+length; --s) for (UINT8 *s = (UINT8 *)source, *d = flippedcol+length-1; d >= flippedcol; s++)
*d++ = *s; *d-- = *s;
drawcolfunc(); drawcolfunc();
} }
@ -729,7 +727,6 @@ void R_DrawFlippedMaskedColumn(column_t *column)
INT32 bottomscreen; INT32 bottomscreen;
fixed_t basetexturemid = dc_texturemid; fixed_t basetexturemid = dc_texturemid;
INT32 topdelta, prevdelta = -1; INT32 topdelta, prevdelta = -1;
UINT8 *d,*s;
for (; column->topdelta != 0xff ;) for (; column->topdelta != 0xff ;)
{ {
@ -769,7 +766,7 @@ void R_DrawFlippedMaskedColumn(column_t *column)
dc_texturemid = basetexturemid - (topdelta<<FRACBITS); dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
// Still drawn by R_DrawColumn. // Still drawn by R_DrawColumn.
R_DrawFlippedPost((UINT8 *)column+2, column->length, colfunc); R_DrawFlippedPost((UINT8 *)column+3, column->length, colfunc);
} }
column = (column_t *)((UINT8 *)column + column->length + 4); column = (column_t *)((UINT8 *)column + column->length + 4);
} }