#include ".\ntexture.h" #include #include "./GraphicLayerError.h" #include "GMMemory.h" namespace CROSSM { char CNTexture::m_strPath[256]; LPDIRECT3DDEVICE8 CNTexture::ms_pd3dDevice = NULL; int CNTexture::m_SkipMipLevel=0; IDirect3DTexture8* CNTexture::ms_pNullTexture = NULL; bool CNTexture::ms_bNullTextureMode = false; void CNTexture::Init(LPDIRECT3DDEVICE8 lpDevice) { ms_pd3dDevice = lpDevice; ms_pd3dDevice->AddRef(); // create 1x1 texture if (FAILED(ms_pd3dDevice->CreateTexture(1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ms_pNullTexture))) { ms_pd3dDevice->Release(); } D3DLOCKED_RECT lr; ms_pNullTexture->LockRect(0, &lr, NULL, 0); *((D3DCOLOR*)(lr.pBits)) = D3DCOLOR_ARGB(0xFF, 0xFF, 0xFF, 0xFF); ms_pNullTexture->UnlockRect(0); ms_bNullTextureMode = false; } void CNTexture::Close() { if (NULL != ms_pNullTexture) { ms_pNullTexture->Release(); ms_pNullTexture = NULL; } if (NULL != ms_pd3dDevice) { ms_pd3dDevice->Release(); } } CNTexture::CNTexture(void) :m_pddTexture(NULL), m_bInterface(false) { m_dwWidth = m_dwHeight = 0; m_bCreateEmpty = false; } CNTexture::~CNTexture(void) { if(m_pddTexture) { SafeRelease(m_pddTexture); m_pddTexture =NULL; } } bool CNTexture::Load() { DDS_HEADER ddsh; if(strstr(m_strPath,"Interface")==0) { m_bInterface = false; } else { m_bInterface = true; } if(m_bInterface) { if(!m_pByteDataObj) { return false; } // magic header(ignore) m_pByteDataObj->Read(&m_dwValue[0],sizeof(DWORD),1); // DDS HEADER m_pByteDataObj->Read(&ddsh,sizeof(ddsh),1); m_dwWidth=ddsh.dwWidth; m_dwHeight=ddsh.dwHeight; // num mip m_dwValue[0] = (ddsh.dwMipMapCount == 0) ? 1 : ddsh.dwMipMapCount; // depth m_dwValue[1] = (ddsh.dwHeaderFlags & DDS_HEADER_FLAGS_VOLUME) ? ddsh.dwDepth : 0; if (ddsh.ddspf.dwFourCC == D3DFMT_DXT1) m_fmt = D3DFMT_DXT1; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT2) m_fmt = D3DFMT_DXT2; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT3) m_fmt = D3DFMT_DXT3; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT4) m_fmt = D3DFMT_DXT4; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT5) m_fmt = D3DFMT_DXT5; else if (ddsh.ddspf.dwFlags == DDS_RGBA && ddsh.ddspf.dwRGBBitCount == 32 && ddsh.ddspf.dwABitMask == 0xff000000) m_fmt = D3DFMT_A8R8G8B8; else if (ddsh.ddspf.dwFlags == DDS_RGB && ddsh.ddspf.dwRGBBitCount == 24) m_fmt = D3DFMT_R8G8B8; else if (ddsh.ddspf.dwFlags == DDS_RGB && ddsh.ddspf.dwRGBBitCount == 16 && ddsh.ddspf.dwGBitMask == 0x000007e0) m_fmt = D3DFMT_R5G6B5; else if (ddsh.ddspf.dwFlags == DDS_RGBA && ddsh.ddspf.dwRGBBitCount == 16 && ddsh.ddspf.dwABitMask == 0x00008000) m_fmt = D3DFMT_A1R5G5B5; else if (ddsh.ddspf.dwFlags == DDS_RGBA && ddsh.ddspf.dwRGBBitCount == 16 && ddsh.ddspf.dwABitMask == 0x0000f000) m_fmt = D3DFMT_A4R4G4B4; else return false; } return true; } bool CNTexture::Unload() { return true; } bool CNTexture::PostLoad() { if(!m_pByteDataObj) return false; LPDIRECT3DTEXTURE8 pmiptex = NULL; if(!m_bInterface) { DWORD dwMagic=MAKEFOURCC('D','D','S',' '); DWORD *pHeader = NULL; pHeader = (DWORD *)m_pByteDataObj->GetReadPtr(); if(pHeader == NULL) return false; *pHeader = dwMagic; HRESULT hr=D3DXCreateTextureFromFileInMemory(ms_pd3dDevice,pHeader,m_pByteDataObj->GetByteSize(),&pmiptex); if(hr != D3D_OK) { printf(""); } if(pmiptex == NULL) { printf(""); } } else { if (FAILED(ms_pd3dDevice->CreateTexture(m_dwWidth>>m_SkipMipLevel, m_dwHeight>>m_SkipMipLevel, m_dwValue[0]-m_SkipMipLevel, 0, m_fmt, D3DPOOL_MANAGED, &pmiptex))) { CGraphicLayerError("CTexture:ReadDDSTexture , CreateTexture is failed"); } if (FAILED(LoadAllMipSurfaces(pmiptex, m_dwValue[0]))) { MessageBox(NULL,"LoadAllMipSurface Load Failed",0,0); CGraphicLayerError("CTexture:ReadDDSTexture , LoadAllMipSurfaces is failed"); } } m_pddTexture = pmiptex; return true; } HRESULT CNTexture::LoadAllMipSurfaces(LPDIRECT3DBASETEXTURE8 ptex, long numMips) { HRESULT hr; LPDIRECT3DSURFACE8 psurf; D3DSURFACE_DESC sd; D3DLOCKED_RECT lr; LPDIRECT3DTEXTURE8 pmiptex = NULL; DWORD dwBytesPerRow; pmiptex = (LPDIRECT3DTEXTURE8)ptex; long iLevel; for (iLevel = 0; iLevel < numMips; iLevel++) { if (pmiptex != NULL) hr = pmiptex->GetSurfaceLevel(iLevel-m_SkipMipLevel, &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); if (FAILED(hr)) return hr; if (dwBytesPerRow == 0) { //fread(lr.pBits,sd.Size,1,fp); m_pByteDataObj->Read(lr.pBits,sd.Size,1); } else { DWORD yp; BYTE* pbDest = (BYTE*)lr.pBits; for (yp = 0; yp < sd.Height; yp++) { //fread(pbDest,dwBytesPerRow,1,fp); m_pByteDataObj->Read(pbDest,dwBytesPerRow,1); pbDest += lr.Pitch; } } if (pmiptex != NULL) hr = pmiptex->UnlockRect(iLevel); ReleasePpo(&psurf); } return S_OK; } LPDIRECT3DBASETEXTURE8 CNTexture::GetTexture() { if (ms_bNullTextureMode) { return ms_pNullTexture; } return m_pddTexture; } void CNTexture::NullTextureMode(bool bNullTexture) { ms_bNullTextureMode = bNullTexture; } }