📄 loadsavedds.cpp
字号:
break;
case D3DFMT_A1R5G5B5:
case D3DFMT_A4R4G4B4:
case D3DFMT_R5G6B5:
numBytesPerRow = 2 * vd.Width;
break;
default:
return E_FAIL;
}
pbSlice = (BYTE*)lb.pBits;
for (zp = 0; zp < vd.Depth; zp++)
{
pbRow = pbSlice;
for (yp = 0; yp < vd.Height; yp++)
{
ar.Write(pbRow, numBytesPerRow);
pbRow += lb.RowPitch;
}
pbSlice += lb.SlicePitch;
}
pvoltex->UnlockBox(iLevel);
}
return S_OK;
}
// loads a texture and returns a pointer in pptex
HRESULT CDDS::LoadDDS(LPDIRECT3DBASETEXTURE8* pptex, const char * filename)
{
CArchive ar;
ar.Open(filename, "rb");
HRESULT hr;
DWORD dwMagic;
DDS_HEADER ddsh;
LPDIRECT3DTEXTURE8 pmiptex = NULL;
LPDIRECT3DCUBETEXTURE8 pcubetex = NULL;
LPDIRECT3DVOLUMETEXTURE8 pvoltex = NULL;
*pptex = NULL;
ar.Read(&dwMagic, sizeof(dwMagic));
if (dwMagic != MAKEFOURCC('D','D','S',' '))
return E_FAIL;
ar.Read(&ddsh, sizeof(ddsh));
if (ddsh.dwSize != sizeof(ddsh))
return E_FAIL;
m_dwWidth = ddsh.dwWidth;
m_dwHeight = ddsh.dwHeight;
m_numMips = ddsh.dwMipMapCount;
if (m_numMips == 0)
m_numMips = 1;
m_dwCubeMapFlags = (ddsh.dwCubemapFlags & DDS_CUBEMAP_ALLFACES);
if (ddsh.dwHeaderFlags & DDS_HEADER_FLAGS_VOLUME)
m_dwDepth = ddsh.dwDepth;
else
m_dwDepth = 0;
D3DFORMAT fmt;
if (!IsVolumeMap() && ddsh.ddspf.dwFourCC == D3DFMT_DXT1)
fmt = D3DFMT_DXT1;
else if (!IsVolumeMap() && ddsh.ddspf.dwFourCC == D3DFMT_DXT2)
fmt = D3DFMT_DXT2;
else if (!IsVolumeMap() && ddsh.ddspf.dwFourCC == D3DFMT_DXT3)
fmt = D3DFMT_DXT3;
else if (!IsVolumeMap() && ddsh.ddspf.dwFourCC == D3DFMT_DXT4)
fmt = D3DFMT_DXT4;
else if (!IsVolumeMap() && ddsh.ddspf.dwFourCC == D3DFMT_DXT5)
fmt = D3DFMT_DXT5;
else if (ddsh.ddspf.dwFlags == DDS_RGBA && ddsh.ddspf.dwRGBBitCount == 32 && ddsh.ddspf.dwABitMask == 0xff000000)
fmt = D3DFMT_A8R8G8B8;
else if (ddsh.ddspf.dwFlags == DDS_RGB && ddsh.ddspf.dwRGBBitCount == 24)
fmt = D3DFMT_R8G8B8;
else if (ddsh.ddspf.dwFlags == DDS_RGB && ddsh.ddspf.dwRGBBitCount == 16 && ddsh.ddspf.dwGBitMask == 0x000007e0)
fmt = D3DFMT_R5G6B5;
else if (ddsh.ddspf.dwFlags == DDS_RGBA && ddsh.ddspf.dwRGBBitCount == 16 && ddsh.ddspf.dwABitMask == 0x00008000)
fmt = D3DFMT_A1R5G5B5;
else if (ddsh.ddspf.dwFlags == DDS_RGBA && ddsh.ddspf.dwRGBBitCount == 16 && ddsh.ddspf.dwABitMask == 0x0000f000)
fmt = D3DFMT_A4R4G4B4;
else
return E_FAIL; // unknown fmt
if (IsVolumeMap())
{
if (FAILED(hr = m_pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips,
0, fmt, D3DPOOL_SYSTEMMEM, &pvoltex)))
{
return hr;
}
if (FAILED(hr = LoadAllVolumeSurfaces(pvoltex, ar)))
return hr;
*pptex = pvoltex;
}
else if (IsCubeMap())
{
if (FAILED(hr = m_pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips,
0, fmt, D3DPOOL_MANAGED, &pcubetex)))
{
return hr;
}
// Cubemaps created with the DX7 version of DxTex may skip some
// cube faces. ddsh.dwCubeMapFlags indicates which faces are
// present. If you only care about loading post-DX7 cubemaps, you
// don't have to check these flags -- just load each face in sequence.
// REVIEW: zero out surfaces of missing faces?
if (m_dwCubeMapFlags & DDS_CUBEMAP_POSITIVEX)
{
if (FAILED(hr = LoadAllMipSurfaces(pcubetex, D3DCUBEMAP_FACE_POSITIVE_X, ar)))
return hr;
}
if (m_dwCubeMapFlags & DDS_CUBEMAP_NEGATIVEX)
{
if (FAILED(hr = LoadAllMipSurfaces(pcubetex, D3DCUBEMAP_FACE_NEGATIVE_X, ar)))
return hr;
}
if (m_dwCubeMapFlags & DDS_CUBEMAP_POSITIVEY)
{
if (FAILED(hr = LoadAllMipSurfaces(pcubetex, D3DCUBEMAP_FACE_POSITIVE_Y, ar)))
return hr;
}
if (m_dwCubeMapFlags & DDS_CUBEMAP_NEGATIVEY)
{
if (FAILED(hr = LoadAllMipSurfaces(pcubetex, D3DCUBEMAP_FACE_NEGATIVE_Y, ar)))
return hr;
}
if (m_dwCubeMapFlags & DDS_CUBEMAP_POSITIVEZ)
{
if (FAILED(hr = LoadAllMipSurfaces(pcubetex, D3DCUBEMAP_FACE_POSITIVE_Z, ar)))
return hr;
}
if (m_dwCubeMapFlags & DDS_CUBEMAP_NEGATIVEZ)
{
if (FAILED(hr = LoadAllMipSurfaces(pcubetex, D3DCUBEMAP_FACE_NEGATIVE_Z, ar)))
return hr;
}
*pptex = pcubetex;
}
else
{
if (FAILED(hr = m_pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips,
0, fmt, D3DPOOL_MANAGED, &pmiptex)))
{
return hr;
}
if (FAILED(hr = LoadAllMipSurfaces(pmiptex, D3DCUBEMAP_FACE_FORCE_DWORD, ar)))
return hr;
*pptex = pmiptex;
}
ar.Close();
return S_OK;
}
HRESULT CDDS::LoadAllMipSurfaces(LPDIRECT3DBASETEXTURE8 ptex, D3DCUBEMAP_FACES FaceType, CArchive& ar)
{
HRESULT hr;
LPDIRECT3DSURFACE8 psurf;
D3DSURFACE_DESC sd;
UINT iLevel;
D3DLOCKED_RECT lr;
LPDIRECT3DTEXTURE8 pmiptex = NULL;
LPDIRECT3DCUBETEXTURE8 pcubetex = NULL;
DWORD dwBytesPerRow;
if (FaceType == D3DCUBEMAP_FACE_FORCE_DWORD)
pmiptex = (LPDIRECT3DTEXTURE8)ptex;
else
pcubetex = (LPDIRECT3DCUBETEXTURE8)ptex;
for (iLevel = 0; iLevel < m_numMips; iLevel++)
{
if (pmiptex != NULL)
hr = pmiptex->GetSurfaceLevel(iLevel, &psurf);
else
hr = pcubetex->GetCubeMapSurface(FaceType, iLevel, &psurf);
if (FAILED(hr))
return hr;
psurf->GetDesc(&sd);
switch (sd.Format)
{
case D3DFMT_DXT1:
case D3DFMT_DXT2:
case D3DFMT_DXT3:
case D3DFMT_DXT4:
case D3DFMT_DXT5:
dwBytesPerRow = 0; // magic value indicates texture's memory is contiguous
break;
case D3DFMT_A8R8G8B8:
dwBytesPerRow = 4 * sd.Width;
break;
case D3DFMT_R8G8B8:
dwBytesPerRow = 3 * sd.Width;
break;
case D3DFMT_A1R5G5B5:
case D3DFMT_A4R4G4B4:
case D3DFMT_R5G6B5:
dwBytesPerRow = 2 * sd.Width;
break;
default:
return E_FAIL;
}
if (pmiptex != NULL)
hr = pmiptex->LockRect(iLevel, &lr, NULL, 0);
else
hr = pcubetex->LockRect(FaceType, iLevel, &lr, NULL, 0);
if (FAILED(hr))
return hr;
if (dwBytesPerRow == 0)
{
ar.Read(lr.pBits, sd.Size);
}
else
{
DWORD yp;
BYTE* pbDest = (BYTE*)lr.pBits;
for (yp = 0; yp < sd.Height; yp++)
{
ar.Read(pbDest, dwBytesPerRow);
pbDest += lr.Pitch;
}
}
if (pmiptex != NULL)
hr = pmiptex->UnlockRect(iLevel);
else
hr = pcubetex->UnlockRect(FaceType, iLevel);
ReleasePpo(&psurf);
}
return S_OK;
}
HRESULT CDDS::LoadAllVolumeSurfaces(LPDIRECT3DVOLUMETEXTURE8 pvoltex, CArchive& ar)
{
HRESULT hr;
D3DVOLUME_DESC vd;
D3DBOX box;
D3DLOCKED_BOX lb;
UINT iLevel;
UINT numBytesPerRow;
BYTE* pbSlice;
BYTE* pbRow;
UINT zp;
UINT yp;
for (iLevel = 0; iLevel < m_numMips; iLevel++)
{
pvoltex->GetLevelDesc(iLevel, &vd);
box.Left = 0;
box.Right = vd.Width;
box.Top = 0;
box.Bottom = vd.Height;
box.Front = 0;
box.Back = vd.Depth;
hr = pvoltex->LockBox(iLevel, &lb, &box, 0);
if (FAILED(hr))
return hr;
switch(vd.Format)
{
case D3DFMT_A8R8G8B8:
numBytesPerRow = 4 * vd.Width;
break;
default:
return E_FAIL;
}
pbSlice = (BYTE*)lb.pBits;
for (zp = 0; zp < vd.Depth; zp++)
{
pbRow = pbSlice;
for (yp = 0; yp < vd.Height; yp++)
{
ar.Read(pbRow, numBytesPerRow);
pbRow += lb.RowPitch;
}
pbSlice += lb.SlicePitch;
}
pvoltex->UnlockBox(iLevel);
}
return S_OK;
}
bool FileExists(std::string & name)
{
FILE * fp;
fp = fopen(name.c_str(), "rb");
if (fp)
{
fclose(fp);
return true;
}
else
return false;
}
/////////////////////////////////////////////////////////////////////////////
// CDDS commands
HRESULT CDDS::LoadBmp(CSTR& strPath)
{
HRESULT hr;
LPDIRECT3DTEXTURE8 ptex;
hr = D3DXCreateTextureFromFileEx(m_pd3ddev, strPath.c_str(), D3DX_DEFAULT,
D3DX_DEFAULT, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
D3DX_FILTER_POINT, D3DX_FILTER_POINT, 0, NULL, NULL, &ptex);
if (FAILED(hr))
return hr;
// Look for "foo_a.bmp" for alpha channel
int i = strPath.rfind('.');
//strPath = strPath.Left(i) + "_a.bmp";
CSTR strPath2;
strPath2 = strPath.substr(0, i) + "_a.bmp";
if (FileExists(strPath2))
{
LPDIRECT3DSURFACE8 psurf;
hr = ptex->GetSurfaceLevel(0, &psurf);
if (FAILED(hr))
return hr;
hr = LoadAlphaIntoSurface(strPath2, psurf);
ReleasePpo(&psurf);
if (FAILED(hr))
return hr;
}
// Ensure that source image dimensions are power of 2
D3DSURFACE_DESC sd;
ptex->GetLevelDesc(0, &sd);
m_dwWidth = sd.Width;
m_dwHeight = sd.Height;
LONG lwTempW;
LONG lwTempH;
lwTempW = sd.Width;
lwTempH = sd.Height;
while ((lwTempW & 1) == 0)
lwTempW = lwTempW >> 1;
while ((lwTempH & 1) == 0)
lwTempH = lwTempH >> 1;
if (lwTempW != 1 || lwTempH != 1)
{
AfxMessageBox(ID_ERROR_NOTPOW2);
ReleasePpo(&ptex);
return E_FAIL;
}
m_numMips = 1;
ReleasePpo(&m_ptexOrig);
m_ptexOrig = ptex;
m_strPathName.empty();
return S_OK;
}
HRESULT CDDS::LoadAlphaBmp(CSTR& strPath)
{
HRESULT hr;
LPDIRECT3DTEXTURE8 pmiptex;
LPDIRECT3DSURFACE8 psurf;
if (IsCubeMap())
return E_FAIL;
pmiptex = (LPDIRECT3DTEXTURE8)m_ptexOrig;
hr = pmiptex->GetSurfaceLevel(0, &psurf);
if (FAILED(hr))
return hr;
hr = LoadAlphaIntoSurface(strPath, psurf);
ReleasePpo(&psurf);
if (FAILED(hr))
return hr;
return S_OK;
}
HRESULT CDDS::Compress(D3DFORMAT fmtTo, BOOL bSwitchView)
{
HRESULT hr;
LPDIRECT3DTEXTURE8 pmiptex;
LPDIRECT3DCUBETEXTURE8 pcubetex;
LPDIRECT3DVOLUMETEXTURE8 pvoltex;
D3DFORMAT fmtFrom;
LPDIRECT3DTEXTURE8 pmiptexNew;
LPDIRECT3DCUBETEXTURE8 pcubetexNew;
LPDIRECT3DVOLUMETEXTURE8 pvoltexNew;
if (IsVolumeMap())
{
if (fmtTo == D3DFMT_DXT1 ||
fmtTo == D3DFMT_DXT2 ||
fmtTo == D3DFMT_DXT3 ||
fmtTo == D3DFMT_DXT4 ||
fmtTo == D3DFMT_DXT5)
{
return E_FAIL;
}
pvoltex = (LPDIRECT3DVOLUMETEXTURE8)m_ptexOrig;
D3DVOLUME_DESC vd;
pvoltex->GetLevelDesc(0, &vd);
fmtFrom = vd.Format;
}
else if (IsCubeMap())
{
pcubetex = (LPDIRECT3DCUBETEXTURE8)m_ptexOrig;
D3DSURFACE_DESC sd;
pcubetex->GetLevelDesc(0, &sd);
fmtFrom = sd.Format;
}
else
{
pmiptex = (LPDIRECT3DTEXTURE8)m_ptexOrig;
D3DSURFACE_DESC sd;
pmiptex->GetLevelDesc(0, &sd);
fmtFrom = sd.Format;
}
if (fmtFrom == D3DFMT_DXT2 || fmtFrom == D3DFMT_DXT4)
{
if (fmtTo == D3DFMT_DXT1)
{
AfxMessageBox(ID_ERROR_PREMULTTODXT1);
}
else if (fmtTo != D3DFMT_DXT2 && fmtTo != D3DFMT_DXT4)
{
AfxMessageBox(ID_ERROR_PREMULTALPHA);
return S_OK;
}
}
if (IsVolumeMap())
{
hr = m_pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips,
0, fmtTo, D3DPOOL_SYSTEMMEM, &pvoltexNew);
if (FAILED(hr))
return hr;
ReleasePpo(&m_ptexNew);
m_ptexNew = pvoltexNew;
if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, m_ptexOrig, m_ptexNew)))
return hr;
}
else if (IsCubeMap())
{
hr = m_pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips,
0, fmtTo, D3DPOOL_MANAGED, &pcubetexNew);
if (FAILED(hr))
return hr;
ReleasePpo(&m_ptexNew);
m_ptexNew = pcubetexNew;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -