- 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.
This commit is contained in:
Christoph Oelckers 2023-01-07 19:12:19 +01:00
parent 4c751db489
commit aceafecce6
4 changed files with 35 additions and 9 deletions

View file

@ -59,6 +59,7 @@
#include "fontinternals.h" #include "fontinternals.h"
TArray<FBitmap> 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<FolderEntry> &folderdata, int width, int height, const DVector2 &Scale) void FFont::ReadSheetFont(TArray<FolderEntry> &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<TexPartBuild> part(1, true);
TMap<int, FGameTexture*> charMap; TMap<int, FGameTexture*> charMap;
int minchar = INT_MAX; int minchar = INT_MAX;
int maxchar = INT_MIN; int maxchar = INT_MIN;
@ -391,14 +414,15 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
if (minchar > position) minchar = int(position); if (minchar > position) minchar = int(position);
if (maxchar < maxinsheet) maxchar = maxinsheet; 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 y = 0; y < numtex_y; y++)
{ {
for (int x = 0; x < numtex_x; x++) for (int x = 0; x < numtex_x; x++)
{ {
part[0].OriginX = -width * x; auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * width, width, height);
part[0].OriginY = -height * y;
part[0].TexImage = static_cast<FImageTexture*>(tex->GetTexture());
FMultiPatchTexture *image = new FMultiPatchTexture(width, height, part, false, false);
FImageTexture *imgtex = new FImageTexture(image); FImageTexture *imgtex = new FImageTexture(image);
auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar); auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar);
gtex->SetWorldPanning(true); gtex->SetWorldPanning(true);

View file

@ -73,6 +73,7 @@ static int TranslationMapCompare (const void *a, const void *b);
// EXTERNAL DATA DECLARATIONS ---------------------------------------------- // EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern int PrintColors[]; extern int PrintColors[];
extern TArray<FBitmap> sheetBitmaps;
// PUBLIC DATA DEFINITIONS ------------------------------------------------- // PUBLIC DATA DEFINITIONS -------------------------------------------------
FFont* SmallFont, * SmallFont2, * BigFont, * BigUpper, * ConFont, * IntermissionFont, * NewConsoleFont, * NewSmallFont, 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() void V_InitFonts()
{ {
sheetBitmaps.Clear();
CreateLuminosityTranslationRanges(); CreateLuminosityTranslationRanges();
V_InitCustomFonts(); V_InitCustomFonts();
@ -929,6 +931,7 @@ void V_ClearFonts()
} }
FFont::FirstFont = nullptr; FFont::FirstFont = nullptr;
AlternativeSmallFont = OriginalSmallFont = CurrentConsoleFont = NewSmallFont = NewConsoleFont = SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = nullptr; AlternativeSmallFont = OriginalSmallFont = CurrentConsoleFont = NewSmallFont = NewConsoleFont = SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = nullptr;
sheetBitmaps.Clear();
} }
//========================================================================== //==========================================================================

View file

@ -208,7 +208,6 @@ protected:
friend void V_InitFonts(); friend void V_InitFonts();
}; };
extern FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont, *NewConsoleFont, *NewSmallFont, *CurrentConsoleFont, *OriginalSmallFont, *AlternativeSmallFont, *OriginalBigFont, *AlternativeBigFont; extern FFont *SmallFont, *SmallFont2, *BigFont, *BigUpper, *ConFont, *IntermissionFont, *NewConsoleFont, *NewSmallFont, *CurrentConsoleFont, *OriginalSmallFont, *AlternativeSmallFont, *OriginalBigFont, *AlternativeBigFont;
void V_InitFonts(); void V_InitFonts();

View file

@ -72,7 +72,6 @@ protected:
// so that all code can benefit from future improvements to that. // so that all code can benefit from future improvements to that.
virtual PalettedPixels CreatePalettedPixels(int conversion); virtual PalettedPixels CreatePalettedPixels(int conversion);
virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'.
int CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap); 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. // tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy.
TArray<uint8_t> GetPalettedPixels(int conversion); TArray<uint8_t> 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); FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr);
static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; } static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; }