关于DDS的DXT1和 DXT3的解码

莫_问 2011-07-12 06:32:01


关于DDS的DXT1和 DXT3的解码, 有两个问题。

第一个问题:它们解码速度怎么样,能实时解码?
第二个问题:谁有相应的解码程序,给发一份?


初次接触DDS格式,请大家多帮忙,谢谢了。

...全文
970 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
莫_问 2011-07-16
  • 打赏
  • 举报
回复
操,没人气,浪费我分水
莫_问 2011-07-14
  • 打赏
  • 举报
回复
晕死,没人啊 真服了
莫_问 2011-07-13
  • 打赏
  • 举报
回复
第一个问题:它们解码速度怎么样,能实时解码?


Sou2012 2011-07-12
  • 打赏
  • 举报
回复
微软的开发者官网上有讲解的
xychzh 2011-07-12
  • 打赏
  • 举报
回复

// ------------------------------------------------------------------------
//§ File: DDSConvert.cpp
//§ Desc: CDDSConvert dds格式转换
//§
//§ Date: 2011/6/6
//§ Copyright(c) xychzh
// ------------------------------------------------------------------------
#include "StdAfx.h"
#include "DDSConvert.h"


#ifndef ReleasePpo
#define ReleasePpo(ppo) \
if (*(ppo) != NULL) \
{ \
(*(ppo))->Release(); \
*(ppo) = NULL; \
} \
else (VOID)0
#endif


CDDSConvert::CDDSConvert(IDirect3DDevice9* pD3DDevice)
{
m_pD3DDevice = pD3DDevice;
m_ptexOrig = NULL;
m_ptexNew = NULL;
}

CDDSConvert::~CDDSConvert()
{
}

void CDDSConvert::ConvertDDS(const char* szSrcFile, const char* szDstFile, D3DFORMAT dstFormat)
{
OpenFile(szSrcFile);

IDirect3DTexture9* pSrcTexture = (IDirect3DTexture9*)m_ptexOrig;
IDirect3DTexture9* pDstTexture = NULL;

Compress(pSrcTexture, &pDstTexture, dstFormat);

if( FAILED( D3DXSaveTextureToFile( szDstFile, D3DXIFF_DDS, pDstTexture, NULL ) ) )
{
return;
}

ReleasePpo(&m_ptexOrig);

if (pDstTexture != NULL)
{
pDstTexture->Release();
pDstTexture = NULL;
}
}

void CDDSConvert::ConvertDDS(IDirect3DTexture9* pSrcTexture, IDirect3DTexture9** ppDstTexture, D3DFORMAT dstFormat)
{
D3DSURFACE_DESC surfaceDesc;
pSrcTexture->GetLevelDesc(0, &surfaceDesc);

m_CurFormat = surfaceDesc.Format;
m_dwWidth = surfaceDesc.Width;
m_dwHeight = surfaceDesc.Height;
m_dwDepth = 0;
m_numMips = 1;

Compress(pSrcTexture, ppDstTexture, dstFormat);
}

BOOL CDDSConvert::OpenFile(LPCTSTR lpszPathName)
{
LPDIRECT3DDEVICE9 pd3ddev = m_pD3DDevice;
D3DXIMAGE_INFO imageinfo;
D3DXIMAGE_INFO imageinfo2;

if( FAILED( D3DXGetImageInfoFromFile( lpszPathName, &imageinfo ) ) )
{
return FALSE;
}

switch( imageinfo.ResourceType )
{
case D3DRTYPE_TEXTURE:
if( FAILED( D3DXCreateTextureFromFileEx( pd3ddev, lpszPathName,
imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0,
imageinfo.Format, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0,
&imageinfo2, NULL, (LPDIRECT3DTEXTURE9*)&m_ptexOrig ) ) )
{
return FALSE;
}

m_dwWidth = imageinfo2.Width;
m_dwHeight = imageinfo2.Height;
m_dwDepth = 0;
m_numMips = imageinfo2.MipLevels;

D3DSURFACE_DESC surfaceDesc;
((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetLevelDesc(0, &surfaceDesc);
m_CurFormat = surfaceDesc.Format;

if( imageinfo.ImageFileFormat == D3DXIFF_BMP )
{
// Look for "foo_a.bmp" for alpha channel
// CString strPath = lpszPathName;
// int i = strPath.ReverseFind('.');
// HRESULT hr;
// strPath = strPath.Left(i) + "_a.bmp";
// CFileStatus status;
// if (CFile::GetStatus(strPath, status))
// {
// // Make sure there's an alpha channel to load alpha image into
// if (FAILED(EnsureAlpha(&m_ptexOrig)))
// return FALSE;
//
// LPDIRECT3DSURFACE9 psurf;
//
// hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(0, &psurf);
// if (FAILED(hr))
// return FALSE;
//
// hr = LoadAlphaIntoSurface(strPath, psurf);
// ReleasePpo(&psurf);
// if (FAILED(hr))
// return FALSE;
// }
}
break;

case D3DRTYPE_VOLUMETEXTURE:
if( FAILED( D3DXCreateVolumeTextureFromFileEx( pd3ddev, lpszPathName,
imageinfo.Width, imageinfo.Height, imageinfo.Depth, imageinfo.MipLevels,
0, imageinfo.Format, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE,
0, &imageinfo2, NULL, (LPDIRECT3DVOLUMETEXTURE9*)&m_ptexOrig ) ) )
{
return FALSE;
}
m_dwWidth = imageinfo2.Width;
m_dwHeight = imageinfo2.Height;
m_dwDepth = imageinfo2.Depth;
m_numMips = imageinfo2.MipLevels;
break;

case D3DRTYPE_CUBETEXTURE:
if( FAILED( D3DXCreateCubeTextureFromFileEx( pd3ddev, lpszPathName,
imageinfo.Width, imageinfo.MipLevels, 0, imageinfo.Format,
D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE,
0, &imageinfo2, NULL, (LPDIRECT3DCUBETEXTURE9*)&m_ptexOrig ) ) )
{
return FALSE;
}
m_dwWidth = imageinfo2.Width;
m_dwHeight = imageinfo2.Height;
m_dwDepth = 0;
m_numMips = imageinfo2.MipLevels;
// m_dwCubeMapFlags = DDS_CUBEMAP_ALLFACES;
break;

default:
return FALSE;
}

return TRUE;
}

HRESULT CDDSConvert::Compress(IDirect3DTexture9* pSrc, IDirect3DTexture9** ppDst, D3DFORMAT fmtTo)
{
HRESULT hr;
LPDIRECT3DBASETEXTURE9 ptexNew = NULL;

if (FAILED(hr = ChangeFormat(pSrc, fmtTo, (LPDIRECT3DBASETEXTURE9*)ppDst)))
return hr;

return S_OK;
}

HRESULT CDDSConvert::ChangeFormat(LPDIRECT3DBASETEXTURE9 ptexCur, D3DFORMAT fmtTo,
LPDIRECT3DBASETEXTURE9* pptexNew)
{
HRESULT hr;
LPDIRECT3DDEVICE9 pd3ddev = m_pD3DDevice;
LPDIRECT3DTEXTURE9 pmiptex;
LPDIRECT3DCUBETEXTURE9 pcubetex;
LPDIRECT3DVOLUMETEXTURE9 pvoltex;
D3DFORMAT fmtFrom;
LPDIRECT3DTEXTURE9 pmiptexNew;
LPDIRECT3DCUBETEXTURE9 pcubetexNew;
LPDIRECT3DVOLUMETEXTURE9 pvoltexNew;

if (IsVolumeMap())
{
pvoltex = (LPDIRECT3DVOLUMETEXTURE9)ptexCur;
D3DVOLUME_DESC vd;
pvoltex->GetLevelDesc(0, &vd);
fmtFrom = vd.Format;
}
// else if (m_dwCubeMapFlags > 0)
// {
// pcubetex = (LPDIRECT3DCUBETEXTURE9)ptexCur;
// D3DSURFACE_DESC sd;
// pcubetex->GetLevelDesc(0, &sd);
// fmtFrom = sd.Format;
// }
else
{
pmiptex = (LPDIRECT3DTEXTURE9)ptexCur;
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 = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips,
0, fmtTo, D3DPOOL_SYSTEMMEM, &pvoltexNew, NULL);
if (FAILED(hr))
return hr;
*pptexNew = pvoltexNew;
if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
return hr;
}
// else if (m_dwCubeMapFlags > 0)
// {
// hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips,
// 0, fmtTo, D3DPOOL_MANAGED, &pcubetexNew, NULL);
// if (FAILED(hr))
// return hr;
// *pptexNew = pcubetexNew;
// if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_X, ptexCur, *pptexNew)))
// return hr;
// if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_X, ptexCur, *pptexNew)))
// return hr;
// if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Y, ptexCur, *pptexNew)))
// return hr;
// if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Y, ptexCur, *pptexNew)))
// return hr;
// if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Z, ptexCur, *pptexNew)))
// return hr;
// if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Z, ptexCur, *pptexNew)))
// return hr;
// }
else
{
if ((fmtTo == D3DFMT_DXT1 || fmtTo == D3DFMT_DXT2 ||
fmtTo == D3DFMT_DXT3 || fmtTo == D3DFMT_DXT4 ||
fmtTo == D3DFMT_DXT5) && (m_dwWidth % 4 != 0 || m_dwHeight % 4 != 0))
{
// AfxMessageBox(ID_ERROR_NEEDMULTOF4);
return E_FAIL;
}

hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips,
0, fmtTo, D3DPOOL_MANAGED, &pmiptexNew, NULL);
if (FAILED(hr))
return hr;
*pptexNew = pmiptexNew;
if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
return hr;
}
return S_OK;
}

HRESULT CDDSConvert::BltAllLevels(D3DCUBEMAP_FACES FaceType, LPDIRECT3DBASETEXTURE9 ptexSrc, LPDIRECT3DBASETEXTURE9 ptexDest)
{
HRESULT hr;
LPDIRECT3DTEXTURE9 pmiptexSrc;
LPDIRECT3DTEXTURE9 pmiptexDest;
LPDIRECT3DCUBETEXTURE9 pcubetexSrc;
LPDIRECT3DCUBETEXTURE9 pcubetexDest;
LPDIRECT3DVOLUMETEXTURE9 pvoltexSrc;
LPDIRECT3DVOLUMETEXTURE9 pvoltexDest;
DWORD iLevel;

if (IsVolumeMap())
{
pvoltexSrc = (LPDIRECT3DVOLUMETEXTURE9)ptexSrc;
pvoltexDest = (LPDIRECT3DVOLUMETEXTURE9)ptexDest;
}
// else if (IsCubeMap())
// {
// pcubetexSrc = (LPDIRECT3DCUBETEXTURE9)ptexSrc;
// pcubetexDest = (LPDIRECT3DCUBETEXTURE9)ptexDest;
// }
else
{
pmiptexSrc = (LPDIRECT3DTEXTURE9)ptexSrc;
pmiptexDest = (LPDIRECT3DTEXTURE9)ptexDest;
}

for (iLevel = 0; iLevel < m_numMips; iLevel++)
{
if (IsVolumeMap())
{
LPDIRECT3DVOLUME9 pvolSrc = NULL;
LPDIRECT3DVOLUME9 pvolDest = NULL;
hr = pvoltexSrc->GetVolumeLevel(iLevel, &pvolSrc);
hr = pvoltexDest->GetVolumeLevel(iLevel, &pvolDest);
hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL,
pvolSrc, NULL, NULL, D3DX_DEFAULT, 0);
ReleasePpo(&pvolSrc);
ReleasePpo(&pvolDest);
}
// else if (IsCubeMap())
// {
// LPDIRECT3DSURFACE9 psurfSrc = NULL;
// LPDIRECT3DSURFACE9 psurfDest = NULL;
// hr = pcubetexSrc->GetCubeMapSurface(FaceType, iLevel, &psurfSrc);
// hr = pcubetexDest->GetCubeMapSurface(FaceType, iLevel, &psurfDest);
// hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL,
// psurfSrc, NULL, NULL, D3DX_DEFAULT, 0);
// ReleasePpo(&psurfSrc);
// ReleasePpo(&psurfDest);
// }
else
{
LPDIRECT3DSURFACE9 psurfSrc = NULL;
LPDIRECT3DSURFACE9 psurfDest = NULL;
hr = pmiptexSrc->GetSurfaceLevel(iLevel, &psurfSrc);
hr = pmiptexDest->GetSurfaceLevel(iLevel, &psurfDest);
hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL,
psurfSrc, NULL, NULL, D3DX_DEFAULT, 0);
ReleasePpo(&psurfSrc);
ReleasePpo(&psurfDest);
}
}

return S_OK;
}


OK,代码都在这了。
该程序已测试过DXT5格式转换没有问题,其他应该没什么问题。
解压缩都在里面了。
xychzh 2011-07-12
  • 打赏
  • 举报
回复
我给你实际源码吧,该源码是从Microsoft DirectX SDK (March 2009)的DirectX Texture Tool示例程序中提取出来的,详细源码,请参考该示例。

// DDSBase.h
//
// This header defines constants and structures that are useful when parsing
// DDS files. DDS files were originally designed to use several structures
// and constants that are native to DirectDraw and are defined in ddraw.h,
// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar
// (compatible) constants and structures so that one can use DDS files
// without needing to include ddraw.h.

#ifndef _DDSBASE_H_
#define _DDSBASE_H_


struct DDS_PIXELFORMAT
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwFourCC;
DWORD dwRGBBitCount;
DWORD dwRBitMask;
DWORD dwGBitMask;
DWORD dwBBitMask;
DWORD dwABitMask;
};

#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS

const DDS_PIXELFORMAT DDSPF_DXT1 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 };

const DDS_PIXELFORMAT DDSPF_DXT2 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 };

const DDS_PIXELFORMAT DDSPF_DXT3 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 };

const DDS_PIXELFORMAT DDSPF_DXT4 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 };

const DDS_PIXELFORMAT DDSPF_DXT5 =
{ sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 };

const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };

const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };

const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };

const DDS_PIXELFORMAT DDSPF_R8G8B8 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };

const DDS_PIXELFORMAT DDSPF_R5G6B5 =
{ sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };

#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT
#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH
#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE

#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX

#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ

#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )

#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME


struct DDS_HEADER
{
DWORD dwSize;
DWORD dwHeaderFlags;
DWORD dwHeight;
DWORD dwWidth;
DWORD dwPitchOrLinearSize;
DWORD dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags
DWORD dwMipMapCount;
DWORD dwReserved1[11];
DDS_PIXELFORMAT ddspf;
DWORD dwSurfaceFlags;
DWORD dwCubemapFlags;
DWORD dwReserved2[3];
};


#endif


//-------------------------------------------------------------------------
//§ File: DDSConvert.h
//§ Desc: CDDSConvert dds格式转换
//§
//§ Date: 2011/6/6
//§ Copyright(c) xychzh
//-------------------------------------------------------------------------
#ifndef _DDSCONVERT_H_
#define _DDSCONVERT_H_

#include "DDSBase.h"



class CDDSConvert
{
public:
CDDSConvert(IDirect3DDevice9* pD3DDevice);
~CDDSConvert();

public:
void ConvertDDS(const char* szSrcFile, const char* szDstFile, D3DFORMAT dstFormat);
void ConvertDDS(IDirect3DTexture9* pSrcTexture, IDirect3DTexture9** ppDstTexture, D3DFORMAT dstFormat);
BOOL OpenFile(LPCTSTR lpszPathName);

HRESULT Compress(IDirect3DTexture9* pSrc, IDirect3DTexture9** ppDst, D3DFORMAT fmtTo);
HRESULT ChangeFormat(LPDIRECT3DBASETEXTURE9 ptexCur, D3DFORMAT fmtTo, LPDIRECT3DBASETEXTURE9* pptexNew);
HRESULT BltAllLevels(D3DCUBEMAP_FACES FaceType, LPDIRECT3DBASETEXTURE9 ptexSrc, LPDIRECT3DBASETEXTURE9 ptexDest);

bool IsVolumeMap() { return m_dwDepth > 0; }
// BOOL IsCubeMap(VOID) { return (m_dwCubeMapFlags > 0); }

private:
IDirect3DDevice9* m_pD3DDevice; // D3D设备对象

private:
LPDIRECT3DBASETEXTURE9 m_ptexOrig;
LPDIRECT3DBASETEXTURE9 m_ptexNew;
DWORD m_dwWidth;
DWORD m_dwHeight;
DWORD m_dwDepth;
int m_numMips;

D3DFORMAT m_CurFormat;
};


#endif


代码未完,下楼接着。
ryfdizuo 2011-07-12
  • 打赏
  • 举报
回复
没做过。
google找找资料。英文习惯就好啊,英文资料多点。
莫_问 2011-07-12
  • 打赏
  • 举报
回复
或者关于格式的详细资料也行,英文看着累啊!!!

8,305

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧