You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
441 lines
13 KiB
441 lines
13 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Local header for CVTFTexture class declaration - allows platform-specific |
|
// implementation to be placed in separate cpp files. |
|
// |
|
// $NoKeywords: $ |
|
//===========================================================================// |
|
|
|
#ifndef CVTF_H |
|
#define CVTF_H |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "s3tc_decode.h" |
|
#include "vtf/vtf.h" |
|
#include "byteswap.h" |
|
#include "filesystem.h" |
|
|
|
class CEdgePos |
|
{ |
|
public: |
|
CEdgePos() = default; |
|
CEdgePos( int ix, int iy ) |
|
{ |
|
x = ix; |
|
y = iy; |
|
} |
|
|
|
void operator +=( const CEdgePos &other ) |
|
{ |
|
x += other.x; |
|
y += other.y; |
|
} |
|
|
|
void operator /=( int val ) |
|
{ |
|
x /= val; |
|
y /= val; |
|
} |
|
|
|
CEdgePos operator >>( int shift ) |
|
{ |
|
return CEdgePos( x >> shift, y >> shift ); |
|
} |
|
|
|
CEdgePos operator *( int shift ) |
|
{ |
|
return CEdgePos( x * shift, y * shift ); |
|
} |
|
|
|
CEdgePos operator -( const CEdgePos &other ) |
|
{ |
|
return CEdgePos( x - other.x, y - other.y ); |
|
} |
|
|
|
CEdgePos operator +( const CEdgePos &other ) |
|
{ |
|
return CEdgePos( x + other.x, y + other.y ); |
|
} |
|
|
|
bool operator!=( const CEdgePos &other ) |
|
{ |
|
return !( *this == other ); |
|
} |
|
|
|
bool operator==( const CEdgePos &other ) |
|
{ |
|
return x==other.x && y==other.y; |
|
} |
|
|
|
int x, y; |
|
}; |
|
|
|
|
|
class CEdgeIncrements |
|
{ |
|
public: |
|
CEdgePos iFace1Start, iFace1End; |
|
CEdgePos iFace1Inc, iFace2Inc; |
|
CEdgePos iFace2Start, iFace2End; |
|
}; |
|
|
|
|
|
class CEdgeMatch |
|
{ |
|
public: |
|
int m_iFaces[2]; // Which faces are touching. |
|
int m_iEdges[2]; // Which edge on each face is touching. |
|
int m_iCubeVerts[2];// Which of the cube's verts comprise this edge? |
|
bool m_bFlipFace2Edge; |
|
}; |
|
|
|
|
|
class CCornerMatch |
|
{ |
|
public: |
|
// The info for the 3 edges that match at this corner. |
|
int m_iFaces[3]; |
|
int m_iFaceEdges[3]; |
|
}; |
|
|
|
|
|
class CEdgeFaceIndex |
|
{ |
|
public: |
|
int m_iEdge; |
|
int m_iFace; |
|
}; |
|
|
|
|
|
#define NUM_EDGE_MATCHES 12 |
|
#define NUM_CORNER_MATCHES 8 |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Implementation of the VTF Texture |
|
//----------------------------------------------------------------------------- |
|
class CVTFTexture : public IVTFTexture |
|
{ |
|
public: |
|
CVTFTexture(); |
|
virtual ~CVTFTexture(); |
|
|
|
virtual bool Init( int nWidth, int nHeight, int nDepth, ImageFormat fmt, int iFlags, int iFrameCount, int nForceMipCount ); |
|
|
|
// Methods to initialize the low-res image |
|
virtual void InitLowResImage( int nWidth, int nHeight, ImageFormat fmt ); |
|
|
|
virtual void *SetResourceData( uint32 eType, void const *pData, size_t nDataSize ); |
|
virtual void *GetResourceData( uint32 eType, size_t *pDataSize ) const; |
|
|
|
// Locates the resource entry info if it's present, easier than crawling array types |
|
virtual bool HasResourceEntry( uint32 eType ) const; |
|
|
|
// Retrieve available resource types of this IVTFTextures |
|
// arrTypesBuffer buffer to be filled with resource types available. |
|
// numTypesBufferElems how many resource types the buffer can accomodate. |
|
// Returns: |
|
// number of resource types available (can be greater than "numTypesBufferElems" |
|
// in which case only first "numTypesBufferElems" are copied to "arrTypesBuffer") |
|
virtual unsigned int GetResourceTypes( uint32 *arrTypesBuffer, int numTypesBufferElems ) const; |
|
|
|
// Methods to set other texture fields |
|
virtual void SetBumpScale( float flScale ); |
|
virtual void SetReflectivity( const Vector &vecReflectivity ); |
|
|
|
// These are methods to help with optimization of file access |
|
virtual void LowResFileInfo( int *pStartLocation, int *pSizeInBytes ) const; |
|
virtual void ImageFileInfo( int nFrame, int nFace, int nMip, int *pStartLocation, int *pSizeInBytes) const; |
|
virtual int FileSize( int nMipSkipCount = 0 ) const; |
|
|
|
// When unserializing, we can skip a certain number of mip levels, |
|
// and we also can just load everything but the image data |
|
virtual bool Unserialize( CUtlBuffer &buf, bool bBufferHeaderOnly = false, int nSkipMipLevels = 0 ); |
|
virtual bool UnserializeEx( CUtlBuffer &buf, bool bHeaderOnly = false, int nForceFlags = 0, int nSkipMipLevels = 0 ); |
|
virtual bool Serialize( CUtlBuffer &buf ); |
|
|
|
virtual void GetMipmapRange( int* pOutFinest, int* pOutCoarsest ); |
|
|
|
// Attributes... |
|
virtual int Width() const; |
|
virtual int Height() const; |
|
virtual int Depth() const; |
|
virtual int MipCount() const; |
|
|
|
virtual int RowSizeInBytes( int nMipLevel ) const; |
|
virtual int FaceSizeInBytes( int nMipLevel ) const; |
|
|
|
virtual ImageFormat Format() const; |
|
virtual int FaceCount() const; |
|
virtual int FrameCount() const; |
|
virtual int Flags() const; |
|
|
|
virtual float BumpScale() const; |
|
virtual const Vector &Reflectivity() const; |
|
|
|
virtual bool IsCubeMap() const; |
|
virtual bool IsNormalMap() const; |
|
virtual bool IsVolumeTexture() const; |
|
|
|
virtual int LowResWidth() const; |
|
virtual int LowResHeight() const; |
|
virtual ImageFormat LowResFormat() const; |
|
|
|
// Computes the size (in bytes) of a single mipmap of a single face of a single frame |
|
virtual int ComputeMipSize( int iMipLevel ) const; |
|
|
|
// Computes the size (in bytes) of a single face of a single frame |
|
// All mip levels starting at the specified mip level are included |
|
virtual int ComputeFaceSize( int iStartingMipLevel = 0 ) const; |
|
|
|
// Computes the total size of all faces, all frames |
|
virtual int ComputeTotalSize( ) const; |
|
|
|
// Computes the dimensions of a particular mip level |
|
virtual void ComputeMipLevelDimensions( int iMipLevel, int *pWidth, int *pHeight, int *pMipDepth ) const; |
|
|
|
// Computes the size of a subrect (specified at the top mip level) at a particular lower mip level |
|
virtual void ComputeMipLevelSubRect( Rect_t* pSrcRect, int nMipLevel, Rect_t *pSubRect ) const; |
|
|
|
// Returns the base address of the image data |
|
virtual unsigned char *ImageData(); |
|
|
|
// Returns a pointer to the data associated with a particular frame, face, and mip level |
|
virtual unsigned char *ImageData( int iFrame, int iFace, int iMipLevel ); |
|
|
|
// Returns a pointer to the data associated with a particular frame, face, mip level, and offset |
|
virtual unsigned char *ImageData( int iFrame, int iFace, int iMipLevel, int x, int y, int z ); |
|
|
|
// Returns the base address of the low-res image data |
|
virtual unsigned char *LowResImageData(); |
|
|
|
// Converts the texture's image format. Use IMAGE_FORMAT_DEFAULT |
|
virtual void ConvertImageFormat( ImageFormat fmt, bool bNormalToDUDV ); |
|
|
|
// Generate spheremap based on the current cube faces (only works for cubemaps) |
|
// The look dir indicates the direction of the center of the sphere |
|
virtual void GenerateSpheremap( LookDir_t lookDir ); |
|
|
|
virtual void GenerateHemisphereMap( unsigned char *pSphereMapBitsRGBA, int targetWidth, |
|
int targetHeight, LookDir_t lookDir, int iFrame ); |
|
|
|
// Fixes the cubemap faces orientation from our standard to the |
|
// standard the material system needs. |
|
virtual void FixCubemapFaceOrientation( ); |
|
|
|
// Normalize the top mip level if necessary |
|
virtual void NormalizeTopMipLevel(); |
|
|
|
// Generates mipmaps from the base mip levels |
|
virtual void GenerateMipmaps(); |
|
|
|
// Put 1/miplevel (1..n) into alpha. |
|
virtual void PutOneOverMipLevelInAlpha(); |
|
|
|
// Computes the reflectivity |
|
virtual void ComputeReflectivity( ); |
|
|
|
// Computes the alpha flags |
|
virtual void ComputeAlphaFlags(); |
|
|
|
// Gets the texture all internally consistent assuming you've loaded |
|
// mip 0 of all faces of all frames |
|
virtual void PostProcess(bool bGenerateSpheremap, LookDir_t lookDir = LOOK_DOWN_Z, bool bAllowFixCubemapOrientation = true); |
|
virtual void SetPostProcessingSettings( VtfProcessingOptions const *pOptions ); |
|
|
|
// Generate the low-res image bits |
|
virtual bool ConstructLowResImage(); |
|
|
|
virtual void MatchCubeMapBorders( int iStage, ImageFormat finalFormat, bool bSkybox ); |
|
|
|
// Sets threshhold values for alphatest mipmapping |
|
virtual void SetAlphaTestThreshholds( float flBase, float flHighFreq ); |
|
|
|
#if defined( _X360 ) |
|
virtual int UpdateOrCreate( const char *pFilename, const char *pPathID = NULL, bool bForce = false ); |
|
virtual int FileSize( bool bPreloadOnly, int nMipSkipCount ) const; |
|
virtual bool UnserializeFromBuffer( CUtlBuffer &buf, bool bBufferIsVolatile, bool bHeaderOnly, bool bPreloadOnly, int nMipSkipCount ); |
|
virtual bool IsPreTiled() const; |
|
virtual int MappingWidth() const; |
|
virtual int MappingHeight() const; |
|
virtual int MappingDepth() const; |
|
virtual int MipSkipCount() const; |
|
virtual unsigned char *LowResImageSample(); |
|
virtual void ReleaseImageMemory(); |
|
#endif |
|
|
|
private: |
|
// Unserialization |
|
bool ReadHeader( CUtlBuffer &buf, VTFFileHeader_t &header ); |
|
|
|
void BlendCubeMapEdgePalettes( |
|
int iFrame, |
|
int iMipLevel, |
|
const CEdgeMatch *pMatch ); |
|
|
|
void BlendCubeMapCornerPalettes( |
|
int iFrame, |
|
int iMipLevel, |
|
const CCornerMatch *pMatch ); |
|
|
|
void MatchCubeMapS3TCPalettes( |
|
CEdgeMatch edgeMatches[NUM_EDGE_MATCHES], |
|
CCornerMatch cornerMatches[NUM_CORNER_MATCHES] |
|
); |
|
|
|
void SetupFaceVert( int iMipLevel, int iVert, CEdgePos &out ); |
|
void SetupEdgeIncrement( CEdgePos &start, CEdgePos &end, CEdgePos &inc ); |
|
|
|
void SetupTextureEdgeIncrements( |
|
int iMipLevel, |
|
int iFace1Edge, |
|
int iFace2Edge, |
|
bool bFlipFace2Edge, |
|
CEdgeIncrements *incs ); |
|
|
|
void BlendCubeMapFaceEdges( |
|
int iFrame, |
|
int iMipLevel, |
|
const CEdgeMatch *pMatch ); |
|
|
|
void BlendCubeMapFaceCorners( |
|
int iFrame, |
|
int iMipLevel, |
|
const CCornerMatch *pMatch ); |
|
|
|
void BuildCubeMapMatchLists( CEdgeMatch edgeMatches[NUM_EDGE_MATCHES], CCornerMatch cornerMatches[NUM_CORNER_MATCHES], bool bSkybox ); |
|
|
|
// Allocate image data blocks with an eye toward re-using memory |
|
bool AllocateImageData( int nMemorySize ); |
|
bool AllocateLowResImageData( int nMemorySize ); |
|
|
|
// Compute the mip count based on the size + flags |
|
int ComputeMipCount( ) const; |
|
|
|
// Unserialization of low-res data |
|
bool LoadLowResData( CUtlBuffer &buf ); |
|
|
|
// Unserialization of new resource data |
|
bool LoadNewResources( CUtlBuffer &buf ); |
|
|
|
// Unserialization of image data |
|
bool LoadImageData( CUtlBuffer &buf, const VTFFileHeader_t &header, int nSkipMipLevels ); |
|
|
|
// Shutdown |
|
void Shutdown(); |
|
void ReleaseResources(); |
|
|
|
// Makes a single frame of spheremap |
|
void ComputeSpheremapFrame( unsigned char **ppCubeFaces, unsigned char *pSpheremap, LookDir_t lookDir ); |
|
|
|
// Makes a single frame of spheremap |
|
void ComputeHemispheremapFrame( unsigned char **ppCubeFaces, unsigned char *pSpheremap, LookDir_t lookDir ); |
|
|
|
// Serialization of image data |
|
bool WriteImageData( CUtlBuffer &buf ); |
|
|
|
// Computes the size (in bytes) of a single mipmap of a single face of a single frame |
|
int ComputeMipSize( int iMipLevel, ImageFormat fmt ) const; |
|
|
|
// Computes the size (in bytes) of a single face of a single frame |
|
// All mip levels starting at the specified mip level are included |
|
int ComputeFaceSize( int iStartingMipLevel, ImageFormat fmt ) const; |
|
|
|
// Computes the total size of all faces, all frames |
|
int ComputeTotalSize( ImageFormat fmt ) const; |
|
|
|
// Computes the location of a particular face, frame, and mip level |
|
int GetImageOffset( int iFrame, int iFace, int iMipLevel, ImageFormat fmt ) const; |
|
|
|
// Determines if the vtf or vtfx file needs to be swapped to the current platform |
|
bool SetupByteSwap( CUtlBuffer &buf ); |
|
|
|
// Locates the resource entry info if it's present |
|
ResourceEntryInfo *FindResourceEntryInfo( unsigned int eType ); |
|
ResourceEntryInfo const *FindResourceEntryInfo( unsigned int eType ) const; |
|
|
|
// Inserts the resource entry info if it's not present |
|
ResourceEntryInfo *FindOrCreateResourceEntryInfo( unsigned int eType ); |
|
|
|
// Removes the resource entry info if it's present |
|
bool RemoveResourceEntryInfo( unsigned int eType ); |
|
|
|
#if defined( _X360 ) |
|
bool ReadHeader( CUtlBuffer &buf, VTFFileHeaderX360_t &header ); |
|
bool LoadImageData( CUtlBuffer &buf, bool bBufferIsVolatile, int nMipSkipCount ); |
|
#endif |
|
|
|
private: |
|
// This is to make sure old-format .vtf files are read properly |
|
int m_nVersion[2]; |
|
|
|
int m_nWidth; |
|
int m_nHeight; |
|
int m_nDepth; |
|
ImageFormat m_Format; |
|
|
|
int m_nMipCount; |
|
int m_nFaceCount; |
|
int m_nFrameCount; |
|
|
|
int m_nImageAllocSize; |
|
int m_nFlags; |
|
unsigned char *m_pImageData; |
|
|
|
Vector m_vecReflectivity; |
|
float m_flBumpScale; |
|
|
|
// FIXME: Do I need this? |
|
int m_iStartFrame; |
|
|
|
// Low res data |
|
int m_nLowResImageAllocSize; |
|
ImageFormat m_LowResImageFormat; |
|
int m_nLowResImageWidth; |
|
int m_nLowResImageHeight; |
|
unsigned char *m_pLowResImageData; |
|
|
|
// Used while fixing mipmap edges. |
|
CUtlVector<S3RGBA> m_OriginalData; |
|
|
|
// Alpha threshholds |
|
float m_flAlphaThreshhold; |
|
float m_flAlphaHiFreqThreshhold; |
|
|
|
CByteswap m_Swap; |
|
|
|
int m_nFinestMipmapLevel; |
|
int m_nCoarsestMipmapLevel; |
|
|
|
#if defined( _X360 ) |
|
int m_iPreloadDataSize; |
|
int m_iCompressedSize; |
|
// resolves actual dimensions to/from mapping dimensions due to pre-picmipping |
|
int m_nMipSkipCount; |
|
unsigned char m_LowResImageSample[4]; |
|
#endif |
|
|
|
CUtlVector< ResourceEntryInfo > m_arrResourcesInfo; |
|
|
|
struct ResourceMemorySection |
|
{ |
|
ResourceMemorySection() { memset( this, 0, sizeof( *this ) ); } |
|
|
|
int m_nDataAllocSize; |
|
int m_nDataLength; |
|
unsigned char *m_pData; |
|
|
|
bool AllocateData( int nMemorySize ); |
|
bool LoadData( CUtlBuffer &buf, CByteswap &byteSwap ); |
|
bool WriteData( CUtlBuffer &buf ) const; |
|
}; |
|
CUtlVector< ResourceMemorySection > m_arrResourcesData; |
|
CUtlVector< ResourceMemorySection > m_arrResourcesData_ForReuse; // Maintained to keep allocated memory blocks when unserializing from files |
|
|
|
VtfProcessingOptions m_Options; |
|
}; |
|
|
|
#endif // CVTF_H
|
|
|