首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络游戏 >

关于DDS的DXT1和 DXT3的解码解决思路

2012-03-23 
关于DDS的DXT1和 DXT3的解码关于DDS的DXT1和 DXT3的解码, 有两个问题。第一个问题:它们解码速度怎么样,能实

关于DDS的DXT1和 DXT3的解码


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

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


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



[解决办法]
没做过。
google找找资料。英文习惯就好啊,英文资料多点。
[解决办法]
我给你实际源码吧,该源码是从Microsoft DirectX SDK (March 2009)的DirectX Texture Tool示例程序中提取出来的,详细源码,请参考该示例。

C/C++ code
// 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_ALPHAPIXELSconst 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_VOLUMEstruct 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 


[解决办法]

C/C++ code
// ------------------------------------//§ 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#endifCDDSConvert::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;} 


[解决办法]
微软的开发者官网上有讲解的

热点排行