From aceafecce6cd0552e395a1265f9e556c7cf38b97 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Jan 2023 19:12:19 +0100 Subject: [PATCH] - optimized sheet font texture generation. Instead of reloading the base image over and over again, let's cache it so that less time is needed for each single character. --- src/common/fonts/font.cpp | 36 ++++++++++++++++++++++++++++++------ src/common/fonts/v_font.cpp | 3 +++ src/common/fonts/v_font.h | 1 - src/common/textures/image.h | 4 ++-- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index e554f63660..011a9cadbe 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -59,6 +59,7 @@ #include "fontinternals.h" +TArray sheetBitmaps; //========================================================================== @@ -367,10 +368,32 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla } } +class FSheetTexture : public FImageSource +{ + unsigned baseSheet; + int X, Y; + +public: + + FSheetTexture(unsigned source, int x, int y, int width, int height) + { + baseSheet = source; + Width = width; + Height = height; + X = x; + Y = y; + } + + int CopyPixels(FBitmap* dest, int conversion) + { + auto& pic = sheetBitmaps[baseSheet]; + dest->CopyPixelDataRGB(0, 0, pic.GetPixels() + 4 * (X + pic.GetWidth() * Y), Width, Height, 4, pic.GetWidth() * 4, 0, CF_BGRA); + return 0; + } + +}; void FFont::ReadSheetFont(TArray &folderdata, int width, int height, const DVector2 &Scale) { - // all valid lumps must be named with a hex number that represents the Unicode character index for its first character, - TArray part(1, true); TMap charMap; int minchar = INT_MAX; int maxchar = INT_MIN; @@ -391,14 +414,15 @@ void FFont::ReadSheetFont(TArray &folderdata, int width, int height if (minchar > position) minchar = int(position); if (maxchar < maxinsheet) maxchar = maxinsheet; + FBitmap* sheetimg = &sheetBitmaps[sheetBitmaps.Reserve(1)]; + sheetimg->Create(tex->GetTexelWidth(), tex->GetTexelHeight()); + tex->GetTexture()->GetImage()->CopyPixels(sheetimg, FImageSource::normal); + for (int y = 0; y < numtex_y; y++) { for (int x = 0; x < numtex_x; x++) { - part[0].OriginX = -width * x; - part[0].OriginY = -height * y; - part[0].TexImage = static_cast(tex->GetTexture()); - FMultiPatchTexture *image = new FMultiPatchTexture(width, height, part, false, false); + auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * width, width, height); FImageTexture *imgtex = new FImageTexture(image); auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar); gtex->SetWorldPanning(true); diff --git a/src/common/fonts/v_font.cpp b/src/common/fonts/v_font.cpp index dd3e476486..f51813aeb4 100644 --- a/src/common/fonts/v_font.cpp +++ b/src/common/fonts/v_font.cpp @@ -73,6 +73,7 @@ static int TranslationMapCompare (const void *a, const void *b); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- extern int PrintColors[]; +extern TArray sheetBitmaps; // PUBLIC DATA DEFINITIONS ------------------------------------------------- FFont* SmallFont, * SmallFont2, * BigFont, * BigUpper, * ConFont, * IntermissionFont, * NewConsoleFont, * NewSmallFont, @@ -863,6 +864,7 @@ EColorRange V_ParseFontColor (const uint8_t *&color_value, int normalcolor, int void V_InitFonts() { + sheetBitmaps.Clear(); CreateLuminosityTranslationRanges(); V_InitCustomFonts(); @@ -929,6 +931,7 @@ void V_ClearFonts() } FFont::FirstFont = nullptr; AlternativeSmallFont = OriginalSmallFont = CurrentConsoleFont = NewSmallFont = NewConsoleFont = SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = nullptr; + sheetBitmaps.Clear(); } //========================================================================== diff --git a/src/common/fonts/v_font.h b/src/common/fonts/v_font.h index 72fd49e292..343cbaf5dc 100644 --- a/src/common/fonts/v_font.h +++ b/src/common/fonts/v_font.h @@ -208,7 +208,6 @@ protected: friend void V_InitFonts(); }; - extern FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont, *NewConsoleFont, *NewSmallFont, *CurrentConsoleFont, *OriginalSmallFont, *AlternativeSmallFont, *OriginalBigFont, *AlternativeBigFont; void V_InitFonts(); diff --git a/src/common/textures/image.h b/src/common/textures/image.h index 349190ec6d..5be8525497 100644 --- a/src/common/textures/image.h +++ b/src/common/textures/image.h @@ -72,7 +72,6 @@ protected: // so that all code can benefit from future improvements to that. virtual PalettedPixels CreatePalettedPixels(int conversion); - virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'. int CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap); @@ -107,7 +106,8 @@ public: // tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy. TArray GetPalettedPixels(int conversion); - // Unlile for paletted images there is no variant here that returns a persistent bitmap, because all users have to process the returned image into another format. + virtual int CopyPixels(FBitmap* bmp, int conversion); + FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr); static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; }