Fix hexen sky stretching

This commit is contained in:
Magnus Norddahl 2016-10-16 13:08:52 +02:00
parent 73f3ff9cd4
commit 42138a6ab9

View file

@ -64,6 +64,8 @@
#pragma warning(disable:4244) #pragma warning(disable:4244)
#endif #endif
CVAR(Bool, r_capsky, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
//EXTERN_CVAR (Int, tx) //EXTERN_CVAR (Int, tx)
//EXTERN_CVAR (Int, ty) //EXTERN_CVAR (Int, ty)
@ -985,25 +987,20 @@ static const BYTE *R_GetTwoSkyColumns (FTexture *fronttex, int x)
} }
} }
static void R_DrawSkyColumn(int start_x, int y1, int y2, int columns) static void R_DrawSkyColumnStripe(int start_x, int y1, int y2, int columns, double scale, double texturemid, double yrepeat)
{ {
uint32_t height = frontskytex->GetHeight(); uint32_t height = frontskytex->GetHeight();
for (int i = 0; i < columns; i++) for (int i = 0; i < columns; i++)
{ {
double uv_stepd = skyiscale * yrepeat;
double v = (texturemid + uv_stepd * (y1 - CenterY + 0.5)) / height + 1.0f;
double v_step = uv_stepd / height;
uint32_t uv_pos = (uint32_t)(v * 0x01000000);
uint32_t uv_step = (uint32_t)(v_step * 0x01000000);
int x = start_x + i; int x = start_x + i;
int uv_fracbits = 24 - frontskytex->HeightBits;
double uv_stepd = skyiscale * frontskytex->Scale.Y;
double v = (skymid * frontskytex->Scale.Y + uv_stepd * (y1 - CenterY + 0.5)) / height;
v = v + 1.0f;
v *= height;
v *= (1 << uv_fracbits);
uint32_t uv_pos = (uint32_t)v;
uint32_t uv_step = xs_ToFixed(uv_fracbits, uv_stepd);
if (uv_step == 0) // To prevent divide by zero elsewhere
uv_step = 1;
if (MirrorFlags & RF_XFLIP) if (MirrorFlags & RF_XFLIP)
x = (viewwidth - x); x = (viewwidth - x);
@ -1023,7 +1020,6 @@ static void R_DrawSkyColumn(int start_x, int y1, int y2, int columns)
bufplce[i] = (const BYTE *)frontskytex->GetColumnBgra(angle1, nullptr); bufplce[i] = (const BYTE *)frontskytex->GetColumnBgra(angle1, nullptr);
bufplce2[i] = backskytex ? (const BYTE *)backskytex->GetColumnBgra(angle2, nullptr) : nullptr; bufplce2[i] = backskytex ? (const BYTE *)backskytex->GetColumnBgra(angle2, nullptr) : nullptr;
buftexturefracx[i] = 0;
vince[i] = uv_step; vince[i] = uv_step;
vplce[i] = uv_pos; vplce[i] = uv_pos;
} }
@ -1048,18 +1044,30 @@ static void R_DrawSkyColumn(int start_x, int y1, int y2, int columns)
R_DrawDoubleSkyCol1(solid_top, solid_bottom); R_DrawDoubleSkyCol1(solid_top, solid_bottom);
} }
static void R_DrawTruecolorSky(visplane_t *pl) static void R_DrawSkyColumn(int start_x, int y1, int y2, int columns)
{ {
R_SetColorMapLight(fixedcolormap, 0, 0); if (1 << frontskytex->HeightBits == frontskytex->GetHeight())
palookupoffse[0] = dc_colormap; {
palookupoffse[1] = dc_colormap; double texturemid = skymid * frontskytex->Scale.Y;
palookupoffse[2] = dc_colormap; R_DrawSkyColumnStripe(start_x, y1, y2, columns, frontskytex->Scale.Y, texturemid, frontskytex->Scale.Y);
palookupoffse[3] = dc_colormap; }
palookuplight[0] = 0; else
palookuplight[1] = 0; {
palookuplight[2] = 0; double yrepeat = frontskytex->Scale.Y;
palookuplight[3] = 0; double scale = frontskytex->Scale.Y * skyscale;
setupvline(FRACBITS); double iscale = 1 / scale;
short drawheight = short(frontskytex->GetHeight() * scale);
double topfrac = fmod(skymid + iscale * (1 - CenterY), frontskytex->GetHeight());
if (topfrac < 0) topfrac += frontskytex->GetHeight();
double texturemid = topfrac - iscale * (1 - CenterY);
R_DrawSkyColumnStripe(start_x, y1, y2, columns, scale, texturemid, yrepeat);
}
}
static void R_DrawCapSky(visplane_t *pl)
{
if (!r_swtruecolor)
R_SetColorMapLight(fixedcolormap, 0, 0);
int x1 = pl->left; int x1 = pl->left;
int x2 = pl->right; int x2 = pl->right;
@ -1104,7 +1112,6 @@ static void R_DrawTruecolorSky(visplane_t *pl)
if (y2[i] <= y1[i]) if (y2[i] <= y1[i])
empty_column_in_set = true; empty_column_in_set = true;
} }
if (empty_column_in_set || middle_y2 <= middle_y1) if (empty_column_in_set || middle_y2 <= middle_y1)
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@ -1149,9 +1156,9 @@ static void R_DrawTruecolorSky(visplane_t *pl)
static void R_DrawSky (visplane_t *pl) static void R_DrawSky (visplane_t *pl)
{ {
if (r_swtruecolor) if (r_swtruecolor && r_capsky)
{ {
R_DrawTruecolorSky(pl); R_DrawCapSky(pl);
return; return;
} }