From 368c78878925bb0f68aa339f0c246cfb986d4715 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 00:46:58 +0100 Subject: [PATCH] - added a 'check only' option to CreateTexBuffer. This is meant to calculate the content ID without constructing the texture buffer. --- src/textures/hires/hirestex.cpp | 37 +++++++------- src/textures/hires/hqresize.cpp | 86 +++++++++++++++++---------------- src/textures/texture.cpp | 44 +++++++++-------- src/textures/textures.h | 5 +- 4 files changed, 91 insertions(+), 81 deletions(-) diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index 1e05d22bdb..d18735fa7d 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -358,7 +358,7 @@ int FTexture::CheckExternalFile(bool & hascolorkey) // //========================================================================== -bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) +bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly) { if (HiresLump == -1) { @@ -377,24 +377,27 @@ bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) int w = HiresTexture->GetWidth(); int h = HiresTexture->GetHeight(); - unsigned char * buffer = new unsigned char[w*(h + 1) * 4]; - 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) + if (!checkonly) { - // 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--) + unsigned char * buffer = new unsigned char[w*(h + 1) * 4]; + 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) { - 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; diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index b9da15ad4b..cc8a65678b 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -352,7 +352,7 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int // 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 // 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; } #endif - if (mult < 2) - type = 0; + // 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 (type == 1) + if (!checkonly) { - 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 (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; - } + 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 == 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; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index eb8f48f963..f6ee5a8dab 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -668,6 +668,7 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) unsigned char * buffer = nullptr; int W, H; int isTransparent = -1; + bool checkonly = !!(flags & CTF_CheckOnly); if (flags & CTF_CheckHires) { @@ -679,25 +680,28 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) W = GetWidth() + 2 * exx; H = GetHeight() + 2 * exx; - buffer = new unsigned char[W*(H + 1) * 4]; - 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) + if (!checkonly) { - CheckTrans(buffer, W*H, trans); - isTransparent = bTranslucent; - } - else - { - isTransparent = 0; - // A translated image is not conclusive for setting the texture's transparency info. + buffer = new unsigned char[W*(H + 1) * 4]; + 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); + isTransparent = bTranslucent; + } + else + { + isTransparent = 0; + // A translated image is not conclusive for setting the texture's transparency info. + } } 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.) if (GetImage() && flags & CTF_ProcessData) { - CreateUpsampledTextureBuffer(result, !!isTransparent); - ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); + CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); + if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); } return result; diff --git a/src/textures/textures.h b/src/textures/textures.h index b96fc5b07c..6fdf6dbc23 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -109,6 +109,7 @@ enum ECreateTexBufferFlags CTF_CheckHires = 1, // use external hires replacement if found 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_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 FImageSource *GetImage() const { return nullptr; } 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. int GetDisplayWidth() { return GetScaledWidth(); } @@ -491,7 +492,7 @@ public: private: int CheckDDPK3(); int CheckExternalFile(bool & hascolorkey); - bool LoadHiresTexture(FTextureBuffer &texbuffer); + bool LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly); bool bSWSkyColorDone = false; PalEntry FloorSkyColor;