2017-04-17 10:27:19 +00:00
/*
* * textures . h
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2005 - 2016 Randy Heit
* * Copyright 2005 - 2016 Christoph Oelckers
* * 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 .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
*/
2016-03-01 15:47:10 +00:00
# ifndef __TEXTURES_H
# define __TEXTURES_H
2016-03-30 14:30:22 +00:00
# include "doomtype.h"
2016-03-26 12:37:44 +00:00
# include "vectors.h"
2018-03-21 23:29:01 +00:00
# include "v_palette.h"
2018-03-28 14:40:09 +00:00
# include "v_colortables.h"
2018-03-21 23:29:01 +00:00
# include "colormatcher.h"
2018-03-18 11:36:14 +00:00
# include "r_data/renderstyle.h"
2018-03-21 23:29:01 +00:00
# include "r_data/r_translate.h"
2016-06-10 11:50:34 +00:00
# include <vector>
2016-03-01 15:47:10 +00:00
2018-07-04 18:36:33 +00:00
// 15 because 0th texture is our texture
# define MAX_CUSTOM_HW_SHADER_TEXTURES 15
2018-04-24 20:37:52 +00:00
typedef TMap < int , bool > SpriteHits ;
2018-04-02 10:28:20 +00:00
enum MaterialShaderIndex
{
SHADER_Default ,
SHADER_Warp1 ,
SHADER_Warp2 ,
SHADER_Brightmap ,
SHADER_Specular ,
SHADER_SpecularBrightmap ,
SHADER_PBR ,
SHADER_PBRBrightmap ,
2018-04-07 10:17:23 +00:00
SHADER_Paletted ,
2018-04-02 10:28:20 +00:00
SHADER_NoTexture ,
SHADER_BasicFuzz ,
SHADER_SmoothFuzz ,
SHADER_SwirlyFuzz ,
SHADER_TranslucentFuzz ,
SHADER_JaggedFuzz ,
SHADER_NoiseFuzz ,
SHADER_SmoothNoiseFuzz ,
SHADER_SoftwareFuzz ,
FIRST_USER_SHADER
} ;
2018-07-15 21:01:40 +00:00
struct UserShaderDesc
{
FString shader ;
MaterialShaderIndex shaderType ;
FString defines ;
2018-10-31 14:56:20 +00:00
bool disablealphatest = false ;
2018-07-15 21:01:40 +00:00
} ;
2018-04-02 10:28:20 +00:00
2018-10-31 14:56:20 +00:00
extern TArray < UserShaderDesc > usershaders ;
2016-03-01 17:50:45 +00:00
struct FloatRect
{
float left , top ;
float width , height ;
void Offset ( float xofs , float yofs )
{
left + = xofs ;
top + = yofs ;
}
void Scale ( float xfac , float yfac )
{
left * = xfac ;
width * = xfac ;
top * = yfac ;
height * = yfac ;
}
} ;
2018-04-01 12:38:48 +00:00
enum ECreateTexBufferFlags
{
2018-04-24 18:41:52 +00:00
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.
2018-04-01 12:38:48 +00:00
} ;
2016-03-01 17:50:45 +00:00
2016-03-01 15:47:10 +00:00
class FBitmap ;
struct FRemapTable ;
struct FCopyInfo ;
class FScanner ;
// Texture IDs
class FTextureManager ;
class FTerrainTypeArray ;
2018-04-24 21:06:34 +00:00
class IHardwareTexture ;
2016-03-01 17:50:45 +00:00
class FMaterial ;
2018-03-31 08:37:46 +00:00
extern int r_spriteadjustSW , r_spriteadjustHW ;
2016-03-01 15:47:10 +00:00
class FNullTextureID : public FTextureID
{
public :
FNullTextureID ( ) : FTextureID ( 0 ) { }
} ;
//
// Animating textures and planes
//
// [RH] Expanded to work with a Hexen ANIMDEFS lump
//
struct FAnimDef
{
FTextureID BasePic ;
2017-03-09 18:54:41 +00:00
uint16_t NumFrames ;
uint16_t CurFrame ;
uint8_t AnimType ;
2016-03-01 15:47:10 +00:00
bool bDiscrete ; // taken out of AnimType to have better control
2017-11-16 01:33:08 +00:00
uint64_t SwitchTime ; // Time to advance to next frame
2016-03-01 15:47:10 +00:00
struct FAnimFrame
{
2017-03-09 19:19:55 +00:00
uint32_t SpeedMin ; // Speeds are in ms, not tics
uint32_t SpeedRange ;
2016-03-01 15:47:10 +00:00
FTextureID FramePic ;
} Frames [ 1 ] ;
enum
{
ANIM_Forward ,
ANIM_Backward ,
ANIM_OscillateUp ,
ANIM_OscillateDown ,
ANIM_Random
} ;
2017-11-16 01:33:08 +00:00
void SetSwitchTime ( uint64_t mstime ) ;
2016-03-01 15:47:10 +00:00
} ;
struct FSwitchDef
{
FTextureID PreTexture ; // texture to switch from
FSwitchDef * PairDef ; // switch def to use to return to PreTexture
2017-03-09 18:54:41 +00:00
uint16_t NumFrames ; // # of animation frames
2016-03-01 15:47:10 +00:00
bool QuestPanel ; // Special texture for Strife mission
int Sound ; // sound to play at start of animation. Changed to int to avoiud having to include s_sound here.
struct frame // Array of times followed by array of textures
{ // actual length of each array is <NumFrames>
2017-03-09 18:54:41 +00:00
uint16_t TimeMin ;
uint16_t TimeRnd ;
2016-03-01 15:47:10 +00:00
FTextureID Texture ;
} frames [ 1 ] ;
} ;
struct FDoorAnimation
{
FTextureID BaseTexture ;
FTextureID * TextureFrames ;
int NumTextureFrames ;
FName OpenSound ;
FName CloseSound ;
} ;
// Patches.
// A patch holds one or more columns.
// Patches are used for sprites and all masked pictures, and we compose
// textures from the TEXTURE1/2 lists of patches.
struct patch_t
{
2017-03-09 18:31:45 +00:00
int16_t width ; // bounding box size
int16_t height ;
int16_t leftoffset ; // pixels to the left of origin
int16_t topoffset ; // pixels below the origin
2017-03-09 19:19:55 +00:00
uint32_t columnofs [ ] ; // only [width] used
2016-03-01 15:47:10 +00:00
// the [0] is &columnofs[width]
} ;
// All FTextures present their data to the world in 8-bit format, but if
// the source data is something else, this is it.
2018-03-24 07:40:24 +00:00
enum FTextureFormat : uint32_t
2016-03-01 15:47:10 +00:00
{
TEX_Pal ,
TEX_Gray ,
TEX_RGB , // Actually ARGB
2018-03-16 20:50:22 +00:00
2018-03-23 22:04:30 +00:00
TEX_Count
2016-03-01 15:47:10 +00:00
} ;
2018-12-06 00:11:04 +00:00
class FSoftwareTexture ;
class FGLRenderState ;
struct spriteframewithrotate ;
class FSerializer ;
2018-12-06 19:12:15 +00:00
namespace OpenGLRenderer
{
class FGLRenderState ;
class FHardwareTexture ;
}
2018-11-17 17:24:14 +00:00
2016-03-01 15:47:10 +00:00
// Base texture class
class FTexture
{
2018-12-06 00:11:04 +00:00
// This is initialization code that is allowed to have full access.
friend void R_InitSpriteDefs ( ) ;
friend void R_InstallSprite ( int num , spriteframewithrotate * sprtemp , int & maxframe ) ;
friend class GLDefsParser ;
// The serializer also needs access to more specific info that shouldn't be accessible through the interface.
friend FSerializer & Serialize ( FSerializer & arc , const char * key , FTextureID & value , FTextureID * defval ) ;
// For now only give access to classes which cannot be reworked yet. None of these should remain here when all is done.
friend class FSoftwareTexture ;
friend class FWarpTexture ;
friend class FMaterial ;
2018-12-06 19:12:15 +00:00
friend class OpenGLRenderer : : FGLRenderState ; // For now this needs access to some fields in ApplyMaterial. This should be rerouted through the Material class
2018-12-06 00:11:04 +00:00
friend struct FTexCoordInfo ;
2018-12-06 19:12:15 +00:00
friend class OpenGLRenderer : : FHardwareTexture ;
2018-12-06 00:11:04 +00:00
friend class FMultiPatchTexture ;
friend class FSkyBox ;
2018-12-06 19:12:15 +00:00
friend class FBrightmapTexture ;
friend class FFontChar1 ;
2018-12-06 00:11:04 +00:00
friend void RecordTextureColors ( FTexture * pic , uint8_t * usedcolors ) ;
2018-04-01 08:41:04 +00:00
2016-03-01 15:47:10 +00:00
public :
2018-03-25 18:26:16 +00:00
static FTexture * CreateTexture ( const char * name , int lumpnum , ETextureType usetype ) ;
static FTexture * CreateTexture ( int lumpnum , ETextureType usetype ) ;
2016-03-01 15:47:10 +00:00
virtual ~ FTexture ( ) ;
2018-03-31 17:20:59 +00:00
void AddAutoMaterials ( ) ;
2018-04-01 08:41:04 +00:00
unsigned char * CreateUpsampledTextureBuffer ( unsigned char * inputBuffer , const int inWidth , const int inHeight , int & outWidth , int & outHeight , bool hasAlpha ) ;
2016-03-01 15:47:10 +00:00
2018-12-06 00:11:04 +00:00
// These should only be used in places where the texture scaling must be ignored and absolutely nowhere else!
// Preferably all code depending on the physical texture size should be rewritten, unless it is part of the software rasterizer.
//int GetPixelWidth() { return GetWidth(); }
//int GetPixelHeight() { return GetHeight(); }
// These are mainly meant for 2D code which only needs logical information about the texture to position it properly.
int GetDisplayWidth ( ) { return GetScaledWidth ( ) ; }
int GetDisplayHeight ( ) { return GetScaledHeight ( ) ; }
double GetDisplayWidthDouble ( ) { return GetScaledWidthDouble ( ) ; }
double GetDisplayHeightDouble ( ) { return GetScaledHeightDouble ( ) ; }
int GetDisplayLeftOffset ( ) { return GetScaledLeftOffset ( 0 ) ; }
int GetDisplayTopOffset ( ) { return GetScaledTopOffset ( 0 ) ; }
double GetDisplayLeftOffsetDouble ( ) { return GetScaledLeftOffsetDouble ( 0 ) ; }
double GetDisplayTopOffsetDouble ( ) { return GetScaledTopOffsetDouble ( 0 ) ; }
bool isValid ( ) const { return UseType ! = ETextureType : : Null ; }
bool isSWCanvas ( ) const { return UseType = = ETextureType : : SWCanvas ; }
bool isSkybox ( ) const { return bSkybox ; }
bool isFullbrightDisabled ( ) const { return bDisableFullbright ; }
bool isHardwareCanvas ( ) const { return bHasCanvas ; } // There's two here so that this can deal with software canvases in the hardware renderer later.
bool isCanvas ( ) const { return bHasCanvas ; }
2018-12-06 19:12:15 +00:00
bool isMiscPatch ( ) const { return UseType = = ETextureType : : MiscPatch ; } // only used by the intermission screen to decide whether to tile the background image or not.
2018-12-06 00:11:04 +00:00
int isWarped ( ) const { return bWarped ; }
int GetRotations ( ) const { return Rotations ; }
void SetRotations ( int rot ) { Rotations = int16_t ( rot ) ; }
const FString & GetName ( ) const { return Name ; }
bool allowNoDecals ( ) const { return bNoDecals ; }
bool isScaled ( ) const { return Scale . X ! = 1 | | Scale . Y ! = 1 ; }
2018-12-06 19:12:15 +00:00
bool isMasked ( ) const { return bMasked ; }
2018-12-06 00:11:04 +00:00
int GetSkyOffset ( ) const { return SkyOffset ; }
FTextureID GetID ( ) const { return id ; }
PalEntry GetSkyCapColor ( bool bottom ) ;
virtual FTexture * GetRawTexture ( ) ; // for FMultiPatchTexture to override
2018-12-06 19:12:15 +00:00
virtual int GetSourceLump ( ) { return SourceLump ; } // needed by the scripted GetName method.
2018-12-06 00:11:04 +00:00
void GetGlowColor ( float * data ) ;
bool isGlowing ( ) const { return bGlowing ; }
bool isAutoGlowing ( ) const { return bAutoGlowing ; }
int GetGlowHeight ( ) const { return GlowHeight ; }
bool isFullbright ( ) const { return bFullbright ; }
void CreateDefaultBrightmap ( ) ;
bool FindHoles ( const unsigned char * buffer , int w , int h ) ;
public :
static void FlipSquareBlock ( uint8_t * block , int x , int y ) ;
static void FlipSquareBlockBgra ( uint32_t * block , int x , int y ) ;
static void FlipSquareBlockRemap ( uint8_t * block , int x , int y , const uint8_t * remap ) ;
static void FlipNonSquareBlock ( uint8_t * blockto , const uint8_t * blockfrom , int x , int y , int srcpitch ) ;
static void FlipNonSquareBlockBgra ( uint32_t * blockto , const uint32_t * blockfrom , int x , int y , int srcpitch ) ;
static void FlipNonSquareBlockRemap ( uint8_t * blockto , const uint8_t * blockfrom , int x , int y , int srcpitch , const uint8_t * remap ) ;
static bool SmoothEdges ( unsigned char * buffer , int w , int h ) ;
static PalEntry averageColor ( const uint32_t * data , int size , int maxout ) ;
FSoftwareTexture * GetSoftwareTexture ( ) ;
protected :
2018-03-31 08:37:46 +00:00
//int16_t LeftOffset, TopOffset;
2016-03-01 15:47:10 +00:00
2017-03-09 18:54:41 +00:00
uint8_t WidthBits , HeightBits ;
2016-03-01 15:47:10 +00:00
2016-03-26 12:37:44 +00:00
DVector2 Scale ;
2016-03-01 15:47:10 +00:00
int SourceLump ;
FTextureID id ;
2018-04-24 21:51:19 +00:00
FMaterial * Material [ 2 ] = { nullptr , nullptr } ;
IHardwareTexture * SystemTexture [ 2 ] = { nullptr , nullptr } ;
2018-12-06 19:12:15 +00:00
FSoftwareTexture * SoftwareTexture = nullptr ;
2018-04-24 21:51:19 +00:00
2018-03-31 17:20:59 +00:00
// None of the following pointers are owned by this texture, they are all controlled by the texture manager.
// Paletted variant
FTexture * PalVersion = nullptr ;
2018-04-01 08:41:04 +00:00
// External hires texture
FTexture * HiresTexture = nullptr ;
2018-03-31 17:20:59 +00:00
// Material layers
2018-03-31 10:27:41 +00:00
FTexture * Brightmap = nullptr ;
FTexture * Normal = nullptr ; // Normal map texture
FTexture * Specular = nullptr ; // Specular light texture for the diffuse+normal+specular light model
FTexture * Metallic = nullptr ; // Metalness texture for the physically based rendering (PBR) light model
FTexture * Roughness = nullptr ; // Roughness texture for PBR
FTexture * AmbientOcclusion = nullptr ; // Ambient occlusion texture for PBR
2018-07-04 18:36:33 +00:00
FTexture * CustomShaderTextures [ MAX_CUSTOM_HW_SHADER_TEXTURES ] = { nullptr } ; // Custom texture maps for custom hardware shaders
2018-03-31 10:27:41 +00:00
2016-03-01 15:47:10 +00:00
FString Name ;
2018-03-25 18:26:16 +00:00
ETextureType UseType ; // This texture's primary purpose
2017-03-09 18:54:41 +00:00
uint8_t bNoDecals : 1 ; // Decals should not stick to texture
uint8_t bNoRemap0 : 1 ; // Do not remap color 0 (used by front layer of parallax skies)
uint8_t bWorldPanning : 1 ; // Texture is panned in world units rather than texels
uint8_t bMasked : 1 ; // Texture (might) have holes
uint8_t bAlphaTexture : 1 ; // Texture is an alpha channel without color information
uint8_t bHasCanvas : 1 ; // Texture is based off FCanvasTexture
uint8_t bWarped : 2 ; // This is a warped texture. Used to avoid multiple warps on one texture
uint8_t bComplex : 1 ; // Will be used to mark extended MultipatchTextures that have to be
2016-03-01 15:47:10 +00:00
// fully composited before subjected to any kind of postprocessing instead of
// doing it per patch.
2018-11-01 09:51:57 +00:00
uint8_t bMultiPatch : 2 ; // This is a multipatch texture (we really could use real type info for textures...)
2017-03-09 18:54:41 +00:00
uint8_t bKeepAround : 1 ; // This texture was used as part of a multi-patch texture. Do not free it.
2018-03-31 17:20:59 +00:00
uint8_t bFullNameTexture : 1 ;
uint8_t bBrightmapChecked : 1 ; // Set to 1 if brightmap has been checked
uint8_t bGlowing : 1 ; // Texture glow color
2018-04-02 11:00:33 +00:00
uint8_t bAutoGlowing : 1 ; // Glow info is determined from texture image.
uint8_t bFullbright : 1 ; // always draw fullbright
uint8_t bDisableFullbright : 1 ; // This texture will not be displayed as fullbright sprite
uint8_t bSkybox : 1 ; // is a cubic skybox
uint8_t bNoCompress : 1 ;
2018-04-24 21:51:19 +00:00
uint8_t bNoExpand : 1 ;
2018-03-31 17:20:59 +00:00
int8_t bTranslucent : 2 ;
2018-04-01 08:41:04 +00:00
bool bHiresHasColorKey = false ; // Support for old color-keyed Doomsday textures
2016-03-01 15:47:10 +00:00
2017-03-09 18:54:41 +00:00
uint16_t Rotations ;
2017-03-09 18:31:45 +00:00
int16_t SkyOffset ;
2018-03-31 17:20:59 +00:00
FloatRect * areas = nullptr ;
int areacount = 0 ;
2018-04-02 11:00:33 +00:00
int GlowHeight = 128 ;
2018-03-31 17:20:59 +00:00
PalEntry GlowColor = 0 ;
2018-04-01 08:41:04 +00:00
int HiresLump = - 1 ; // For external hires textures.
2018-04-02 11:00:33 +00:00
float Glossiness = 10.f ;
float SpecularLevel = 0.1f ;
float shaderspeed = 1.f ;
int shaderindex = 0 ;
2016-03-01 15:47:10 +00:00
// Returns the whole texture, stored in column-major order
2018-04-08 19:19:57 +00:00
virtual const uint8_t * GetPixels ( FRenderStyle style ) ;
2016-06-10 11:50:34 +00:00
2016-06-25 08:33:35 +00:00
// Returns true if GetPixelsBgra includes mipmaps
virtual bool Mipmapped ( ) { return true ; }
2016-03-01 15:47:10 +00:00
virtual int CopyTrueColorPixels ( FBitmap * bmp , int x , int y , int rotate = 0 , FCopyInfo * inf = NULL ) ;
2018-04-24 19:58:26 +00:00
virtual int CopyTrueColorTranslated ( FBitmap * bmp , int x , int y , int rotate , PalEntry * remap , FCopyInfo * inf = NULL ) ;
2016-03-01 15:47:10 +00:00
virtual bool UseBasePalette ( ) ;
2018-04-24 19:58:26 +00:00
virtual FTexture * GetRedirect ( ) ;
2016-03-01 15:47:10 +00:00
2016-06-13 19:39:55 +00:00
virtual void Unload ( ) ;
2016-03-01 15:47:10 +00:00
// Returns the native pixel format for this image
virtual FTextureFormat GetFormat ( ) ;
// Fill the native texture buffer with pixel data for this image
2017-03-09 18:54:41 +00:00
virtual void FillBuffer ( uint8_t * buff , int pitch , int height , FTextureFormat fmt ) ;
2016-03-01 15:47:10 +00:00
int GetWidth ( ) { return Width ; }
int GetHeight ( ) { return Height ; }
2016-03-26 12:37:44 +00:00
int GetScaledWidth ( ) { int foo = int ( ( Width * 2 ) / Scale . X ) ; return ( foo > > 1 ) + ( foo & 1 ) ; }
int GetScaledHeight ( ) { int foo = int ( ( Height * 2 ) / Scale . Y ) ; return ( foo > > 1 ) + ( foo & 1 ) ; }
double GetScaledWidthDouble ( ) { return Width / Scale . X ; }
double GetScaledHeightDouble ( ) { return Height / Scale . Y ; }
double GetScaleY ( ) const { return Scale . Y ; }
2016-03-01 15:47:10 +00:00
2018-03-31 08:37:46 +00:00
// Now with improved offset adjustment.
int GetLeftOffset ( int adjusted ) { return _LeftOffset [ adjusted ] ; }
int GetTopOffset ( int adjusted ) { return _TopOffset [ adjusted ] ; }
int GetScaledLeftOffset ( int adjusted ) { int foo = int ( ( _LeftOffset [ adjusted ] * 2 ) / Scale . X ) ; return ( foo > > 1 ) + ( foo & 1 ) ; }
int GetScaledTopOffset ( int adjusted ) { int foo = int ( ( _TopOffset [ adjusted ] * 2 ) / Scale . Y ) ; return ( foo > > 1 ) + ( foo & 1 ) ; }
double GetScaledLeftOffsetDouble ( int adjusted ) { return _LeftOffset [ adjusted ] / Scale . X ; }
double GetScaledTopOffsetDouble ( int adjusted ) { return _TopOffset [ adjusted ] / Scale . Y ; }
// Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets
// should use these, so that if changes are needed, this is the only place to edit.
// For the original software renderer
int GetLeftOffsetSW ( ) { return _LeftOffset [ r_spriteadjustSW ] ; }
int GetTopOffsetSW ( ) { return _TopOffset [ r_spriteadjustSW ] ; }
int GetScaledLeftOffsetSW ( ) { return GetScaledLeftOffset ( r_spriteadjustSW ) ; }
int GetScaledTopOffsetSW ( ) { return GetScaledTopOffset ( r_spriteadjustSW ) ; }
// For the softpoly renderer, in case it wants adjustment
int GetLeftOffsetPo ( ) { return _LeftOffset [ r_spriteadjustSW ] ; }
int GetTopOffsetPo ( ) { return _TopOffset [ r_spriteadjustSW ] ; }
int GetScaledLeftOffsetPo ( ) { return GetScaledLeftOffset ( r_spriteadjustSW ) ; }
int GetScaledTopOffsetPo ( ) { return GetScaledTopOffset ( r_spriteadjustSW ) ; }
// For the hardware renderer
int GetLeftOffsetHW ( ) { return _LeftOffset [ r_spriteadjustHW ] ; }
int GetTopOffsetHW ( ) { return _TopOffset [ r_spriteadjustHW ] ; }
2016-10-24 21:35:18 +00:00
virtual void ResolvePatches ( ) { }
2016-03-01 15:47:10 +00:00
virtual void SetFrontSkyLayer ( ) ;
2018-03-18 11:36:14 +00:00
void CopyToBlock ( uint8_t * dest , int dwidth , int dheight , int x , int y , int rotate , const uint8_t * translation , FRenderStyle style ) ;
2016-03-01 15:47:10 +00:00
// Returns true if the next call to GetPixels() will return an image different from the
// last call to GetPixels(). This should be considered valid only if a call to CheckModified()
// is immediately followed by a call to GetPixels().
2018-03-18 20:33:44 +00:00
virtual bool CheckModified ( FRenderStyle style ) ;
2016-03-01 15:47:10 +00:00
static void InitGrayMap ( ) ;
void CopySize ( FTexture * BaseTexture )
{
Width = BaseTexture - > GetWidth ( ) ;
Height = BaseTexture - > GetHeight ( ) ;
2018-03-31 08:37:46 +00:00
_TopOffset [ 0 ] = BaseTexture - > _TopOffset [ 0 ] ;
_TopOffset [ 1 ] = BaseTexture - > _TopOffset [ 1 ] ;
_LeftOffset [ 0 ] = BaseTexture - > _LeftOffset [ 0 ] ;
_LeftOffset [ 1 ] = BaseTexture - > _LeftOffset [ 1 ] ;
2016-03-01 15:47:10 +00:00
WidthBits = BaseTexture - > WidthBits ;
HeightBits = BaseTexture - > HeightBits ;
2016-03-26 12:37:44 +00:00
Scale = BaseTexture - > Scale ;
2016-03-01 15:47:10 +00:00
WidthMask = ( 1 < < WidthBits ) - 1 ;
}
void SetScaledSize ( int fitwidth , int fitheight ) ;
protected :
2017-03-09 18:54:41 +00:00
uint16_t Width , Height , WidthMask ;
2018-03-31 08:37:46 +00:00
int16_t _LeftOffset [ 2 ] , _TopOffset [ 2 ] ;
2017-03-09 18:54:41 +00:00
static uint8_t GrayMap [ 256 ] ;
2018-03-21 23:29:01 +00:00
uint8_t * GetRemap ( FRenderStyle style , bool srcisgrayscale = false )
{
if ( style . Flags & STYLEF_RedIsAlpha )
{
return translationtables [ TRANSLATION_Standard ] [ srcisgrayscale ? STD_Gray : STD_Grayscale ] - > Remap ;
}
else
{
return srcisgrayscale ? GrayMap : GPalette . Remap ;
}
}
uint8_t RGBToPalettePrecise ( bool wantluminance , int r , int g , int b , int a = 255 )
{
if ( wantluminance )
{
return ( uint8_t ) Luminance ( r , g , b ) * a / 255 ;
}
else
{
return ColorMatcher . Pick ( r , g , b ) ;
}
}
uint8_t RGBToPalette ( bool wantluminance , int r , int g , int b , int a = 255 )
{
if ( wantluminance )
{
// This is the same formula the OpenGL renderer uses for grayscale textures with an alpha channel.
return ( uint8_t ) ( Luminance ( r , g , b ) * a / 255 ) ;
}
else
{
return a < 128 ? 0 : RGB256k . RGB [ r > > 2 ] [ g > > 2 ] [ b > > 2 ] ;
}
}
uint8_t RGBToPalette ( bool wantluminance , PalEntry pe , bool hasalpha = true )
{
return RGBToPalette ( wantluminance , pe . r , pe . g , pe . b , hasalpha ? pe . a : 255 ) ;
}
uint8_t RGBToPalette ( FRenderStyle style , int r , int g , int b , int a = 255 )
{
return RGBToPalette ( ! ! ( style . Flags & STYLEF_RedIsAlpha ) , r , g , b , a ) ;
}
2016-03-01 15:47:10 +00:00
FTexture ( const char * name = NULL , int lumpnum = - 1 ) ;
void CalcBitSize ( ) ;
void CopyInfo ( FTexture * other )
{
CopySize ( other ) ;
bNoDecals = other - > bNoDecals ;
Rotations = other - > Rotations ;
}
2016-06-21 19:55:08 +00:00
2018-04-01 08:41:04 +00:00
public :
2018-04-01 12:38:48 +00:00
unsigned char * CreateTexBuffer ( int translation , int & w , int & h , int flags = 0 ) ;
bool GetTranslucency ( ) ;
2016-10-19 21:52:09 +00:00
private :
2018-04-01 08:41:04 +00:00
int CheckDDPK3 ( ) ;
int CheckExternalFile ( bool & hascolorkey ) ;
2018-04-01 12:38:48 +00:00
unsigned char * LoadHiresTexture ( int * width , int * height ) ;
2018-04-01 08:41:04 +00:00
2016-10-19 21:52:09 +00:00
bool bSWSkyColorDone = false ;
2016-10-20 07:08:07 +00:00
PalEntry FloorSkyColor ;
PalEntry CeilingSkyColor ;
2016-10-19 21:52:09 +00:00
2016-03-01 15:47:10 +00:00
public :
2016-03-01 17:50:45 +00:00
void CheckTrans ( unsigned char * buffer , int size , int trans ) ;
bool ProcessData ( unsigned char * buffer , int w , int h , bool ispatch ) ;
2017-03-17 22:08:22 +00:00
int CheckRealHeight ( ) ;
2018-03-31 08:37:46 +00:00
void SetSpriteAdjust ( ) ;
friend class FTextureManager ;
2016-03-01 17:50:45 +00:00
} ;
2016-03-01 15:47:10 +00:00
2018-12-06 00:11:04 +00:00
2017-01-15 22:21:38 +00:00
class FxAddSub ;
2016-03-01 15:47:10 +00:00
// Texture manager
class FTextureManager
{
2017-01-15 22:21:38 +00:00
friend class FxAddSub ; // needs access to do a bounds check on the texture ID.
2016-03-01 15:47:10 +00:00
public :
FTextureManager ( ) ;
~ FTextureManager ( ) ;
// Get texture without translation
2018-03-25 18:26:16 +00:00
//private:
2016-03-01 15:47:10 +00:00
FTexture * operator [ ] ( FTextureID texnum )
{
if ( ( unsigned ) texnum . GetIndex ( ) > = Textures . Size ( ) ) return NULL ;
return Textures [ texnum . GetIndex ( ) ] . Texture ;
}
FTexture * operator [ ] ( const char * texname )
{
2018-03-25 18:26:16 +00:00
FTextureID texnum = GetTexture ( texname , ETextureType : : MiscPatch ) ;
2016-03-01 15:47:10 +00:00
if ( ! texnum . Exists ( ) ) return NULL ;
return Textures [ texnum . GetIndex ( ) ] . Texture ;
}
FTexture * ByIndex ( int i )
{
if ( unsigned ( i ) > = Textures . Size ( ) ) return NULL ;
return Textures [ i ] . Texture ;
}
2018-03-25 18:26:16 +00:00
FTexture * FindTexture ( const char * texname , ETextureType usetype = ETextureType : : MiscPatch , BITFIELD flags = TEXMAN_TryAny ) ;
2016-03-01 15:47:10 +00:00
// Get texture with translation
FTexture * operator ( ) ( FTextureID texnum , bool withpalcheck = false )
{
if ( ( size_t ) texnum . texnum > = Textures . Size ( ) ) return NULL ;
int picnum = Translation [ texnum . texnum ] ;
if ( withpalcheck )
{
picnum = PalCheck ( picnum ) . GetIndex ( ) ;
}
return Textures [ picnum ] . Texture ;
}
FTexture * operator ( ) ( const char * texname )
{
2018-03-25 18:26:16 +00:00
FTextureID texnum = GetTexture ( texname , ETextureType : : MiscPatch ) ;
2016-03-01 15:47:10 +00:00
if ( texnum . texnum = = - 1 ) return NULL ;
return Textures [ Translation [ texnum . texnum ] ] . Texture ;
}
FTexture * ByIndexTranslated ( int i )
{
if ( unsigned ( i ) > = Textures . Size ( ) ) return NULL ;
return Textures [ Translation [ i ] ] . Texture ;
}
2018-03-25 18:26:16 +00:00
//public:
2016-03-01 15:47:10 +00:00
FTextureID PalCheck ( FTextureID tex ) ;
enum
{
TEXMAN_TryAny = 1 ,
TEXMAN_Overridable = 2 ,
TEXMAN_ReturnFirst = 4 ,
TEXMAN_AllowSkins = 8 ,
TEXMAN_ShortNameOnly = 16 ,
TEXMAN_DontCreate = 32
} ;
enum
{
HIT_Wall = 1 ,
HIT_Flat = 2 ,
HIT_Sky = 4 ,
HIT_Sprite = 8 ,
HIT_Columnmode = HIT_Wall | HIT_Sky | HIT_Sprite
} ;
2018-03-25 18:26:16 +00:00
FTextureID CheckForTexture ( const char * name , ETextureType usetype , BITFIELD flags = TEXMAN_TryAny ) ;
FTextureID GetTexture ( const char * name , ETextureType usetype , BITFIELD flags = 0 ) ;
2016-10-26 09:56:15 +00:00
int ListTextures ( const char * name , TArray < FTextureID > & list , bool listall = false ) ;
2016-03-01 15:47:10 +00:00
void AddTexturesLump ( const void * lumpdata , int lumpsize , int deflumpnum , int patcheslump , int firstdup = 0 , bool texture1 = false ) ;
void AddTexturesLumps ( int lump1 , int lump2 , int patcheslump ) ;
2018-03-25 18:26:16 +00:00
void AddGroup ( int wadnum , int ns , ETextureType usetype ) ;
2016-03-01 15:47:10 +00:00
void AddPatches ( int lumpnum ) ;
void AddHiresTextures ( int wadnum ) ;
void LoadTextureDefs ( int wadnum , const char * lumpname ) ;
2018-05-24 19:18:20 +00:00
void ParseTextureDef ( int remapLump ) ;
2018-03-25 18:26:16 +00:00
void ParseXTexture ( FScanner & sc , ETextureType usetype ) ;
2016-03-01 15:47:10 +00:00
void SortTexturesByType ( int start , int end ) ;
bool AreTexturesCompatible ( FTextureID picnum1 , FTextureID picnum2 ) ;
2018-03-25 18:26:16 +00:00
FTextureID CreateTexture ( int lumpnum , ETextureType usetype = ETextureType : : Any ) ; // Also calls AddTexture
2016-03-01 15:47:10 +00:00
FTextureID AddTexture ( FTexture * texture ) ;
FTextureID GetDefaultTexture ( ) const { return DefaultTexture ; }
void LoadTextureX ( int wadnum ) ;
void AddTexturesForWad ( int wadnum ) ;
void Init ( ) ;
void DeleteAll ( ) ;
2018-03-31 08:37:46 +00:00
void SpriteAdjustChanged ( ) ;
2016-03-01 15:47:10 +00:00
// Replaces one texture with another. The new texture will be assigned
// the same name, slot, and use type as the texture it is replacing.
// The old texture will no longer be managed. Set free true if you want
// the old texture to be deleted or set it false if you want it to
// be left alone in memory. You will still need to delete it at some
// point, because the texture manager no longer knows about it.
// This function can be used for such things as warping textures.
void ReplaceTexture ( FTextureID picnum , FTexture * newtexture , bool free ) ;
void UnloadAll ( ) ;
int NumTextures ( ) const { return ( int ) Textures . Size ( ) ; }
2017-11-16 01:33:08 +00:00
void UpdateAnimations ( uint64_t mstime ) ;
2016-03-01 15:47:10 +00:00
int GuesstimateNumTextures ( ) ;
FSwitchDef * FindSwitch ( FTextureID texture ) ;
FDoorAnimation * FindAnimatedDoor ( FTextureID picnum ) ;
private :
// texture counting
int CountTexturesX ( ) ;
int CountLumpTextures ( int lumpnum ) ;
2018-03-31 08:37:46 +00:00
void AdjustSpriteOffsets ( ) ;
2016-03-01 15:47:10 +00:00
// Build tiles
2018-03-19 19:02:38 +00:00
void AddTiles ( const FString & pathprefix , const void * , int translation ) ;
//int CountBuildTiles ();
2016-03-01 15:47:10 +00:00
void InitBuildTiles ( ) ;
// Animation stuff
FAnimDef * AddAnim ( FAnimDef * anim ) ;
void FixAnimations ( ) ;
void InitAnimated ( ) ;
void InitAnimDefs ( ) ;
2017-03-09 19:19:55 +00:00
FAnimDef * AddSimpleAnim ( FTextureID picnum , int animcount , uint32_t speedmin , uint32_t speedrange = 0 ) ;
2016-03-01 15:47:10 +00:00
FAnimDef * AddComplexAnim ( FTextureID picnum , const TArray < FAnimDef : : FAnimFrame > & frames ) ;
2018-03-25 18:26:16 +00:00
void ParseAnim ( FScanner & sc , ETextureType usetype ) ;
FAnimDef * ParseRangeAnim ( FScanner & sc , FTextureID picnum , ETextureType usetype , bool missing ) ;
void ParsePicAnim ( FScanner & sc , FTextureID picnum , ETextureType usetype , bool missing , TArray < FAnimDef : : FAnimFrame > & frames ) ;
2016-03-01 15:47:10 +00:00
void ParseWarp ( FScanner & sc ) ;
void ParseCameraTexture ( FScanner & sc ) ;
2018-03-25 18:26:16 +00:00
FTextureID ParseFramenum ( FScanner & sc , FTextureID basepicnum , ETextureType usetype , bool allowMissing ) ;
2017-03-09 19:19:55 +00:00
void ParseTime ( FScanner & sc , uint32_t & min , uint32_t & max ) ;
2016-03-01 15:47:10 +00:00
FTexture * Texture ( FTextureID id ) { return Textures [ id . GetIndex ( ) ] . Texture ; }
void SetTranslation ( FTextureID fromtexnum , FTextureID totexnum ) ;
void ParseAnimatedDoor ( FScanner & sc ) ;
void InitPalettedVersions ( ) ;
2018-03-31 17:20:59 +00:00
void GenerateGlobalBrightmapFromColormap ( ) ;
2016-03-01 15:47:10 +00:00
// Switches
void InitSwitchList ( ) ;
void ProcessSwitchDef ( FScanner & sc ) ;
FSwitchDef * ParseSwitchDef ( FScanner & sc , bool ignoreBad ) ;
void AddSwitchPair ( FSwitchDef * def1 , FSwitchDef * def2 ) ;
struct TextureHash
{
FTexture * Texture ;
int HashNext ;
} ;
enum { HASH_END = - 1 , HASH_SIZE = 1027 } ;
TArray < TextureHash > Textures ;
TArray < int > Translation ;
int HashFirst [ HASH_SIZE ] ;
FTextureID DefaultTexture ;
TArray < int > FirstTextureForFile ;
2018-03-19 19:02:38 +00:00
TArray < TArray < uint8_t > > BuildTileData ;
2016-03-01 15:47:10 +00:00
TArray < FAnimDef * > mAnimations ;
TArray < FSwitchDef * > mSwitchDefs ;
TArray < FDoorAnimation > mAnimatedDoors ;
2018-03-19 19:02:38 +00:00
2016-04-28 13:59:37 +00:00
public :
2018-03-31 17:20:59 +00:00
bool HasGlobalBrightmap ;
FRemapTable GlobalBrightmap ;
2016-04-28 13:59:37 +00:00
short sintable [ 2048 ] ; // for texture warping
enum
{
SINMASK = 2047
} ;
2018-04-28 22:09:44 +00:00
FTextureID glLight ;
FTextureID glPart2 ;
FTextureID glPart ;
FTextureID mirrorTexture ;
2016-03-01 15:47:10 +00:00
} ;
2018-03-18 11:36:14 +00:00
// base class for everything that can be used as a world texture.
// This intermediate class encapsulates the buffers for the software renderer.
class FWorldTexture : public FTexture
{
protected :
uint8_t * Pixeldata [ 2 ] = { nullptr , nullptr } ;
2018-03-18 11:54:40 +00:00
uint8_t PixelsAreStatic = 0 ; // can be set by subclasses which provide static pixel buffers.
2018-03-18 11:36:14 +00:00
FWorldTexture ( const char * name = nullptr , int lumpnum = - 1 ) ;
~ FWorldTexture ( ) ;
2018-03-18 20:33:44 +00:00
void Unload ( ) override ;
2018-12-06 23:04:39 +00:00
const uint8_t * GetPixels ( FRenderStyle style ) override ;
2018-03-18 11:36:14 +00:00
virtual uint8_t * MakeTexture ( FRenderStyle style ) = 0 ;
} ;
2016-03-01 15:47:10 +00:00
// A texture that doesn't really exist
2018-03-18 20:33:44 +00:00
class FDummyTexture : public FTexture
2016-03-01 15:47:10 +00:00
{
public :
FDummyTexture ( ) ;
void SetSize ( int width , int height ) ;
} ;
// A texture that returns a wiggly version of another texture.
2018-03-18 20:33:44 +00:00
class FWarpTexture : public FWorldTexture
2016-03-01 15:47:10 +00:00
{
public :
2016-04-30 10:36:55 +00:00
FWarpTexture ( FTexture * source , int warptype ) ;
2016-03-01 15:47:10 +00:00
~ FWarpTexture ( ) ;
2018-03-18 20:33:44 +00:00
void Unload ( ) override ;
2016-03-01 15:47:10 +00:00
2018-03-18 20:33:44 +00:00
virtual int CopyTrueColorPixels ( FBitmap * bmp , int x , int y , int rotate = 0 , FCopyInfo * inf = NULL ) override ;
2018-04-24 19:58:26 +00:00
virtual int CopyTrueColorTranslated ( FBitmap * bmp , int x , int y , int rotate , PalEntry * remap , FCopyInfo * inf = NULL ) override ;
2018-12-06 23:04:39 +00:00
//const uint32_t *GetPixelsBgra() override;
2018-03-18 20:33:44 +00:00
bool CheckModified ( FRenderStyle ) override ;
2016-03-01 15:47:10 +00:00
float GetSpeed ( ) const { return Speed ; }
int GetSourceLump ( ) { return SourcePic - > GetSourceLump ( ) ; }
void SetSpeed ( float fac ) { Speed = fac ; }
2018-03-18 20:33:44 +00:00
uint64_t GenTime [ 2 ] = { 0 , 0 } ;
uint64_t GenTimeBgra = 0 ;
float Speed = 1.f ;
2016-04-28 17:04:01 +00:00
int WidthOffsetMultiplier , HeightOffsetMultiplier ; // [mxd]
2016-03-01 15:47:10 +00:00
protected :
FTexture * SourcePic ;
2018-03-18 20:33:44 +00:00
uint8_t * MakeTexture ( FRenderStyle style ) override ;
2016-03-01 15:47:10 +00:00
int NextPo2 ( int v ) ; // [mxd]
void SetupMultipliers ( int width , int height ) ; // [mxd]
} ;
// A texture that can be drawn to.
2018-11-30 16:02:39 +00:00
class DCanvas ;
2016-03-01 15:47:10 +00:00
class AActor ;
class FCanvasTexture : public FTexture
{
public :
FCanvasTexture ( const char * name , int width , int height ) ;
~ FCanvasTexture ( ) ;
2018-12-06 23:04:39 +00:00
//const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
//const uint32_t *GetPixelsBgra() override;
2018-03-18 20:33:44 +00:00
const uint8_t * GetPixels ( FRenderStyle style ) ;
2016-03-01 15:47:10 +00:00
void Unload ( ) ;
2018-03-18 20:33:44 +00:00
bool CheckModified ( FRenderStyle ) override ;
2016-03-01 15:47:10 +00:00
void NeedUpdate ( ) { bNeedsUpdate = true ; }
void SetUpdated ( ) { bNeedsUpdate = false ; bDidUpdate = true ; bFirstUpdate = false ; }
2018-11-30 16:02:39 +00:00
DCanvas * GetCanvas ( ) { return Canvas ; }
DCanvas * GetCanvasBgra ( ) { return CanvasBgra ; }
2016-06-25 08:33:35 +00:00
bool Mipmapped ( ) override { return false ; }
2018-03-18 20:33:44 +00:00
void MakeTexture ( FRenderStyle style ) ;
2016-06-13 01:16:48 +00:00
void MakeTextureBgra ( ) ;
2016-03-01 15:47:10 +00:00
protected :
2018-11-30 16:02:39 +00:00
DCanvas * Canvas = nullptr ;
DCanvas * CanvasBgra = nullptr ;
2017-03-09 18:54:41 +00:00
uint8_t * Pixels = nullptr ;
2016-06-13 01:16:48 +00:00
uint32_t * PixelsBgra = nullptr ;
2018-12-06 23:04:39 +00:00
//FSoftwareTextureSpan DummySpans[2];
2016-06-13 01:16:48 +00:00
bool bNeedsUpdate = true ;
bool bDidUpdate = false ;
bool bPixelsAllocated = false ;
bool bPixelsAllocatedBgra = false ;
2016-03-01 15:47:10 +00:00
public :
bool bFirstUpdate ;
friend struct FCanvasTextureInfo ;
} ;
2018-10-29 06:39:33 +00:00
// A wrapper around a hardware texture, to allow using it in the 2D drawing interface.
class FWrapperTexture : public FTexture
{
public :
FWrapperTexture ( int w , int h , int bits = 1 ) ;
2018-12-06 00:11:04 +00:00
IHardwareTexture * GetSystemTexture ( int slot )
{
return SystemTexture [ slot ] ;
}
2018-12-06 19:12:15 +00:00
int GetColorFormat ( ) const
{
return WidthBits ;
}
2018-10-29 06:39:33 +00:00
} ;
2016-03-01 15:47:10 +00:00
extern FTextureManager TexMan ;
2018-11-17 17:24:14 +00:00
struct FTexCoordInfo
{
int mRenderWidth ;
int mRenderHeight ;
int mWidth ;
FVector2 mScale ;
FVector2 mTempScale ;
bool mWorldPanning ;
float FloatToTexU ( float v ) const { return v / mRenderWidth ; }
float FloatToTexV ( float v ) const { return v / mRenderHeight ; }
float RowOffset ( float ofs ) const ;
float TextureOffset ( float ofs ) const ;
float TextureAdjustWidth ( ) const ;
void GetFromTexture ( FTexture * tex , float x , float y ) ;
} ;
2016-03-01 15:47:10 +00:00
# endif