- added a 'check only' option to CreateTexBuffer.

This is meant to calculate the content ID without constructing the texture buffer.
This commit is contained in:
Christoph Oelckers 2018-12-12 00:46:58 +01:00
parent 200188b3a4
commit 368c788789
4 changed files with 91 additions and 81 deletions

View file

@ -358,7 +358,7 @@ int FTexture::CheckExternalFile(bool & hascolorkey)
// //
//========================================================================== //==========================================================================
bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly)
{ {
if (HiresLump == -1) if (HiresLump == -1)
{ {
@ -377,24 +377,27 @@ bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer)
int w = HiresTexture->GetWidth(); int w = HiresTexture->GetWidth();
int h = HiresTexture->GetHeight(); int h = HiresTexture->GetHeight();
unsigned char * buffer = new unsigned char[w*(h + 1) * 4]; if (!checkonly)
memset(buffer, 0, w * (h + 1) * 4);
FBitmap bmp(buffer, w * 4, w, h);
int trans;
auto Pixels = HiresTexture->GetBgraBitmap(nullptr, &trans);
bmp.Blit(0, 0, Pixels);
HiresTexture->CheckTrans(buffer, w*h, trans);
if (bHiresHasColorKey)
{ {
// This is a crappy Doomsday color keyed image unsigned char * buffer = new unsigned char[w*(h + 1) * 4];
// We have to remove the key manually. :( memset(buffer, 0, w * (h + 1) * 4);
uint32_t * dwdata = (uint32_t*)buffer;
for (int i = (w*h); i>0; i--) FBitmap bmp(buffer, w * 4, w, h);
int trans;
auto Pixels = HiresTexture->GetBgraBitmap(nullptr, &trans);
bmp.Blit(0, 0, Pixels);
HiresTexture->CheckTrans(buffer, w*h, trans);
if (bHiresHasColorKey)
{ {
if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; // This is a crappy Doomsday color keyed image
// We have to remove the key manually. :(
uint32_t * dwdata = (uint32_t*)buffer;
for (int i = (w*h); i > 0; i--)
{
if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0;
}
} }
} }
FContentIdBuilder contentId; FContentIdBuilder contentId;

View file

@ -352,7 +352,7 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int
// the upsampled buffer. // the upsampled buffer.
// //
//=========================================================================== //===========================================================================
void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha) void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly)
{ {
// [BB] Make sure that inWidth and inHeight denote the size of // [BB] Make sure that inWidth and inHeight denote the size of
// the returned buffer even if we don't upsample the input buffer. // the returned buffer even if we don't upsample the input buffer.
@ -398,51 +398,53 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
type = 2; type = 2;
} }
#endif #endif
if (mult < 2) // These checks are to ensure consistency of the content ID.
type = 0; 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) if (type == 1)
texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); {
else if (mult == 3) if (mult == 2)
texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else if (mult == 4) else if (mult == 3)
texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else return; else if (mult == 4)
} texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else if (type == 2) else return;
{ }
if (mult == 2) else if (type == 2)
texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); {
else if (mult == 3) if (mult == 2)
texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else if (mult == 4) else if (mult == 3)
texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else return; else if (mult == 4)
} texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else return;
}
#ifdef HAVE_MMX #ifdef HAVE_MMX
else if (type == 3) else if (type == 3)
{ {
if (mult == 2) if (mult == 2)
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else if (mult == 3) else if (mult == 3)
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else if (mult == 4) else if (mult == 4)
texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else return; else return;
} }
#endif #endif
else if (type == 4) else if (type == 4)
texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else if (type == 5) else if (type == 5)
texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else if (type == 6) else if (type == 6)
texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight);
else else
return; return;
}
// Encode the scaling method in the content ID. // Encode the scaling method in the content ID.
FContentIdBuilder contentId; FContentIdBuilder contentId;
contentId.id = texbuffer.mContentId; contentId.id = texbuffer.mContentId;

View file

@ -668,6 +668,7 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
unsigned char * buffer = nullptr; unsigned char * buffer = nullptr;
int W, H; int W, H;
int isTransparent = -1; int isTransparent = -1;
bool checkonly = !!(flags & CTF_CheckOnly);
if (flags & CTF_CheckHires) if (flags & CTF_CheckHires)
{ {
@ -679,25 +680,28 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
W = GetWidth() + 2 * exx; W = GetWidth() + 2 * exx;
H = GetHeight() + 2 * exx; H = GetHeight() + 2 * exx;
buffer = new unsigned char[W*(H + 1) * 4]; if (!checkonly)
memset(buffer, 0, W * (H + 1) * 4);
auto remap = translation <= 0? nullptr : FUniquePalette::GetPalette(translation);
FBitmap bmp(buffer, W * 4, W, H);
int trans;
auto Pixels = GetBgraBitmap(remap, &trans);
bmp.Blit(exx, exx, Pixels);
if (remap == nullptr)
{ {
CheckTrans(buffer, W*H, trans); buffer = new unsigned char[W*(H + 1) * 4];
isTransparent = bTranslucent; memset(buffer, 0, W * (H + 1) * 4);
}
else auto remap = translation <= 0 ? nullptr : FUniquePalette::GetPalette(translation);
{ FBitmap bmp(buffer, W * 4, W, H);
isTransparent = 0;
// A translated image is not conclusive for setting the texture's transparency info. int trans;
auto Pixels = GetBgraBitmap(remap, &trans);
bmp.Blit(exx, exx, Pixels);
if (remap == nullptr)
{
CheckTrans(buffer, W*H, trans);
isTransparent = bTranslucent;
}
else
{
isTransparent = 0;
// A translated image is not conclusive for setting the texture's transparency info.
}
} }
if (GetImage()) if (GetImage())
@ -718,8 +722,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags)
// Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.)
if (GetImage() && flags & CTF_ProcessData) if (GetImage() && flags & CTF_ProcessData)
{ {
CreateUpsampledTextureBuffer(result, !!isTransparent); CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly);
ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false);
} }
return result; return result;

View file

@ -109,6 +109,7 @@ enum ECreateTexBufferFlags
CTF_CheckHires = 1, // use external hires replacement if found CTF_CheckHires = 1, // use external hires replacement if found
CTF_Expand = 2, // create buffer with a one-pixel wide border CTF_Expand = 2, // create buffer with a one-pixel wide border
CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture.
CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures.
}; };
@ -282,7 +283,7 @@ public:
virtual ~FTexture (); virtual ~FTexture ();
virtual FImageSource *GetImage() const { return nullptr; } virtual FImageSource *GetImage() const { return nullptr; }
void AddAutoMaterials(); void AddAutoMaterials();
void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha); void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly);
// These are mainly meant for 2D code which only needs logical information about the texture to position it properly. // These are mainly meant for 2D code which only needs logical information about the texture to position it properly.
int GetDisplayWidth() { return GetScaledWidth(); } int GetDisplayWidth() { return GetScaledWidth(); }
@ -491,7 +492,7 @@ public:
private: private:
int CheckDDPK3(); int CheckDDPK3();
int CheckExternalFile(bool & hascolorkey); int CheckExternalFile(bool & hascolorkey);
bool LoadHiresTexture(FTextureBuffer &texbuffer); bool LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly);
bool bSWSkyColorDone = false; bool bSWSkyColorDone = false;
PalEntry FloorSkyColor; PalEntry FloorSkyColor;