Skip to content

Commit

Permalink
- enable the texture scalers in software mode.
Browse files Browse the repository at this point in the history
Currently only implemented for 8 bit in the classic renderer.
  • Loading branch information
coelckers committed Dec 14, 2018
1 parent 656dbc9 commit 4d8e8e7
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 82 deletions.
12 changes: 6 additions & 6 deletions src/swrenderer/line/r_line.cpp
Expand Up @@ -858,7 +858,7 @@ namespace swrenderer
}
else
{
mTopPart.TextureMid += rowoffset;
mTopPart.TextureMid += rowoffset * mTopPart.Texture->GetPhysicalScale();
}
}

Expand Down Expand Up @@ -918,7 +918,7 @@ namespace swrenderer
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
mMiddlePart.TextureMid += rowoffset;
mMiddlePart.TextureMid += rowoffset * mMiddlePart.Texture->GetPhysicalScale();
}
}

Expand Down Expand Up @@ -983,7 +983,7 @@ namespace swrenderer
}
else
{
mBottomPart.TextureMid += rowoffset;
mBottomPart.TextureMid += rowoffset * mBottomPart.Texture->GetPhysicalScale();
}
}

Expand Down Expand Up @@ -1158,7 +1158,7 @@ namespace swrenderer
}
else
{
offset = mTopPart.TextureOffsetU;
offset = mTopPart.TextureOffsetU * mTopPart.Texture->GetPhysicalScale();
}
if (xscale < 0)
{
Expand Down Expand Up @@ -1205,7 +1205,7 @@ namespace swrenderer
}
else
{
offset = mMiddlePart.TextureOffsetU;
offset = mMiddlePart.TextureOffsetU * mMiddlePart.Texture->GetPhysicalScale();
}
if (xscale < 0)
{
Expand Down Expand Up @@ -1253,7 +1253,7 @@ namespace swrenderer
}
else
{
offset = mBottomPart.TextureOffsetU;
offset = mBottomPart.TextureOffsetU * mBottomPart.Texture->GetPhysicalScale();
}
if (xscale < 0)
{
Expand Down
40 changes: 39 additions & 1 deletion src/swrenderer/textures/r_swtexture.cpp
Expand Up @@ -37,6 +37,9 @@
#include "r_swtexture.h"
#include "bitmap.h"
#include "m_alloc.h"
#include "imagehelpers.h"

EXTERN_CVAR(Bool, gl_texture_usehires)


FSoftwareTexture *FTexture::GetSoftwareTexture()
Expand All @@ -56,6 +59,25 @@ 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 ()
{
// WidthBits is rounded down, and HeightBits is rounded up
Expand Down Expand Up @@ -93,7 +115,23 @@ const uint8_t *FSoftwareTexture::GetPixels(int 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(GetWidth()*GetHeight());
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;
for (int y = 0; y < GetHeight(); y++)
{
for (int x = 0; x < GetWidth(); x++)
{
Pixels[y + x * GetHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetWidth()], true);
}
}
}
}
return Pixels.Data();
}
Expand Down
32 changes: 15 additions & 17 deletions src/swrenderer/textures/r_swtexture.h
Expand Up @@ -21,19 +21,17 @@ class FSoftwareTexture
FSoftwareTextureSpan **Spandata[3] = { };
uint8_t WidthBits = 0, HeightBits = 0;
uint16_t WidthMask = 0;

int mPhysicalWidth, mPhysicalHeight;
int mPhysicalScale;
int mBufferFlags;

void FreeAllSpans();
template<class T> FSoftwareTextureSpan **CreateSpans(const T *pixels);
void FreeSpans(FSoftwareTextureSpan **spans);
void CalcBitSize();

public:
FSoftwareTexture(FTexture *tex)
{
mTexture = tex;
mSource = tex;
CalcBitSize();
}
FSoftwareTexture(FTexture *tex);

virtual ~FSoftwareTexture()
{
Expand All @@ -59,24 +57,23 @@ class FSoftwareTexture
int GetSkyOffset() const { return mTexture->GetSkyOffset(); }
PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); }

int GetWidth () { return mTexture->GetWidth(); }
int GetHeight () { return mTexture->GetHeight(); }
int GetWidth () { return mPhysicalWidth; }
int GetHeight () { return mPhysicalHeight; }
int GetWidthBits() { return WidthBits; }
int GetHeightBits() { return HeightBits; }

int GetScaledWidth () { return mTexture->GetScaledWidth(); }
int GetScaledHeight () { return mTexture->GetScaledHeight(); }
double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); }
double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); }
double GetScaleY() const { return mTexture->GetScaleY(); }

// Now with improved offset adjustment.
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); }
int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); }
int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); }
int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); }
double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted); }
double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted); }
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted) * mPhysicalScale; }
int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted) * mPhysicalScale; }
int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted) * mPhysicalScale; }
int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted) * mPhysicalScale; }
double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted) * mPhysicalScale; }
double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted) * mPhysicalScale; }

// 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.
Expand All @@ -93,7 +90,8 @@ class FSoftwareTexture
int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); }
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }

DVector2 GetScale() const { return mTexture->Scale; }
DVector2 GetScale() const { return mTexture->Scale * mPhysicalScale; }
int GetPhysicalScale() const { return mPhysicalScale; }

virtual void Unload()
{
Expand Down
118 changes: 60 additions & 58 deletions src/textures/hires/hqresize.cpp
Expand Up @@ -387,69 +387,71 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
break;
}

if (texbuffer.mBuffer)
{
int type = gl_texture_hqresizemode;
int mult = gl_texture_hqresizemult;
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)
{
type = 2;
}
// 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;
// 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 (!checkonly)
{
if (type == 1)
{
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;
}
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 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;
}
// 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
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;
}
1 change: 1 addition & 0 deletions src/textures/textures.h
Expand Up @@ -330,6 +330,7 @@ class FTexture
int isWarped() const { return bWarped; }
int GetRotations() const { return Rotations; }
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; }
bool allowNoDecals() const { return bNoDecals; }
Expand Down

0 comments on commit 4d8e8e7

Please sign in to comment.