2019-10-05 17:28:05 +00:00
/*
* * textures . h
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2005 - 2016 Randy Heit
2019-10-12 20:49:46 +00:00
* * Copyright 2005 - 2019 Christoph Oelckers
2019-10-05 17:28:05 +00:00
* * All rights reserved .
* *
* * Redistribution and use in source and binary forms , with or without
* * modification , are permitted provided that the following conditions
* * are met :
* *
* * 1. Redistributions of source code must retain the above copyright
* * notice , this list of conditions and the following disclaimer .
* * 2. Redistributions in binary form must reproduce the above copyright
* * notice , this list of conditions and the following disclaimer in the
* * documentation and / or other materials provided with the distribution .
* * 3. The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission .
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* * INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* * NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* * DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* * THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* * THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
*/
# ifndef __TEXTURES_H
# define __TEXTURES_H
2019-10-14 21:11:01 +00:00
# include "compat.h"
2019-10-05 17:28:05 +00:00
# include "textureid.h"
2019-10-05 19:59:03 +00:00
# include "zstring.h"
2019-10-12 20:49:46 +00:00
# include "tarray.h"
2019-10-05 17:28:05 +00:00
# include "palentry.h"
2019-10-17 22:20:27 +00:00
class FHardwareTexture ;
2020-05-24 11:53:27 +00:00
class FImageSource ;
2019-10-05 17:28:05 +00:00
2020-05-24 11:53:27 +00:00
enum MaterialShaderIndex
2019-10-12 20:49:46 +00:00
{
2020-05-24 11:53:27 +00:00
SHADER_Default ,
SHADER_Warp1 ,
SHADER_Warp2 ,
SHADER_Brightmap ,
SHADER_Specular ,
SHADER_SpecularBrightmap ,
SHADER_PBR ,
SHADER_PBRBrightmap ,
SHADER_Paletted ,
SHADER_NoTexture ,
SHADER_BasicFuzz ,
SHADER_SmoothFuzz ,
SHADER_SwirlyFuzz ,
SHADER_TranslucentFuzz ,
SHADER_JaggedFuzz ,
SHADER_NoiseFuzz ,
SHADER_SmoothNoiseFuzz ,
SHADER_SoftwareFuzz ,
FIRST_USER_SHADER
2019-10-12 20:49:46 +00:00
} ;
2020-05-24 11:53:27 +00:00
struct UserShaderDesc
2019-10-05 17:28:05 +00:00
{
2020-05-24 11:53:27 +00:00
FString shader ;
MaterialShaderIndex shaderType ;
FString defines ;
bool disablealphatest = false ;
2019-10-05 17:28:05 +00:00
} ;
2020-05-24 11:53:27 +00:00
extern TArray < UserShaderDesc > usershaders ;
2019-10-14 21:11:01 +00:00
2019-10-05 17:28:05 +00:00
2020-05-24 11:53:27 +00:00
struct FloatRect
2019-10-12 20:49:46 +00:00
{
2020-05-24 11:53:27 +00:00
float left , top ;
float width , height ;
2019-10-12 20:49:46 +00:00
2020-05-24 11:53:27 +00:00
void Offset ( float xofs , float yofs )
{
left + = xofs ;
top + = yofs ;
}
void Scale ( float xfac , float yfac )
2019-10-12 20:49:46 +00:00
{
2020-05-24 11:53:27 +00:00
left * = xfac ;
width * = xfac ;
top * = yfac ;
height * = yfac ;
2019-10-12 20:49:46 +00:00
}
} ;
2020-05-24 11:53:27 +00:00
enum ECreateTexBufferFlags
2019-10-12 20:49:46 +00:00
{
2020-05-24 11:53:27 +00:00
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.
2019-10-12 20:49:46 +00:00
} ;
2020-05-24 11:53:27 +00:00
2019-10-05 17:28:05 +00:00
class FBitmap ;
struct FRemapTable ;
struct FCopyInfo ;
class FScanner ;
// Texture IDs
class FTextureManager ;
class FTerrainTypeArray ;
class IHardwareTexture ;
class FMaterial ;
class FMultipatchTextureBuilder ;
extern int r_spriteadjustSW , r_spriteadjustHW ;
class FNullTextureID : public FTextureID
{
public :
FNullTextureID ( ) : FTextureID ( 0 ) { }
} ;
2020-05-24 11:53:27 +00:00
enum FTextureFormat : uint32_t
{
TEX_Pal ,
TEX_Gray ,
TEX_RGB , // Actually ARGB
2019-10-05 17:28:05 +00:00
2020-05-24 11:53:27 +00:00
TEX_Count
} ;
2019-10-05 17:28:05 +00:00
2020-05-24 11:53:27 +00:00
class FSoftwareTexture ;
2019-10-05 17:28:05 +00:00
class FGLRenderState ;
2020-05-24 11:53:27 +00:00
struct spriteframewithrotate ;
2019-10-05 17:28:05 +00:00
class FSerializer ;
namespace OpenGLRenderer
{
class FGLRenderState ;
2020-05-24 11:53:27 +00:00
class FHardwareTexture ;
2019-10-05 17:28:05 +00:00
}
union FContentIdBuilder
{
uint64_t id ;
struct
{
unsigned imageID : 24 ;
unsigned translation : 16 ;
unsigned expand : 1 ;
unsigned scaler : 4 ;
unsigned scalefactor : 4 ;
} ;
} ;
struct FTextureBuffer
{
uint8_t * mBuffer = nullptr ;
int mWidth = 0 ;
int mHeight = 0 ;
2020-05-24 11:53:27 +00:00
uint64_t mContentId = 0 ; // unique content identifier. (Two images created from the same image source with the same settings will return the same value.)
2019-10-05 17:28:05 +00:00
FTextureBuffer ( ) = default ;
~ FTextureBuffer ( )
{
if ( mBuffer ) delete [ ] mBuffer ;
}
FTextureBuffer ( const FTextureBuffer & other ) = delete ;
FTextureBuffer ( FTextureBuffer & & other )
{
mBuffer = other . mBuffer ;
mWidth = other . mWidth ;
mHeight = other . mHeight ;
2020-05-24 11:53:27 +00:00
mContentId = other . mContentId ;
2019-10-05 17:28:05 +00:00
other . mBuffer = nullptr ;
}
FTextureBuffer & operator = ( FTextureBuffer & & other )
{
mBuffer = other . mBuffer ;
mWidth = other . mWidth ;
mHeight = other . mHeight ;
2020-05-24 11:53:27 +00:00
mContentId = other . mContentId ;
2019-10-05 17:28:05 +00:00
other . mBuffer = nullptr ;
return * this ;
}
} ;
// Base texture class
class FTexture
{
2019-10-21 07:22:55 +00:00
friend struct BuildTiles ;
2019-10-14 21:11:01 +00:00
friend bool tileLoad ( int tileNum ) ;
friend const uint8_t * tilePtr ( int num ) ;
2019-10-05 17:28:05 +00:00
public :
2019-10-12 20:49:46 +00:00
enum UseType : uint8_t
{
2020-03-29 12:01:46 +00:00
Canvas , // camera texture
2019-10-12 20:49:46 +00:00
User // A texture with user-provided image content
} ;
2019-10-05 17:28:05 +00:00
static FTexture * CreateTexture ( const char * name ) ;
2019-10-05 19:59:03 +00:00
2019-10-05 17:28:05 +00:00
virtual ~ FTexture ( ) ;
virtual FImageSource * GetImage ( ) const { return nullptr ; }
const FString & GetName ( ) const { return Name ; }
bool isMasked ( ) const { return bMasked ; }
bool isTranslucent ( ) const { return bMasked ; }
PalEntry GetSkyCapColor ( bool bottom ) ;
// Returns the whole texture, stored in column-major order
2019-10-11 17:21:36 +00:00
virtual void Create8BitPixels ( uint8_t * buffer ) ;
virtual const uint8_t * Get8BitPixels ( ) ;
2019-10-12 06:54:06 +00:00
virtual uint8_t * GetWritableBuffer ( ) { return nullptr ; } // For dynamic tiles. Requesting this must also invalidate the texture.
2019-10-18 17:06:57 +00:00
virtual FBitmap GetBgraBitmap ( const PalEntry * remap , int * trans = nullptr ) ;
2019-10-05 17:28:05 +00:00
static int SmoothEdges ( unsigned char * buffer , int w , int h ) ;
static PalEntry averageColor ( const uint32_t * data , int size , int maxout ) ;
2019-10-12 20:49:46 +00:00
int GetWidth ( ) const { return Size . x ; }
int GetHeight ( ) const { return Size . y ; }
2020-05-23 22:38:10 +00:00
int GetTexelWidth ( ) const { return Size . x ; }
int GetTexelHeight ( ) const { return Size . y ; }
int GetDisplayWidth ( ) const { return Size . x ; }
int GetDisplayHeight ( ) const { return Size . y ; }
2019-10-14 21:11:01 +00:00
const vec2_16_t & GetSize ( ) const { return Size ; }
2020-05-24 10:31:38 +00:00
int GetLeftOffset ( ) const { return leftoffset ; }
int GetTopOffset ( ) const { return topoffset ; }
int GetDisplayLeftOffset ( ) const { return leftoffset ; }
int GetDisplayTopOffset ( ) const { return topoffset ; }
void SetOffsets ( int x , int y ) { leftoffset = x ; topoffset = y ; }
2019-10-18 17:06:57 +00:00
FTextureBuffer CreateTexBuffer ( const PalEntry * palette , int flags = 0 ) ;
2019-10-05 17:28:05 +00:00
bool GetTranslucency ( ) ;
void CheckTrans ( unsigned char * buffer , int size , int trans ) ;
bool ProcessData ( unsigned char * buffer , int w , int h , bool ispatch ) ;
2019-10-12 20:49:46 +00:00
virtual void Reload ( ) { }
2019-10-14 21:11:01 +00:00
UseType GetUseType ( ) const { return useType ; }
2019-10-18 09:37:07 +00:00
void DeleteHardwareTextures ( ) ;
2019-10-14 21:11:01 +00:00
2019-10-17 22:20:27 +00:00
void SetHardwareTexture ( int palid , FHardwareTexture * htex )
{
HardwareTextures . Insert ( palid , htex ) ;
}
2019-10-18 09:37:07 +00:00
FHardwareTexture * * GetHardwareTexture ( int palid )
2019-10-17 22:20:27 +00:00
{
2019-10-18 09:37:07 +00:00
return HardwareTextures . CheckKey ( palid ) ;
2019-10-17 22:20:27 +00:00
}
2019-10-14 21:11:01 +00:00
int alphaThreshold = 128 ;
2019-11-10 18:42:26 +00:00
FixedBitArray < 256 > NoBrightmapFlag { 0 } ;
2019-10-05 17:28:05 +00:00
protected :
void CopySize ( FTexture * BaseTexture )
{
2019-10-12 06:54:06 +00:00
Size . x = BaseTexture - > GetWidth ( ) ;
Size . y = BaseTexture - > GetHeight ( ) ;
2020-05-24 10:31:38 +00:00
leftoffset = BaseTexture - > leftoffset ;
topoffset = BaseTexture - > topoffset ;
2019-10-05 17:28:05 +00:00
}
2019-10-12 06:54:06 +00:00
void SetSize ( int w , int h )
{
Size = { int16_t ( w ) , int16_t ( h ) } ;
2019-10-12 20:49:46 +00:00
}
2019-10-05 17:28:05 +00:00
FString Name ;
2020-05-23 22:38:10 +00:00
union
{
vec2_16_t Size = { 0 , 0 } ; // Keep this in the native format so that we can use it without copying it around.
struct { uint16_t Width , Height ; } ;
} ;
2020-05-24 10:31:38 +00:00
int leftoffset = 0 , topoffset = 0 ;
2019-10-05 17:28:05 +00:00
uint8_t bMasked = true ; // Texture (might) have holes
int8_t bTranslucent = - 1 ; // Does this texture have an active alpha channel?
bool skyColorDone = false ;
2020-05-24 13:02:20 +00:00
UseType useType = User ;
2019-10-05 17:28:05 +00:00
PalEntry FloorSkyColor ;
PalEntry CeilingSkyColor ;
2019-10-20 23:01:38 +00:00
TArray < uint8_t > CachedPixels ;
2019-10-17 22:20:27 +00:00
// Don't waste too much effort on efficient storage here. Polymost performs so many calculations on a single draw call that the minor map lookup hardly matters.
TMap < int , FHardwareTexture * > HardwareTextures ; // Note: These must be deleted by the backend. When the texture manager is taken down it may already be too late to delete them.
2019-10-05 17:28:05 +00:00
FTexture ( const char * name = NULL ) ;
2019-10-21 07:22:55 +00:00
friend struct BuildTiles ;
2019-10-05 19:59:03 +00:00
} ;
2019-10-05 17:28:05 +00:00
2020-03-29 12:01:46 +00:00
class FCanvasTexture : public FTexture
{
public :
FCanvasTexture ( const char * name , int width , int height )
{
Name = name ;
Size . x = width ;
Size . y = height ;
bMasked = false ;
bTranslucent = false ;
//bNoExpand = true;
useType = FTexture : : Canvas ;
}
void NeedUpdate ( ) { bNeedsUpdate = true ; }
void SetUpdated ( bool rendertype ) { bNeedsUpdate = false ; bFirstUpdate = false ; bLastUpdateType = rendertype ; }
protected :
bool bLastUpdateType = false ;
bool bNeedsUpdate = true ;
public :
bool bFirstUpdate = true ;
friend struct FCanvasTextureInfo ;
} ;
2019-10-18 09:37:07 +00:00
2019-10-05 17:28:05 +00:00
# endif