- implement the physical texture scaling at the drawer transition level as the frontend of the software renderers do not even need to know the textures are scaled

This commit is contained in:
Magnus Norddahl 2018-12-16 14:34:44 +01:00
parent 57525f1505
commit eaf1c4f1e2
12 changed files with 118 additions and 107 deletions

View file

@ -858,7 +858,7 @@ namespace swrenderer
} }
else else
{ {
mTopPart.TextureMid += rowoffset * mTopPart.Texture->GetPhysicalScale(); mTopPart.TextureMid += rowoffset;
} }
} }
@ -918,7 +918,7 @@ namespace swrenderer
{ {
// rowoffset is added outside the multiply so that it positions the texture // rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units. // by texels instead of world units.
mMiddlePart.TextureMid += rowoffset * mMiddlePart.Texture->GetPhysicalScale(); mMiddlePart.TextureMid += rowoffset;
} }
} }
@ -983,7 +983,7 @@ namespace swrenderer
} }
else else
{ {
mBottomPart.TextureMid += rowoffset * mBottomPart.Texture->GetPhysicalScale(); mBottomPart.TextureMid += rowoffset;
} }
} }
@ -1158,7 +1158,7 @@ namespace swrenderer
} }
else else
{ {
offset = mTopPart.TextureOffsetU * mTopPart.Texture->GetPhysicalScale(); offset = mTopPart.TextureOffsetU;
} }
if (xscale < 0) if (xscale < 0)
{ {
@ -1205,7 +1205,7 @@ namespace swrenderer
} }
else else
{ {
offset = mMiddlePart.TextureOffsetU * mMiddlePart.Texture->GetPhysicalScale(); offset = mMiddlePart.TextureOffsetU;
} }
if (xscale < 0) if (xscale < 0)
{ {
@ -1253,7 +1253,7 @@ namespace swrenderer
} }
else else
{ {
offset = mBottomPart.TextureOffsetU * mBottomPart.Texture->GetPhysicalScale(); offset = mBottomPart.TextureOffsetU;
} }
if (xscale < 0) if (xscale < 0)
{ {

View file

@ -57,10 +57,11 @@ namespace swrenderer
WallSampler::WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FSoftwareTexture *texture) WallSampler::WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FSoftwareTexture *texture)
{ {
xoffset += FLOAT2FIXED(xmagnitude * 0.5); xoffset += FLOAT2FIXED(xmagnitude * 0.5);
xoffset *= texture->GetPhysicalScale();
if (!viewport->RenderTarget->IsBgra()) if (!viewport->RenderTarget->IsBgra())
{ {
height = texture->GetHeight(); height = texture->GetPhysicalHeight();
int uv_fracbits = 32 - texture->GetHeightBits(); int uv_fracbits = 32 - texture->GetHeightBits();
if (uv_fracbits != 32) if (uv_fracbits != 32)
@ -70,13 +71,13 @@ namespace swrenderer
// Find start uv in [0-base_height[ range. // Find start uv in [0-base_height[ range.
// Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range. // Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range.
double uv_stepd = swal * yrepeat; double uv_stepd = swal * yrepeat;
double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / height; double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / texture->GetHeight();
v = v - floor(v); v = v - floor(v);
v *= height; v *= height;
v *= (1 << uv_fracbits); v *= (1 << uv_fracbits);
uv_pos = (uint32_t)(int64_t)v; uv_pos = (uint32_t)(int64_t)v;
uv_step = xs_ToFixed(uv_fracbits, uv_stepd); uv_step = xs_ToFixed(uv_fracbits, uv_stepd * texture->GetPhysicalScale());
if (uv_step == 0) // To prevent divide by zero elsewhere if (uv_step == 0) // To prevent divide by zero elsewhere
uv_step = 1; uv_step = 1;
} }
@ -92,7 +93,7 @@ namespace swrenderer
// If the texture's width isn't a power of 2, then we need to make it a // If the texture's width isn't a power of 2, then we need to make it a
// positive offset for proper clamping. // positive offset for proper clamping.
int width; int width;
if (col < 0 && (width = texture->GetWidth()) != (1 << texture->GetWidthBits())) if (col < 0 && (width = texture->GetPhysicalWidth()) != (1 << texture->GetWidthBits()))
{ {
col = width + (col % width); col = width + (col % width);
} }
@ -129,8 +130,8 @@ namespace swrenderer
bool magnifying = lod < 0.0f; bool magnifying = lod < 0.0f;
int mipmap_offset = 0; int mipmap_offset = 0;
int mip_width = texture->GetWidth(); int mip_width = texture->GetPhysicalWidth();
int mip_height = texture->GetHeight(); int mip_height = texture->GetPhysicalHeight();
if (r_mipmap && texture->Mipmapped() && mip_width > 1 && mip_height > 1) if (r_mipmap && texture->Mipmapped() && mip_width > 1 && mip_height > 1)
{ {
uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width); uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width);

View file

@ -67,6 +67,8 @@ namespace swrenderer
return; return;
} }
tex = texture;
drawerargs.SetSolidColor(3); drawerargs.SetSolidColor(3);
drawerargs.SetTexture(Thread, texture); drawerargs.SetTexture(Thread, texture);
@ -181,11 +183,11 @@ namespace swrenderer
float zbufferdepth = (float)(1.0 / fabs(planeheight / Thread->Viewport->ScreenToViewY(y, 1.0))); float zbufferdepth = (float)(1.0 / fabs(planeheight / Thread->Viewport->ScreenToViewY(y, 1.0)));
drawerargs.SetTextureUStep(distance * xstepscale / drawerargs.TextureWidth()); drawerargs.SetTextureUStep(distance * xstepscale / tex->GetWidth());
drawerargs.SetTextureUPos((distance * curxfrac + pviewx) / drawerargs.TextureWidth()); drawerargs.SetTextureUPos((distance * curxfrac + pviewx) / tex->GetWidth());
drawerargs.SetTextureVStep(distance * ystepscale / drawerargs.TextureHeight()); drawerargs.SetTextureVStep(distance * ystepscale / tex->GetHeight());
drawerargs.SetTextureVPos((distance * curyfrac + pviewy) / drawerargs.TextureHeight()); drawerargs.SetTextureVPos((distance * curyfrac + pviewy) / tex->GetHeight());
if (viewport->RenderTarget->IsBgra()) if (viewport->RenderTarget->IsBgra())
{ {

View file

@ -51,6 +51,7 @@ namespace swrenderer
double xstepscale, ystepscale; double xstepscale, ystepscale;
double basexfrac, baseyfrac; double basexfrac, baseyfrac;
VisiblePlaneLight *light_list; VisiblePlaneLight *light_list;
FSoftwareTexture *tex;
SpanDrawerArgs drawerargs; SpanDrawerArgs drawerargs;
}; };

View file

@ -248,11 +248,9 @@ namespace swrenderer
RenderPortal *renderportal = Thread->Portal.get(); RenderPortal *renderportal = Thread->Portal.get();
auto viewport = Thread->Viewport.get(); auto viewport = Thread->Viewport.get();
uint32_t height = frontskytex->GetHeight();
double uv_stepd = skyiscale * yrepeat; double uv_stepd = skyiscale * yrepeat;
double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / height; double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / frontskytex->GetHeight();
double v_step = uv_stepd / height; double v_step = uv_stepd / frontskytex->GetHeight();
uint32_t uv_pos = (uint32_t)(int32_t)(v * 0x01000000); uint32_t uv_pos = (uint32_t)(int32_t)(v * 0x01000000);
uint32_t uv_step = (uint32_t)(int32_t)(v_step * 0x01000000); uint32_t uv_step = (uint32_t)(int32_t)(v_step * 0x01000000);
@ -272,8 +270,8 @@ namespace swrenderer
{ {
ang = (skyangle + viewport->xtoviewangle[x]) ^ skyflip; ang = (skyangle + viewport->xtoviewangle[x]) ^ skyflip;
} }
angle1 = (uint32_t)((UMulScale16(ang, frontcyl) + frontpos) >> FRACBITS); angle1 = UMulScale16(ang, frontcyl) + frontpos;
angle2 = (uint32_t)((UMulScale16(ang, backcyl) + backpos) >> FRACBITS); angle2 = UMulScale16(ang, backcyl) + backpos;
drawerargs.SetFrontTexture(Thread, frontskytex, angle1); drawerargs.SetFrontTexture(Thread, frontskytex, angle1);
drawerargs.SetBackTexture(Thread, backskytex, angle2); drawerargs.SetBackTexture(Thread, backskytex, angle2);
@ -296,7 +294,7 @@ namespace swrenderer
void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2) void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2)
{ {
if (1 << frontskytex->GetHeightBits() == frontskytex->GetHeight()) if (1 << frontskytex->GetHeightBits() == frontskytex->GetPhysicalHeight())
{ {
double texturemid = skymid * frontskytex->GetScale().Y + frontskytex->GetHeight(); double texturemid = skymid * frontskytex->GetScale().Y + frontskytex->GetHeight();
DrawSkyColumnStripe(start_x, y1, y2, frontskytex->GetScale().Y, texturemid, frontskytex->GetScale().Y); DrawSkyColumnStripe(start_x, y1, y2, frontskytex->GetScale().Y, texturemid, frontskytex->GetScale().Y);

View file

@ -98,6 +98,9 @@ namespace swrenderer
drawerargs.SetSolidColor(3); drawerargs.SetSolidColor(3);
drawerargs.SetTexture(Thread, texture); drawerargs.SetTexture(Thread, texture);
_xscale /= texture->GetPhysicalScale();
_yscale /= texture->GetPhysicalScale();
lxscale = _xscale * ifloatpow2[drawerargs.TextureWidthBits()]; lxscale = _xscale * ifloatpow2[drawerargs.TextureWidthBits()];
lyscale = _yscale * ifloatpow2[drawerargs.TextureHeightBits()]; lyscale = _yscale * ifloatpow2[drawerargs.TextureHeightBits()];
xscale = 64.f / lxscale; xscale = 64.f / lxscale;

View file

@ -68,7 +68,7 @@ FSoftwareTexture::FSoftwareTexture(FTexture *tex)
auto info = tex->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags); auto info = tex->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags);
mPhysicalWidth = info.mWidth; mPhysicalWidth = info.mWidth;
mPhysicalHeight = info.mHeight; mPhysicalHeight = info.mHeight;
mPhysicalScale = mPhysicalWidth / tex->Width;; mPhysicalScale = mPhysicalWidth / tex->Width;
CalcBitSize(); CalcBitSize();
} }
@ -83,7 +83,7 @@ void FSoftwareTexture::CalcBitSize ()
// WidthBits is rounded down, and HeightBits is rounded up // WidthBits is rounded down, and HeightBits is rounded up
int i; int i;
for (i = 0; (1 << i) < GetWidth(); ++i) for (i = 0; (1 << i) < GetPhysicalWidth(); ++i)
{ } { }
WidthBits = i; WidthBits = i;
@ -91,7 +91,7 @@ void FSoftwareTexture::CalcBitSize ()
// Having WidthBits that would allow for columns past the end of the // Having WidthBits that would allow for columns past the end of the
// texture is not allowed, even if it means the entire texture is // texture is not allowed, even if it means the entire texture is
// not drawn. // not drawn.
if (GetWidth() < (1 << WidthBits)) if (GetPhysicalWidth() < (1 << WidthBits))
{ {
WidthBits--; WidthBits--;
} }
@ -99,7 +99,7 @@ void FSoftwareTexture::CalcBitSize ()
// <hr>The minimum height is 2, because we cannot shift right 32 bits.</hr> // <hr>The minimum height is 2, because we cannot shift right 32 bits.</hr>
// Scratch that. Somebody actually made a 1x1 texture, so now we have to handle it. // Scratch that. Somebody actually made a 1x1 texture, so now we have to handle it.
for (i = 0; (1 << i) < GetHeight(); ++i) for (i = 0; (1 << i) < GetPhysicalHeight(); ++i)
{ } { }
HeightBits = i; HeightBits = i;
@ -122,13 +122,13 @@ const uint8_t *FSoftwareTexture::GetPixels(int style)
else else
{ {
auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags);
Pixels.Resize(GetWidth()*GetHeight()); Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight());
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;
for (int y = 0; y < GetHeight(); y++) for (int y = 0; y < GetPhysicalHeight(); y++)
{ {
for (int x = 0; x < GetWidth(); x++) for (int x = 0; x < GetPhysicalWidth(); x++)
{ {
Pixels[y + x * GetHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetWidth()], true); Pixels[y + x * GetPhysicalHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetPhysicalWidth()], true);
} }
} }
} }
@ -156,11 +156,11 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra()
auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags);
CreatePixelsBgraWithMipmaps(); CreatePixelsBgraWithMipmaps();
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;
for (int y = 0; y < GetHeight(); y++) for (int y = 0; y < GetPhysicalHeight(); y++)
{ {
for (int x = 0; x < GetWidth(); x++) for (int x = 0; x < GetPhysicalWidth(); x++)
{ {
PixelsBgra[y + x * GetHeight()] = pe[x + y * GetWidth()]; PixelsBgra[y + x * GetPhysicalHeight()] = pe[x + y * GetPhysicalWidth()];
} }
} }
GenerateBgraMipmaps(); GenerateBgraMipmaps();
@ -178,15 +178,15 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra()
const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const FSoftwareTextureSpan **spans_out) const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const FSoftwareTextureSpan **spans_out)
{ {
auto Pixeldata = GetPixels(index); auto Pixeldata = GetPixels(index);
if ((unsigned)column >= (unsigned)GetWidth()) if ((unsigned)column >= (unsigned)GetPhysicalWidth())
{ {
if (WidthMask + 1 == GetWidth()) if (WidthMask + 1 == GetPhysicalWidth())
{ {
column &= WidthMask; column &= WidthMask;
} }
else else
{ {
column %= GetWidth(); column %= GetPhysicalWidth();
} }
} }
if (spans_out != nullptr) if (spans_out != nullptr)
@ -197,7 +197,7 @@ const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const
} }
*spans_out = Spandata[index][column]; *spans_out = Spandata[index][column];
} }
return Pixeldata + column * GetHeight(); return Pixeldata + column * GetPhysicalHeight();
} }
//========================================================================== //==========================================================================
@ -209,15 +209,15 @@ const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const
const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out)
{ {
auto Pixeldata = GetPixelsBgra(); auto Pixeldata = GetPixelsBgra();
if ((unsigned)column >= (unsigned)GetWidth()) if ((unsigned)column >= (unsigned)GetPhysicalWidth())
{ {
if (WidthMask + 1 == GetWidth()) if (WidthMask + 1 == GetPhysicalWidth())
{ {
column &= WidthMask; column &= WidthMask;
} }
else else
{ {
column %= GetWidth(); column %= GetPhysicalWidth();
} }
} }
if (spans_out != nullptr) if (spans_out != nullptr)
@ -228,7 +228,7 @@ const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoft
} }
*spans_out = Spandata[2][column]; *spans_out = Spandata[2][column];
} }
return Pixeldata + column * GetHeight(); return Pixeldata + column * GetPhysicalHeight();
} }
//========================================================================== //==========================================================================
@ -254,21 +254,21 @@ FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const T *pixels)
if (!mTexture->isMasked()) if (!mTexture->isMasked())
{ // Texture does not have holes, so it can use a simpler span structure { // Texture does not have holes, so it can use a simpler span structure
spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*GetWidth() + sizeof(FSoftwareTextureSpan)*2); spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*GetPhysicalWidth() + sizeof(FSoftwareTextureSpan)*2);
span = (FSoftwareTextureSpan *)&spans[GetWidth()]; span = (FSoftwareTextureSpan *)&spans[GetPhysicalWidth()];
for (int x = 0; x < GetWidth(); ++x) for (int x = 0; x < GetPhysicalWidth(); ++x)
{ {
spans[x] = span; spans[x] = span;
} }
span[0].Length = GetHeight(); span[0].Length = GetPhysicalHeight();
span[0].TopOffset = 0; span[0].TopOffset = 0;
span[1].Length = 0; span[1].Length = 0;
span[1].TopOffset = 0; span[1].TopOffset = 0;
} }
else else
{ // Texture might have holes, so build a complete span structure { // Texture might have holes, so build a complete span structure
int numcols = GetWidth(); int numcols = GetPhysicalWidth();
int numrows = GetHeight(); int numrows = GetPhysicalHeight();
int numspans = numcols; // One span to terminate each column int numspans = numcols; // One span to terminate each column
const T *data_p; const T *data_p;
bool newspan; bool newspan;
@ -360,11 +360,11 @@ void FSoftwareTexture::GenerateBgraFromBitmap(const FBitmap &bitmap)
// Transpose // Transpose
const uint32_t *src = (const uint32_t *)bitmap.GetPixels(); const uint32_t *src = (const uint32_t *)bitmap.GetPixels();
uint32_t *dest = PixelsBgra.Data(); uint32_t *dest = PixelsBgra.Data();
for (int x = 0; x < GetWidth(); x++) for (int x = 0; x < GetPhysicalWidth(); x++)
{ {
for (int y = 0; y < GetHeight(); y++) for (int y = 0; y < GetPhysicalHeight(); y++)
{ {
dest[y + x * GetHeight()] = src[x + y * GetWidth()]; dest[y + x * GetPhysicalHeight()] = src[x + y * GetPhysicalWidth()];
} }
} }
@ -377,8 +377,8 @@ void FSoftwareTexture::CreatePixelsBgraWithMipmaps()
int buffersize = 0; int buffersize = 0;
for (int i = 0; i < levels; i++) for (int i = 0; i < levels; i++)
{ {
int w = MAX(GetWidth() >> i, 1); int w = MAX(GetPhysicalWidth() >> i, 1);
int h = MAX(GetHeight() >> i, 1); int h = MAX(GetPhysicalHeight() >> i, 1);
buffersize += w * h; buffersize += w * h;
} }
PixelsBgra.Resize(buffersize); PixelsBgra.Resize(buffersize);
@ -387,10 +387,10 @@ void FSoftwareTexture::CreatePixelsBgraWithMipmaps()
int FSoftwareTexture::MipmapLevels() int FSoftwareTexture::MipmapLevels()
{ {
int widthbits = 0; int widthbits = 0;
while ((GetWidth() >> widthbits) != 0) widthbits++; while ((GetPhysicalWidth() >> widthbits) != 0) widthbits++;
int heightbits = 0; int heightbits = 0;
while ((GetHeight() >> heightbits) != 0) heightbits++; while ((GetPhysicalHeight() >> heightbits) != 0) heightbits++;
return MAX(widthbits, heightbits); return MAX(widthbits, heightbits);
} }
@ -421,32 +421,32 @@ void FSoftwareTexture::GenerateBgraMipmaps()
// Convert to normalized linear colorspace // Convert to normalized linear colorspace
{ {
for (int x = 0; x < GetWidth(); x++) for (int x = 0; x < GetPhysicalWidth(); x++)
{ {
for (int y = 0; y < GetHeight(); y++) for (int y = 0; y < GetPhysicalHeight(); y++)
{ {
uint32_t c8 = PixelsBgra[x * GetHeight() + y]; uint32_t c8 = PixelsBgra[x * GetPhysicalHeight() + y];
Color4f c; Color4f c;
c.a = powf(APART(c8) * (1.0f / 255.0f), 2.2f); c.a = powf(APART(c8) * (1.0f / 255.0f), 2.2f);
c.r = powf(RPART(c8) * (1.0f / 255.0f), 2.2f); c.r = powf(RPART(c8) * (1.0f / 255.0f), 2.2f);
c.g = powf(GPART(c8) * (1.0f / 255.0f), 2.2f); c.g = powf(GPART(c8) * (1.0f / 255.0f), 2.2f);
c.b = powf(BPART(c8) * (1.0f / 255.0f), 2.2f); c.b = powf(BPART(c8) * (1.0f / 255.0f), 2.2f);
image[x * GetHeight() + y] = c; image[x * GetPhysicalHeight() + y] = c;
} }
} }
} }
// Generate mipmaps // Generate mipmaps
{ {
std::vector<Color4f> smoothed(GetWidth() * GetHeight()); std::vector<Color4f> smoothed(GetPhysicalWidth() * GetPhysicalHeight());
Color4f *src = image.data(); Color4f *src = image.data();
Color4f *dest = src + GetWidth() * GetHeight(); Color4f *dest = src + GetPhysicalWidth() * GetPhysicalHeight();
for (int i = 1; i < levels; i++) for (int i = 1; i < levels; i++)
{ {
int srcw = MAX(GetWidth() >> (i - 1), 1); int srcw = MAX(GetPhysicalWidth() >> (i - 1), 1);
int srch = MAX(GetHeight() >> (i - 1), 1); int srch = MAX(GetPhysicalHeight() >> (i - 1), 1);
int w = MAX(GetWidth() >> i, 1); int w = MAX(GetPhysicalWidth() >> i, 1);
int h = MAX(GetHeight() >> i, 1); int h = MAX(GetPhysicalHeight() >> i, 1);
// Downscale // Downscale
for (int x = 0; x < w; x++) for (int x = 0; x < w; x++)
@ -502,12 +502,12 @@ void FSoftwareTexture::GenerateBgraMipmaps()
// Convert to bgra8 sRGB colorspace // Convert to bgra8 sRGB colorspace
{ {
Color4f *src = image.data() + GetWidth() * GetHeight(); Color4f *src = image.data() + GetPhysicalWidth() * GetPhysicalHeight();
uint32_t *dest = PixelsBgra.Data() + GetWidth() * GetHeight(); uint32_t *dest = PixelsBgra.Data() + GetPhysicalWidth() * GetPhysicalHeight();
for (int i = 1; i < levels; i++) for (int i = 1; i < levels; i++)
{ {
int w = MAX(GetWidth() >> i, 1); int w = MAX(GetPhysicalWidth() >> i, 1);
int h = MAX(GetHeight() >> i, 1); int h = MAX(GetPhysicalHeight() >> i, 1);
for (int j = 0; j < w * h; j++) for (int j = 0; j < w * h; j++)
{ {
uint32_t a = (uint32_t)clamp(powf(MAX(src[j].a, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); uint32_t a = (uint32_t)clamp(powf(MAX(src[j].a, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
@ -531,14 +531,14 @@ void FSoftwareTexture::GenerateBgraMipmaps()
void FSoftwareTexture::GenerateBgraMipmapsFast() void FSoftwareTexture::GenerateBgraMipmapsFast()
{ {
uint32_t *src = PixelsBgra.Data(); uint32_t *src = PixelsBgra.Data();
uint32_t *dest = src + GetWidth() * GetHeight(); uint32_t *dest = src + GetPhysicalWidth() * GetPhysicalHeight();
int levels = MipmapLevels(); int levels = MipmapLevels();
for (int i = 1; i < levels; i++) for (int i = 1; i < levels; i++)
{ {
int srcw = MAX(GetWidth() >> (i - 1), 1); int srcw = MAX(GetPhysicalWidth() >> (i - 1), 1);
int srch = MAX(GetHeight() >> (i - 1), 1); int srch = MAX(GetPhysicalHeight() >> (i - 1), 1);
int w = MAX(GetWidth() >> i, 1); int w = MAX(GetPhysicalWidth() >> i, 1);
int h = MAX(GetHeight() >> i, 1); int h = MAX(GetPhysicalHeight() >> i, 1);
for (int x = 0; x < w; x++) for (int x = 0; x < w; x++)
{ {

View file

@ -58,8 +58,8 @@ public:
int GetSkyOffset() const { return mTexture->GetSkyOffset(); } int GetSkyOffset() const { return mTexture->GetSkyOffset(); }
PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); }
int GetWidth () { return mPhysicalWidth; } int GetWidth () { return mTexture->GetWidth(); }
int GetHeight () { return mPhysicalHeight; } int GetHeight () { return mTexture->GetHeight(); }
int GetWidthBits() { return WidthBits; } int GetWidthBits() { return WidthBits; }
int GetHeightBits() { return HeightBits; } int GetHeightBits() { return HeightBits; }
@ -69,12 +69,12 @@ public:
double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); } double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); }
// Now with improved offset adjustment. // Now with improved offset adjustment.
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted) * mPhysicalScale; } int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); }
int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted) * mPhysicalScale; } int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); }
int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted) * mPhysicalScale; } int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); }
int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted) * mPhysicalScale; } int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); }
double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted) * mPhysicalScale; } double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted); }
double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted) * mPhysicalScale; } double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted); }
// Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets // Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets
// should use these, so that if changes are needed, this is the only place to edit. // should use these, so that if changes are needed, this is the only place to edit.
@ -91,7 +91,9 @@ public:
int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); }
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }
DVector2 GetScale() const { return mTexture->Scale * mPhysicalScale; } DVector2 GetScale() const { return mTexture->Scale; }
int GetPhysicalWidth() { return mPhysicalWidth; }
int GetPhysicalHeight() { return mPhysicalHeight; }
int GetPhysicalScale() const { return mPhysicalScale; } int GetPhysicalScale() const { return mPhysicalScale; }
virtual void Unload() virtual void Unload()

View file

@ -47,21 +47,21 @@ namespace swrenderer
dc_viewport = viewport; dc_viewport = viewport;
} }
void SkyDrawerArgs::SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column) void SkyDrawerArgs::SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column)
{ {
if (thread->Viewport->RenderTarget->IsBgra()) if (thread->Viewport->RenderTarget->IsBgra())
{ {
dc_source = (const uint8_t *)texture->GetColumnBgra(column, nullptr); dc_source = (const uint8_t *)texture->GetColumnBgra((column * texture->GetPhysicalScale()) >> FRACBITS, nullptr);
dc_sourceheight = texture->GetHeight(); dc_sourceheight = texture->GetPhysicalHeight();
} }
else else
{ {
dc_source = texture->GetColumn(DefaultRenderStyle(), column, nullptr); dc_source = texture->GetColumn(DefaultRenderStyle(), (column * texture->GetPhysicalScale()) >> FRACBITS, nullptr);
dc_sourceheight = texture->GetHeight(); dc_sourceheight = texture->GetPhysicalHeight();
} }
} }
void SkyDrawerArgs::SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column) void SkyDrawerArgs::SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column)
{ {
if (texture == nullptr) if (texture == nullptr)
{ {
@ -70,13 +70,13 @@ namespace swrenderer
} }
else if (thread->Viewport->RenderTarget->IsBgra()) else if (thread->Viewport->RenderTarget->IsBgra())
{ {
dc_source2 = (const uint8_t *)texture->GetColumnBgra(column, nullptr); dc_source2 = (const uint8_t *)texture->GetColumnBgra((column * texture->GetPhysicalScale()) >> FRACBITS, nullptr);
dc_sourceheight2 = texture->GetHeight(); dc_sourceheight2 = texture->GetPhysicalHeight();
} }
else else
{ {
dc_source2 = texture->GetColumn(DefaultRenderStyle(), column, nullptr); dc_source2 = texture->GetColumn(DefaultRenderStyle(), (column * texture->GetPhysicalScale()) >> FRACBITS, nullptr);
dc_sourceheight2 = texture->GetHeight(); dc_sourceheight2 = texture->GetPhysicalHeight();
} }
} }
} }

View file

@ -15,8 +15,8 @@ namespace swrenderer
public: public:
void SetDest(RenderViewport *viewport, int x, int y); void SetDest(RenderViewport *viewport, int x, int y);
void SetCount(int count) { dc_count = count; } void SetCount(int count) { dc_count = count; }
void SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column); void SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column);
void SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column); void SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column);
void SetTextureVPos(uint32_t texturefrac) { dc_texturefrac = texturefrac; } void SetTextureVPos(uint32_t texturefrac) { dc_texturefrac = texturefrac; }
void SetTextureVStep(uint32_t iscale) { dc_iscale = iscale; } void SetTextureVStep(uint32_t iscale) { dc_iscale = iscale; }
void SetSolidTop(uint32_t color) { solid_top = color; } void SetSolidTop(uint32_t color) { solid_top = color; }

View file

@ -34,21 +34,21 @@ namespace swrenderer
{ {
thread->PrepareTexture(tex, DefaultRenderStyle()); thread->PrepareTexture(tex, DefaultRenderStyle());
ds_texwidth = tex->GetWidth(); ds_texwidth = tex->GetPhysicalWidth();
ds_texheight = tex->GetHeight(); ds_texheight = tex->GetPhysicalHeight();
ds_xbits = tex->GetWidthBits(); ds_xbits = tex->GetWidthBits();
ds_ybits = tex->GetHeightBits(); ds_ybits = tex->GetHeightBits();
if ((1 << ds_xbits) > tex->GetWidth()) if ((1 << ds_xbits) > tex->GetPhysicalWidth())
{ {
ds_xbits--; ds_xbits--;
} }
if ((1 << ds_ybits) > tex->GetHeight()) if ((1 << ds_ybits) > tex->GetPhysicalHeight())
{ {
ds_ybits--; ds_ybits--;
} }
ds_source = thread->Viewport->RenderTarget->IsBgra() ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels(DefaultRenderStyle()); // Get correct render style? Shaded won't get here. ds_source = thread->Viewport->RenderTarget->IsBgra() ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels(DefaultRenderStyle()); // Get correct render style? Shaded won't get here.
ds_source_mipmapped = tex->Mipmapped() && tex->GetWidth() > 1 && tex->GetHeight() > 1; ds_source_mipmapped = tex->Mipmapped() && tex->GetPhysicalWidth() > 1 && tex->GetPhysicalHeight() > 1;
} }
void SpanDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha) void SpanDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha)

View file

@ -48,6 +48,10 @@ namespace swrenderer
if (x < thread->X1 || x >= thread->X2) if (x < thread->X1 || x >= thread->X2)
return; return;
col *= tex->GetPhysicalScale();
iscale *= tex->GetPhysicalScale();
spryscale /= tex->GetPhysicalScale();
auto viewport = thread->Viewport.get(); auto viewport = thread->Viewport.get();
// Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom. // Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom.
@ -60,7 +64,7 @@ namespace swrenderer
dc_viewport = viewport; dc_viewport = viewport;
dc_x = x; dc_x = x;
dc_iscale = iscale; dc_iscale = iscale;
dc_textureheight = tex->GetHeight(); dc_textureheight = tex->GetPhysicalHeight();
const FSoftwareTextureSpan *span; const FSoftwareTextureSpan *span;
const uint8_t *column; const uint8_t *column;
@ -74,7 +78,7 @@ namespace swrenderer
{ {
span = unmaskedSpan; span = unmaskedSpan;
unmaskedSpan[0].TopOffset = 0; unmaskedSpan[0].TopOffset = 0;
unmaskedSpan[0].Length = tex->GetHeight(); unmaskedSpan[0].Length = tex->GetPhysicalHeight();
unmaskedSpan[1].TopOffset = 0; unmaskedSpan[1].TopOffset = 0;
unmaskedSpan[1].Length = 0; unmaskedSpan[1].Length = 0;
} }
@ -134,7 +138,7 @@ namespace swrenderer
// Normalize to 0-1 range: // Normalize to 0-1 range:
double uv_stepd = FIXED2DBL(dc_iscale); double uv_stepd = FIXED2DBL(dc_iscale);
double v_step = uv_stepd / tex->GetHeight(); double v_step = uv_stepd / tex->GetPhysicalHeight();
// Convert to uint32_t: // Convert to uint32_t:
dc_iscale = (uint32_t)(v_step * (1 << 30)); dc_iscale = (uint32_t)(v_step * (1 << 30));
@ -150,8 +154,8 @@ namespace swrenderer
bool magnifying = lod < 0.0f; bool magnifying = lod < 0.0f;
int mipmap_offset = 0; int mipmap_offset = 0;
int mip_width = tex->GetWidth(); int mip_width = tex->GetPhysicalWidth();
int mip_height = tex->GetHeight(); int mip_height = tex->GetPhysicalHeight();
uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width); uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width);
if (r_mipmap && tex->Mipmapped() && mip_width > 1 && mip_height > 1) if (r_mipmap && tex->Mipmapped() && mip_width > 1 && mip_height > 1)
{ {
@ -199,7 +203,7 @@ namespace swrenderer
{ {
span = unmaskedSpan; span = unmaskedSpan;
unmaskedSpan[0].TopOffset = 0; unmaskedSpan[0].TopOffset = 0;
unmaskedSpan[0].Length = tex->GetHeight(); unmaskedSpan[0].Length = tex->GetPhysicalHeight();
unmaskedSpan[1].TopOffset = 0; unmaskedSpan[1].TopOffset = 0;
unmaskedSpan[1].Length = 0; unmaskedSpan[1].Length = 0;
} }
@ -233,7 +237,7 @@ namespace swrenderer
SetDest(dc_viewport, dc_x, dc_yl); SetDest(dc_viewport, dc_x, dc_yl);
dc_count = dc_yh - dc_yl + 1; dc_count = dc_yh - dc_yl + 1;
double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight(); double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetPhysicalHeight();
dc_texturefrac = (uint32_t)(v * (1 << 30)); dc_texturefrac = (uint32_t)(v * (1 << 30));
(thread->Drawers(dc_viewport)->*colfunc)(*this); (thread->Drawers(dc_viewport)->*colfunc)(*this);