📄 vbf_ddsreader.inl
字号:
//************************************************************************
// 文件名: VBF_DDS.cpp
// 描述: 读取DDS的实现文件
// 作者: 杜莹
// 时间: 2005-1-1
//************************************************************************
#ifndef __VBF_DDS_READER_INL__
#define __VBF_DDS_READER_INL__
//---------------------------------------------------------------------------------
// 函数:LoadDDSBuf()
// 描述:从内存DDS数据中获取信息
// 说明:DDS文件可以是压缩格式的,或非压缩格式的
//---------------------------------------------------------------------------------
inline BOOL LoadDDSBuf(int nSizeDDS, BYTE* pDDSBuf, DDSIMAGE* pImage)
{
ZeroMemory( pImage, sizeof(DDSIMAGE) );
// 构造内存文件
CMemFile* pMemFile = new CMemFile(pDDSBuf, nSizeDDS);
// 确认文件格式
DWORD dwMagic;
pMemFile->Read( &dwMagic, sizeof(DWORD) );
if( dwMagic!=MAKEFOURCC('D','D','S',' ') )
{
pMemFile->Close();
SAFE_DELETE(pMemFile);
return FALSE;
}
// 读取文件头信息 (即表面描述信息)
DDS_HEADER ddsHeader;
pMemFile->Read( &ddsHeader, sizeof(DDS_HEADER) );
// 判断是否压缩格式
BOOL bCompressed = FALSE;
if( ddsHeader.ddpfPixelFormat.dwFlags & DDS_RGB ) // 非压缩格式(RGB/RGBA)
{
bCompressed = FALSE;
switch(ddsHeader.ddpfPixelFormat.dwRGBBitCount)
{
case 24: { pImage->format = DDS_RGB; break; } // RGB
case 32: { pImage->format = DDS_RGBA; break; } // RGBA
default: { return FALSE; }
}
}
else if(ddsHeader.ddpfPixelFormat.dwFlags & DDS_FOURCC) // 压缩格式
{
bCompressed = TRUE;
switch(ddsHeader.ddpfPixelFormat.dwFourCC)
{
case FOURCC_DXT1: { pImage->format = VBF_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; }
case FOURCC_DXT3: { pImage->format = VBF_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; }
case FOURCC_DXT5: { pImage->format = VBF_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; }
default: { return FALSE; }
}
}
// 杜莹修改:2004-12-29
// 计算DDS大小
// 每个级别的大计算公式为:(参见D3D9帮助:DDS File Layout for Textures)
// nSizeDDSLevel = max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
int nSizeBlk = (ddsHeader.ddpfPixelFormat.dwFourCC==FOURCC_DXT1) ? 8 : 16;
int nLevelWidth = ddsHeader.dwWidth;
int nLevelHeight = ddsHeader.dwHeight;
pImage->nNumComponents = (ddsHeader.ddpfPixelFormat.dwFourCC==FOURCC_DXT1)? 3 : 4;
pImage->nNumMipmaps = ddsHeader.dwMipMapCount;
pImage->pLevelWidth = new int[pImage->nNumMipmaps];
pImage->pLevelHeight = new int[pImage->nNumMipmaps];
pImage->pLevelBytes = new int[pImage->nNumMipmaps];
pImage->nBitsBytes = 0;
for(DWORD i=0; i<ddsHeader.dwMipMapCount; i++)
{
if(bCompressed)
pImage->pLevelBytes[i] = max(1,nLevelWidth/4) * max(1,nLevelHeight/4) * nSizeBlk;
else
pImage->pLevelBytes[i] = nLevelWidth * nLevelHeight * ddsHeader.ddpfPixelFormat.dwRGBBitCount/8;
pImage->nBitsBytes += pImage->pLevelBytes[i];
pImage->pLevelWidth[i] = nLevelWidth;
pImage->pLevelHeight[i] = nLevelHeight;
nLevelWidth >>= 1;
nLevelHeight >>= 1;
}
pImage->pBits = new BYTE[pImage->nBitsBytes];
pMemFile->Read( pImage->pBits, pImage->nBitsBytes );
pMemFile->Close();
SAFE_DELETE(pMemFile);
return TRUE;
}
//---------------------------------------------------------------------------------
// 函数:ReadDDSFile()
// 描述:读取DDS文件
//---------------------------------------------------------------------------------
inline BOOL ReadDDSFile(const CString& strDDSFn, DDSIMAGE* pImage)
{
// 打开DDS文件,并确认格式
CFile file;
if( !file.Open(strDDSFn, CFile::modeRead|CFile::typeBinary, NULL) )
return FALSE;
int nSizeDDS = file.GetLength();
BYTE* pDDSBuf = new BYTE[nSizeDDS];
file.ReadHuge(pDDSBuf, nSizeDDS);
file.Close();
if( !::LoadDDSBuf(nSizeDDS, pDDSBuf, pImage) )
return FALSE;
SAFE_DELETE(pDDSBuf);
return TRUE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -