mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
Merge branch 'SoftwareScaling'
This commit is contained in:
commit
9787e32d28
15 changed files with 248 additions and 168 deletions
|
@ -50,8 +50,8 @@ void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height)
|
||||||
void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, FRenderStyle style)
|
void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, FRenderStyle style)
|
||||||
{
|
{
|
||||||
mTexture = texture;
|
mTexture = texture;
|
||||||
mTextureWidth = texture->GetWidth();
|
mTextureWidth = texture->GetPhysicalWidth();
|
||||||
mTextureHeight = texture->GetHeight();
|
mTextureHeight = texture->GetPhysicalHeight();
|
||||||
if (PolyTriangleDrawer::IsBgra())
|
if (PolyTriangleDrawer::IsBgra())
|
||||||
mTexturePixels = (const uint8_t *)texture->GetPixelsBgra();
|
mTexturePixels = (const uint8_t *)texture->GetPixelsBgra();
|
||||||
else
|
else
|
||||||
|
@ -73,8 +73,8 @@ void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, uint32_t translationID,
|
||||||
mTranslation = table->Remap;
|
mTranslation = table->Remap;
|
||||||
|
|
||||||
mTexture = texture;
|
mTexture = texture;
|
||||||
mTextureWidth = texture->GetWidth();
|
mTextureWidth = texture->GetPhysicalWidth();
|
||||||
mTextureHeight = texture->GetHeight();
|
mTextureHeight = texture->GetPhysicalHeight();
|
||||||
mTexturePixels = texture->GetPixels(style);
|
mTexturePixels = texture->GetPixels(style);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -83,8 +83,8 @@ void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, uint32_t translationID,
|
||||||
if (style.Flags & STYLEF_RedIsAlpha)
|
if (style.Flags & STYLEF_RedIsAlpha)
|
||||||
{
|
{
|
||||||
mTexture = texture;
|
mTexture = texture;
|
||||||
mTextureWidth = texture->GetWidth();
|
mTextureWidth = texture->GetPhysicalWidth();
|
||||||
mTextureHeight = texture->GetHeight();
|
mTextureHeight = texture->GetPhysicalHeight();
|
||||||
mTexturePixels = texture->GetPixels(style);
|
mTexturePixels = texture->GetPixels(style);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -158,25 +158,25 @@ void RenderPolyDecal::Render(PolyRenderThread *thread, DBaseDecal *decal, const
|
||||||
vertices[0].z = (float)ztop;
|
vertices[0].z = (float)ztop;
|
||||||
vertices[0].w = 1.0f;
|
vertices[0].w = 1.0f;
|
||||||
vertices[0].u = (float)u_left;
|
vertices[0].u = (float)u_left;
|
||||||
vertices[0].v = (float)v_top;
|
vertices[0].v = 1.0f - (float)v_top;
|
||||||
vertices[1].x = (float)decal_right.X;
|
vertices[1].x = (float)decal_right.X;
|
||||||
vertices[1].y = (float)decal_right.Y;
|
vertices[1].y = (float)decal_right.Y;
|
||||||
vertices[1].z = (float)ztop;
|
vertices[1].z = (float)ztop;
|
||||||
vertices[1].w = 1.0f;
|
vertices[1].w = 1.0f;
|
||||||
vertices[1].u = (float)u_right;
|
vertices[1].u = (float)u_right;
|
||||||
vertices[1].v = (float)v_top;
|
vertices[1].v = 1.0f - (float)v_top;
|
||||||
vertices[2].x = (float)decal_right.X;
|
vertices[2].x = (float)decal_right.X;
|
||||||
vertices[2].y = (float)decal_right.Y;
|
vertices[2].y = (float)decal_right.Y;
|
||||||
vertices[2].z = (float)zbottom;
|
vertices[2].z = (float)zbottom;
|
||||||
vertices[2].w = 1.0f;
|
vertices[2].w = 1.0f;
|
||||||
vertices[2].u = (float)u_right;
|
vertices[2].u = (float)u_right;
|
||||||
vertices[2].v = (float)v_bottom;
|
vertices[2].v = 1.0f - (float)v_bottom;
|
||||||
vertices[3].x = (float)decal_left.X;
|
vertices[3].x = (float)decal_left.X;
|
||||||
vertices[3].y = (float)decal_left.Y;
|
vertices[3].y = (float)decal_left.Y;
|
||||||
vertices[3].z = (float)zbottom;
|
vertices[3].z = (float)zbottom;
|
||||||
vertices[3].w = 1.0f;
|
vertices[3].w = 1.0f;
|
||||||
vertices[3].u = (float)u_left;
|
vertices[3].u = (float)u_left;
|
||||||
vertices[3].v = (float)v_bottom;
|
vertices[3].v = 1.0f - (float)v_bottom;
|
||||||
|
|
||||||
// Light calculations
|
// Light calculations
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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())
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
#include "r_swtexture.h"
|
#include "r_swtexture.h"
|
||||||
#include "bitmap.h"
|
#include "bitmap.h"
|
||||||
#include "m_alloc.h"
|
#include "m_alloc.h"
|
||||||
|
#include "imagehelpers.h"
|
||||||
|
|
||||||
|
EXTERN_CVAR(Bool, gl_texture_usehires)
|
||||||
|
|
||||||
|
|
||||||
FSoftwareTexture *FTexture::GetSoftwareTexture()
|
FSoftwareTexture *FTexture::GetSoftwareTexture()
|
||||||
|
@ -56,12 +59,31 @@ FSoftwareTexture *FTexture::GetSoftwareTexture()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
FSoftwareTexture::FSoftwareTexture(FTexture *tex)
|
||||||
|
{
|
||||||
|
mTexture = tex;
|
||||||
|
mSource = tex;
|
||||||
|
|
||||||
|
mBufferFlags = (gl_texture_usehires && !tex->isScaled() && tex->GetImage() && !tex->isSprite() ) ? CTF_CheckHires|CTF_ProcessData : CTF_ProcessData;
|
||||||
|
auto info = tex->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags);
|
||||||
|
mPhysicalWidth = info.mWidth;
|
||||||
|
mPhysicalHeight = info.mHeight;
|
||||||
|
mPhysicalScale = mPhysicalWidth / tex->Width;
|
||||||
|
CalcBitSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void FSoftwareTexture::CalcBitSize ()
|
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;
|
||||||
|
@ -69,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--;
|
||||||
}
|
}
|
||||||
|
@ -77,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;
|
||||||
|
@ -93,7 +115,36 @@ const uint8_t *FSoftwareTexture::GetPixels(int style)
|
||||||
{
|
{
|
||||||
if (Pixels.Size() == 0 || CheckModified(style))
|
if (Pixels.Size() == 0 || CheckModified(style))
|
||||||
{
|
{
|
||||||
Pixels = mSource->Get8BitPixels(style);
|
if (mPhysicalScale == 1)
|
||||||
|
{
|
||||||
|
Pixels = mSource->Get8BitPixels(style);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags);
|
||||||
|
Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight());
|
||||||
|
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;
|
||||||
|
if (!style)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < GetPhysicalHeight(); y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < GetPhysicalWidth(); x++)
|
||||||
|
{
|
||||||
|
Pixels[y + x * GetPhysicalHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetPhysicalWidth()], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int y = 0; y < GetPhysicalHeight(); y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < GetPhysicalWidth(); x++)
|
||||||
|
{
|
||||||
|
Pixels[y + x * GetPhysicalHeight()] = pe[x + y * GetPhysicalWidth()].r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Pixels.Data();
|
return Pixels.Data();
|
||||||
}
|
}
|
||||||
|
@ -108,8 +159,25 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra()
|
||||||
{
|
{
|
||||||
if (PixelsBgra.Size() == 0 || CheckModified(2))
|
if (PixelsBgra.Size() == 0 || CheckModified(2))
|
||||||
{
|
{
|
||||||
FBitmap bitmap = mTexture->GetBgraBitmap(nullptr);
|
if (mPhysicalScale == 1)
|
||||||
GenerateBgraFromBitmap(bitmap);
|
{
|
||||||
|
FBitmap bitmap = mTexture->GetBgraBitmap(nullptr);
|
||||||
|
GenerateBgraFromBitmap(bitmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags);
|
||||||
|
CreatePixelsBgraWithMipmaps();
|
||||||
|
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;
|
||||||
|
for (int y = 0; y < GetPhysicalHeight(); y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < GetPhysicalWidth(); x++)
|
||||||
|
{
|
||||||
|
PixelsBgra[y + x * GetPhysicalHeight()] = pe[x + y * GetPhysicalWidth()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GenerateBgraMipmaps();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return PixelsBgra.Data();
|
return PixelsBgra.Data();
|
||||||
}
|
}
|
||||||
|
@ -123,15 +191,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)
|
||||||
|
@ -142,7 +210,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -154,15 +222,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)
|
||||||
|
@ -173,7 +241,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();
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -199,21 +267,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;
|
||||||
|
@ -305,11 +373,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()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,8 +390,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);
|
||||||
|
@ -332,10 +400,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);
|
||||||
}
|
}
|
||||||
|
@ -366,32 +434,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++)
|
||||||
|
@ -447,12 +515,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);
|
||||||
|
@ -476,14 +544,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++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,19 +22,17 @@ protected:
|
||||||
FSoftwareTextureSpan **Spandata[3] = { };
|
FSoftwareTextureSpan **Spandata[3] = { };
|
||||||
uint8_t WidthBits = 0, HeightBits = 0;
|
uint8_t WidthBits = 0, HeightBits = 0;
|
||||||
uint16_t WidthMask = 0;
|
uint16_t WidthMask = 0;
|
||||||
|
int mPhysicalWidth, mPhysicalHeight;
|
||||||
|
int mPhysicalScale;
|
||||||
|
int mBufferFlags;
|
||||||
|
|
||||||
void FreeAllSpans();
|
void FreeAllSpans();
|
||||||
template<class T> FSoftwareTextureSpan **CreateSpans(const T *pixels);
|
template<class T> FSoftwareTextureSpan **CreateSpans(const T *pixels);
|
||||||
void FreeSpans(FSoftwareTextureSpan **spans);
|
void FreeSpans(FSoftwareTextureSpan **spans);
|
||||||
void CalcBitSize();
|
void CalcBitSize();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FSoftwareTexture(FTexture *tex)
|
FSoftwareTexture(FTexture *tex);
|
||||||
{
|
|
||||||
mTexture = tex;
|
|
||||||
mSource = tex;
|
|
||||||
CalcBitSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~FSoftwareTexture()
|
virtual ~FSoftwareTexture()
|
||||||
{
|
{
|
||||||
|
@ -69,7 +67,6 @@ public:
|
||||||
int GetScaledHeight () { return mTexture->GetScaledHeight(); }
|
int GetScaledHeight () { return mTexture->GetScaledHeight(); }
|
||||||
double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); }
|
double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); }
|
||||||
double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); }
|
double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); }
|
||||||
double GetScaleY() const { return mTexture->GetScaleY(); }
|
|
||||||
|
|
||||||
// Now with improved offset adjustment.
|
// Now with improved offset adjustment.
|
||||||
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); }
|
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); }
|
||||||
|
@ -95,6 +92,9 @@ public:
|
||||||
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }
|
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }
|
||||||
|
|
||||||
DVector2 GetScale() const { return mTexture->Scale; }
|
DVector2 GetScale() const { return mTexture->Scale; }
|
||||||
|
int GetPhysicalWidth() { return mPhysicalWidth; }
|
||||||
|
int GetPhysicalHeight() { return mPhysicalHeight; }
|
||||||
|
int GetPhysicalScale() const { return mPhysicalScale; }
|
||||||
|
|
||||||
virtual void Unload()
|
virtual void Unload()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -387,69 +387,71 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texbuffer.mBuffer)
|
int type = gl_texture_hqresizemode;
|
||||||
|
int mult = gl_texture_hqresizemult;
|
||||||
|
#ifdef HAVE_MMX
|
||||||
|
// hqNx MMX does not preserve the alpha channel so fall back to C-version for such textures
|
||||||
|
if (hasAlpha && type == 3)
|
||||||
{
|
{
|
||||||
int type = gl_texture_hqresizemode;
|
type = 2;
|
||||||
int mult = gl_texture_hqresizemult;
|
|
||||||
#ifdef HAVE_MMX
|
|
||||||
// hqNx MMX does not preserve the alpha channel so fall back to C-version for such textures
|
|
||||||
if (hasAlpha && type == 3)
|
|
||||||
{
|
|
||||||
type = 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// These checks are to ensure consistency of the content ID.
|
|
||||||
if (mult < 2 || mult > 6 || type < 1 || type > 6) return;
|
|
||||||
if (type < 4 && mult > 4) mult = 4;
|
|
||||||
|
|
||||||
if (!checkonly)
|
|
||||||
{
|
|
||||||
if (type == 1)
|
|
||||||
{
|
|
||||||
if (mult == 2)
|
|
||||||
texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (mult == 3)
|
|
||||||
texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (mult == 4)
|
|
||||||
texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else return;
|
|
||||||
}
|
|
||||||
else if (type == 2)
|
|
||||||
{
|
|
||||||
if (mult == 2)
|
|
||||||
texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (mult == 3)
|
|
||||||
texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (mult == 4)
|
|
||||||
texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else return;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_MMX
|
|
||||||
else if (type == 3)
|
|
||||||
{
|
|
||||||
if (mult == 2)
|
|
||||||
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (mult == 3)
|
|
||||||
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (mult == 4)
|
|
||||||
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (type == 4)
|
|
||||||
texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (type == 5)
|
|
||||||
texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else if (type == 6)
|
|
||||||
texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Encode the scaling method in the content ID.
|
|
||||||
FContentIdBuilder contentId;
|
|
||||||
contentId.id = texbuffer.mContentId;
|
|
||||||
contentId.scaler = type;
|
|
||||||
contentId.scalefactor = mult;
|
|
||||||
texbuffer.mContentId = contentId.id;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
// These checks are to ensure consistency of the content ID.
|
||||||
|
if (mult < 2 || mult > 6 || type < 1 || type > 6) return;
|
||||||
|
if (type < 4 && mult > 4) mult = 4;
|
||||||
|
|
||||||
|
if (!checkonly)
|
||||||
|
{
|
||||||
|
if (type == 1)
|
||||||
|
{
|
||||||
|
if (mult == 2)
|
||||||
|
texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (mult == 3)
|
||||||
|
texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (mult == 4)
|
||||||
|
texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
else if (type == 2)
|
||||||
|
{
|
||||||
|
if (mult == 2)
|
||||||
|
texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (mult == 3)
|
||||||
|
texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (mult == 4)
|
||||||
|
texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_MMX
|
||||||
|
else if (type == 3)
|
||||||
|
{
|
||||||
|
if (mult == 2)
|
||||||
|
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (mult == 3)
|
||||||
|
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (mult == 4)
|
||||||
|
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (type == 4)
|
||||||
|
texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (type == 5)
|
||||||
|
texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else if (type == 6)
|
||||||
|
texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texbuffer.mWidth *= mult;
|
||||||
|
texbuffer.mHeight *= mult;
|
||||||
|
}
|
||||||
|
// Encode the scaling method in the content ID.
|
||||||
|
FContentIdBuilder contentId;
|
||||||
|
contentId.id = texbuffer.mContentId;
|
||||||
|
contentId.scaler = type;
|
||||||
|
contentId.scalefactor = mult;
|
||||||
|
texbuffer.mContentId = contentId.id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,6 +330,7 @@ public:
|
||||||
int isWarped() const { return bWarped; }
|
int isWarped() const { return bWarped; }
|
||||||
int GetRotations() const { return Rotations; }
|
int GetRotations() const { return Rotations; }
|
||||||
void SetRotations(int rot) { Rotations = int16_t(rot); }
|
void SetRotations(int rot) { Rotations = int16_t(rot); }
|
||||||
|
bool isSprite() const { return UseType == ETextureType::Sprite || UseType == ETextureType::SkinSprite || UseType == ETextureType::Decal; }
|
||||||
|
|
||||||
const FString &GetName() const { return Name; }
|
const FString &GetName() const { return Name; }
|
||||||
bool allowNoDecals() const { return bNoDecals; }
|
bool allowNoDecals() const { return bNoDecals; }
|
||||||
|
|
Loading…
Reference in a new issue