2018-12-11 23:34:37 +00:00
# pragma once
# include "tarray.h"
2020-04-11 17:04:48 +00:00
# include "hw_ihwtexture.h"
2020-04-11 17:00:07 +00:00
# include "palettecontainer.h"
2024-02-19 09:16:36 +00:00
# include "hw_ihwtexture.h" // Note: this cannot be a forward declaration due to the inlined delete statement below.
2018-12-11 23:34:37 +00:00
struct FTextureBuffer ;
2020-04-16 21:37:22 +00:00
enum ECreateTexBufferFlags
{
CTF_Expand = 1 , // create buffer with a one-pixel wide border
CTF_Upscale = 2 , // Upscale the texture
CTF_CreateMask = 3 , // Flags that are relevant for hardware texture creation.
2020-09-27 17:28:47 +00:00
CTF_Indexed = 4 , // Tell the backend to create an indexed texture.
2020-04-16 21:37:22 +00:00
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.
2020-09-27 17:28:47 +00:00
CTF_ProcessData = 16 , // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture.
2020-04-16 21:37:22 +00:00
} ;
2018-12-11 23:34:37 +00:00
class FHardwareTextureContainer
{
public :
enum
{
MAX_TEXTURES = 16
} ;
private :
struct TranslatedTexture
{
IHardwareTexture * hwTexture = nullptr ;
int translation = 0 ;
2020-04-19 08:08:24 +00:00
bool precacheMarker ; // This is used to check whether a texture has been hit by the precacher, so that the cleanup code can delete the unneeded ones.
2018-12-11 23:34:37 +00:00
void Delete ( )
{
2024-02-19 09:16:36 +00:00
delete hwTexture ;
2018-12-11 23:34:37 +00:00
hwTexture = nullptr ;
}
2019-05-09 15:55:29 +00:00
2018-12-11 23:34:37 +00:00
~ TranslatedTexture ( )
{
Delete ( ) ;
}
2020-04-19 08:08:24 +00:00
void MarkForPrecache ( bool on )
{
precacheMarker = on ;
}
bool isMarkedForPreache ( ) const
{
return precacheMarker ;
}
2018-12-11 23:34:37 +00:00
} ;
private :
2020-04-16 21:37:22 +00:00
TranslatedTexture hwDefTex [ 4 ] ;
2018-12-11 23:34:37 +00:00
TArray < TranslatedTexture > hwTex_Translated ;
2022-01-02 11:23:42 +00:00
2020-04-16 21:37:22 +00:00
TranslatedTexture * GetTexID ( int translation , int scaleflags )
2018-12-11 23:34:37 +00:00
{
2020-05-26 20:59:50 +00:00
// Allow negative indices to pass through unchanged.
// This is needed for allowing the client to allocate slots that aren't matched to a palette, e.g. Build's indexed variants.
if ( translation > = 0 )
{
2021-05-24 19:24:17 +00:00
if ( ! IsLuminosityTranslation ( translation ) )
{
auto remap = GPalette . TranslationToTable ( translation ) ;
translation = remap = = nullptr ? 0 : remap - > Index ;
}
else
{
// only needs to preserve the color range plus an identifier for marking this a luminosity translation.
translation = ( ( translation > > 16 ) & 0x3fff ) | 0xff0000 ;
}
2020-05-26 20:59:50 +00:00
}
else translation & = ~ 0x7fffffff ;
2020-04-11 10:43:46 +00:00
2020-04-16 21:37:22 +00:00
if ( translation = = 0 & & ! ( scaleflags & CTF_Upscale ) )
2018-12-11 23:34:37 +00:00
{
2020-04-16 21:37:22 +00:00
return & hwDefTex [ scaleflags ] ;
2018-12-11 23:34:37 +00:00
}
2020-04-16 21:37:22 +00:00
translation | = ( scaleflags < < 24 ) ;
2018-12-11 23:34:37 +00:00
// normally there aren't more than very few different
// translations here so this isn't performance critical.
unsigned index = hwTex_Translated . FindEx ( [ = ] ( auto & element )
{
return element . translation = = translation ;
2018-12-12 01:28:42 +00:00
} ) ;
2018-12-11 23:34:37 +00:00
if ( index < hwTex_Translated . Size ( ) )
{
2018-12-12 01:28:42 +00:00
return & hwTex_Translated [ index ] ;
2018-12-11 23:34:37 +00:00
}
int add = hwTex_Translated . Reserve ( 1 ) ;
auto item = & hwTex_Translated [ add ] ;
item - > translation = translation ;
return item ;
}
public :
2020-04-18 21:56:22 +00:00
void Clean ( )
2018-12-11 23:34:37 +00:00
{
2020-04-16 21:37:22 +00:00
hwDefTex [ 0 ] . Delete ( ) ;
hwDefTex [ 1 ] . Delete ( ) ;
hwTex_Translated . Clear ( ) ;
2018-12-11 23:34:37 +00:00
}
2022-01-02 11:23:42 +00:00
2020-04-16 21:37:22 +00:00
IHardwareTexture * GetHardwareTexture ( int translation , int scaleflags )
2018-12-11 23:34:37 +00:00
{
2020-04-16 21:37:22 +00:00
auto tt = GetTexID ( translation , scaleflags ) ;
2018-12-11 23:34:37 +00:00
return tt - > hwTexture ;
}
2022-01-02 11:23:42 +00:00
2020-04-16 21:37:22 +00:00
void AddHardwareTexture ( int translation , int scaleflags , IHardwareTexture * tex )
2018-12-11 23:34:37 +00:00
{
2020-04-16 21:37:22 +00:00
auto tt = GetTexID ( translation , scaleflags ) ;
2018-12-11 23:34:37 +00:00
tt - > Delete ( ) ;
tt - > hwTexture = tex ;
}
2019-03-21 20:57:39 +00:00
2018-12-11 23:34:37 +00:00
//===========================================================================
//
// Deletes all allocated resources and considers translations
//
//===========================================================================
2020-04-19 08:08:24 +00:00
void CleanUnused ( )
2018-12-11 23:34:37 +00:00
{
2020-04-19 08:08:24 +00:00
for ( auto & tt : hwDefTex )
2018-12-11 23:34:37 +00:00
{
2020-04-19 08:08:24 +00:00
if ( ! tt . isMarkedForPreache ( ) ) tt . Delete ( ) ;
2018-12-11 23:34:37 +00:00
}
for ( int i = hwTex_Translated . Size ( ) - 1 ; i > = 0 ; i - - )
{
2020-04-19 08:08:24 +00:00
auto & tt = hwTex_Translated [ i ] ;
2024-02-19 11:25:05 +00:00
if ( ! tt . isMarkedForPreache ( ) )
2018-12-11 23:34:37 +00:00
{
hwTex_Translated . Delete ( i ) ;
}
}
}
2020-04-19 08:08:24 +00:00
void UnmarkAll ( )
{
for ( auto & tt : hwDefTex )
{
2024-02-19 11:25:05 +00:00
tt . MarkForPrecache ( false ) ;
2020-04-19 08:08:24 +00:00
}
for ( auto & tt : hwTex_Translated )
{
2024-02-19 11:25:05 +00:00
tt . MarkForPrecache ( false ) ;
2020-04-19 08:08:24 +00:00
}
}
void MarkForPrecache ( int translation , int scaleflags )
{
auto tt = GetTexID ( translation , scaleflags ) ;
tt - > MarkForPrecache ( true ) ;
}
2019-03-21 20:57:39 +00:00
template < class T >
void Iterate ( T callback )
{
for ( auto & t : hwDefTex ) if ( t . hwTexture ) callback ( t . hwTexture ) ;
for ( auto & t : hwTex_Translated ) if ( t . hwTexture ) callback ( t . hwTexture ) ;
}
2022-01-02 11:23:42 +00:00
2018-12-11 23:34:37 +00:00
} ;