⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadsavedds.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            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 + -