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.
442 lines
13 KiB
442 lines
13 KiB
5 years ago
|
//========= 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() {}
|
||
|
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
|