source-engine/vtf/cvtf.h

442 lines
13 KiB
C
Raw Permalink Normal View History

2020-04-22 16:56:21 +00:00
//========= 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;
2020-04-22 16:56:21 +00:00
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