// Texture.cpp: implementation of the CTexture class. // ////////////////////////////////////////////////////////////////////// #include "Texture.h" #include "3DMath.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// typedef LPDIRECT3DTEXTURE8 DXTEXTURE; LPDIRECT3DDEVICE8 CTexture::m_pd3dDevice; char CTexture::m_strPath[TEXTURENAMEBUFFER]; CTextureContainer CTexture::m_TextureContainer; int CTexture::m_SkipMipLevel=0; unsigned char *CTexture::m_pReadBuffer=NULL; int GetNumberOfBits( int mask ) { for( int nBits = 0; mask; nBits++ ) mask = mask & ( mask - 1 ); return nBits; } CTexture::CTexture() { strcpy(m_strName,""); m_pddTexture=NULL; m_bCreateEmpty=false; if(m_pReadBuffer==NULL) { int nSize=1398256*4; m_pReadBuffer=new unsigned char[nSize]; } } CTexture::~CTexture() { if(m_bCreateEmpty) { m_pddTexture->Release(); } Unload(); } void CTexture::Init(LPDIRECT3DDEVICE8 pd3dDevice) { m_pd3dDevice=pd3dDevice; strcpy(m_strPath,""); } void CTexture::LoadNotMessage(char *filename,DWORD stage) { if(strcmp(filename,"")==0) return; strcpy(m_strName,filename); m_stage=stage; int nUsedText=m_TextureContainer.FindTexture(filename); if(nUsedText>=0) { m_pddTexture=m_TextureContainer.AddUsedTexture(nUsedText); if(m_pddTexture) { D3DSURFACE_DESC ddsc; ((LPDIRECT3DTEXTURE8)m_pddTexture)->GetLevelDesc(0,&ddsc); m_dwWidth=ddsc.Width; m_dwHeight=ddsc.Height; return; } } //LPDIRECT3DBASETEXTURE8 pddsTemp = NULL; m_pddTexture=NULL; if(strstr(m_strPath,"Interface")==0) { if(ReadDDSTextureNotMessage(m_pddTexture,0) == -1) m_pddTexture = NULL; } else { if(ReadDDSTextureNotMessage(m_pddTexture,1) == -1) m_pddTexture = NULL; } m_TextureContainer.AddTexture(filename,m_pddTexture); //pddsTemp->Release(); //pddsTemp=NULL; } void CTexture::LoadNotCache(char *filename,DWORD stage) { if(strcmp(filename,"")==0) return; strcpy(m_strName,filename); m_stage=stage; //LPDIRECT3DBASETEXTURE8 pddsTemp = NULL; m_pddTexture=NULL; if(strstr(m_strPath,"Interface")==0) { ReadDDSTexture( m_pddTexture ,0); } else { ReadDDSTexture( m_pddTexture ,1); } //pddsTemp->Release(); //pddsTemp=NULL; } void CTexture::Load(char *filename, DWORD stage) { if(strcmp(filename,"")==0) return; strcpy(m_strName,filename); m_stage=stage; int nUsedText=m_TextureContainer.FindTexture(filename); if(nUsedText>=0) { m_pddTexture=m_TextureContainer.AddUsedTexture(nUsedText); if(m_pddTexture) { D3DSURFACE_DESC ddsc; ((LPDIRECT3DTEXTURE8)m_pddTexture)->GetLevelDesc(0,&ddsc); m_dwWidth=ddsc.Width; m_dwHeight=ddsc.Height; return; } } //LPDIRECT3DBASETEXTURE8 pddsTemp = NULL; m_pddTexture=NULL; if(strstr(m_strPath,"Interface")==0) { ReadDDSTexture( m_pddTexture ,0); } else { ReadDDSTexture( m_pddTexture ,1); } m_TextureContainer.AddTexture(filename,m_pddTexture); //pddsTemp->Release(); //pddsTemp=NULL; } int CTexture::ReadDDSTextureNotMessage(LPDIRECT3DBASETEXTURE8 &pddsTemp,int nMethod) { char strFullName[TEXTURENAMEBUFFER]; memset(strFullName, 0, TEXTURENAMEBUFFER); if(strcmp(m_strPath, "")) { strcpy(strFullName,m_strPath); strcat(strFullName,"\\"); } strcat(strFullName,m_strName); int lens=strlen(strFullName); strFullName[lens-1]='s'; strFullName[lens-2]='d'; strFullName[lens-3]='d'; if(nMethod) { FILE* fp=fopen(strFullName,"rb"); if(fp==NULL) { return -1; /* char msg[256]; sprintf(msg,"File not found %s",strFullName); MessageBox(NULL,msg,0,0);*/ } DWORD dwMagic; DDS_HEADER ddsh; LPDIRECT3DTEXTURE8 pmiptex = NULL; fread(&dwMagic,sizeof(dwMagic),1,fp); fread(&ddsh,sizeof(ddsh),1,fp); if (ddsh.dwSize != sizeof(ddsh)) CGraphicLayerError("CTexture:ReadDDSTexture , This is not dds format"); DWORD dwWidth = ddsh.dwWidth; DWORD dwHeight = ddsh.dwHeight; DWORD numMips = ddsh.dwMipMapCount; DWORD dwDepth=0; m_dwWidth=ddsh.dwWidth; m_dwHeight=ddsh.dwHeight; if (numMips == 0) numMips = 1; if (ddsh.dwHeaderFlags & DDS_HEADER_FLAGS_VOLUME) dwDepth = ddsh.dwDepth; else dwDepth = 0; D3DFORMAT fmt; if (ddsh.ddspf.dwFourCC == D3DFMT_DXT1) fmt = D3DFMT_DXT1; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT2) fmt = D3DFMT_DXT2; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT3) fmt = D3DFMT_DXT3; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT4) fmt = D3DFMT_DXT4; else if (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 -1; if (FAILED(m_pd3dDevice->CreateTexture(dwWidth>>m_SkipMipLevel, dwHeight>>m_SkipMipLevel, numMips-m_SkipMipLevel, 0, fmt, D3DPOOL_MANAGED, &pmiptex))) { CGraphicLayerError("CTexture:ReadDDSTexture , CreateTexture is failed"); } if (FAILED(LoadAllMipSurfaces(pmiptex, numMips, fp))) { fclose(fp); pddsTemp = NULL; return -1; /*MessageBox(NULL,"LoadAllMipSurface Load Failed",0,0); MessageBox(NULL,strFullName,0,0); CGraphicLayerError("CTexture:ReadDDSTexture , LoadAllMipSurfaces is failed");*/ } fclose(fp); pddsTemp = pmiptex; } else { HANDLE hFile; hFile=CreateFile(strFullName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if( hFile==INVALID_HANDLE_VALUE) { pddsTemp = NULL; return -1; /* char msg[256]; sprintf(msg,"File not found %s",strFullName); MessageBox(NULL,msg,0,0);*/ } DWORD dwTextureFileSize=GetFileSize(hFile,NULL); //unsigned char *pFileBuffer=new unsigned char[dwTextureFileSize]; DWORD dwReaded; ReadFile(hFile,m_pReadBuffer,dwTextureFileSize,&dwReaded,NULL); CloseHandle(hFile); DWORD dwMagic=MAKEFOURCC('D','D','S',' '); DWORD *p=(DWORD*)m_pReadBuffer; *p=dwMagic; LPDIRECT3DTEXTURE8 pmiptex = NULL; HRESULT hr=D3DXCreateTextureFromFileInMemory(m_pd3dDevice,m_pReadBuffer,dwTextureFileSize,&pmiptex); pddsTemp = pmiptex; } return 0; } void CTexture::ReadDDSTexture(LPDIRECT3DBASETEXTURE8 &pddsTemp,int nMethod) { char strFullName[TEXTURENAMEBUFFER]; memset(strFullName, 0, TEXTURENAMEBUFFER); if(strcmp(m_strPath, "")) { strcpy(strFullName,m_strPath); strcat(strFullName,"\\"); } strcat(strFullName,m_strName); int lens=strlen(strFullName); strFullName[lens-1]='s'; strFullName[lens-2]='d'; strFullName[lens-3]='d'; if(nMethod) { FILE* fp=fopen(strFullName,"rb"); if(fp==NULL) { char msg[256]; sprintf(msg,"File not found %s",strFullName); MessageBox(NULL,msg,0,0); } DWORD dwMagic; DDS_HEADER ddsh; LPDIRECT3DTEXTURE8 pmiptex = NULL; fread(&dwMagic,sizeof(dwMagic),1,fp); fread(&ddsh,sizeof(ddsh),1,fp); if (ddsh.dwSize != sizeof(ddsh)) CGraphicLayerError("CTexture:ReadDDSTexture , This is not dds format"); DWORD dwWidth = ddsh.dwWidth; DWORD dwHeight = ddsh.dwHeight; DWORD numMips = ddsh.dwMipMapCount; DWORD dwDepth=0; m_dwWidth=ddsh.dwWidth; m_dwHeight=ddsh.dwHeight; if (numMips == 0) numMips = 1; if (ddsh.dwHeaderFlags & DDS_HEADER_FLAGS_VOLUME) dwDepth = ddsh.dwDepth; else dwDepth = 0; D3DFORMAT fmt; if (ddsh.ddspf.dwFourCC == D3DFMT_DXT1) fmt = D3DFMT_DXT1; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT2) fmt = D3DFMT_DXT2; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT3) fmt = D3DFMT_DXT3; else if (ddsh.ddspf.dwFourCC == D3DFMT_DXT4) fmt = D3DFMT_DXT4; else if (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; if (FAILED(m_pd3dDevice->CreateTexture(dwWidth>>m_SkipMipLevel, dwHeight>>m_SkipMipLevel, numMips-m_SkipMipLevel, 0, fmt, D3DPOOL_MANAGED, &pmiptex))) { CGraphicLayerError("CTexture:ReadDDSTexture , CreateTexture is failed"); } if (FAILED(LoadAllMipSurfaces(pmiptex, numMips, fp))) { MessageBox(NULL,"LoadAllMipSurface Load Failed",0,0); MessageBox(NULL,strFullName,0,0); CGraphicLayerError("CTexture:ReadDDSTexture , LoadAllMipSurfaces is failed"); } fclose(fp); pddsTemp = pmiptex; } else { HANDLE hFile; hFile=CreateFile(strFullName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if( hFile==INVALID_HANDLE_VALUE) { char msg[256]; sprintf(msg,"File not found %s",strFullName); MessageBox(NULL,msg,0,0); } DWORD dwTextureFileSize=GetFileSize(hFile,NULL); //unsigned char *pFileBuffer=new unsigned char[dwTextureFileSize]; DWORD dwReaded; ReadFile(hFile,m_pReadBuffer,dwTextureFileSize,&dwReaded,NULL); CloseHandle(hFile); DWORD dwMagic=MAKEFOURCC('D','D','S',' '); DWORD *p=(DWORD*)m_pReadBuffer; *p=dwMagic; LPDIRECT3DTEXTURE8 pmiptex = NULL; HRESULT hr=D3DXCreateTextureFromFileInMemory(m_pd3dDevice,m_pReadBuffer,dwTextureFileSize,&pmiptex); pddsTemp = pmiptex; } } void CTexture::DeleteTexture() { if(m_pddTexture) m_TextureContainer.DeleteTexture(m_strName); } void CTexture::CreateEmpty(long lSx, long lSy,D3DFORMAT format,D3DPOOL pool,long mip) { LPDIRECT3DTEXTURE8 pddEmpty; m_pd3dDevice->CreateTexture(lSx,lSy,mip,0,format,pool,&pddEmpty); m_pddTexture=pddEmpty; m_bCreateEmpty=true; m_dwWidth=lSx; m_dwHeight=lSy; } void CTexture::FillColor(DWORD color) { D3DSURFACE_DESC sd; LPDIRECT3DTEXTURE8 pddEmpty; pddEmpty=(LPDIRECT3DTEXTURE8)m_pddTexture; pddEmpty->GetLevelDesc(0,&sd); D3DLOCKED_RECT lr; pddEmpty->LockRect(0,&lr,NULL,0); DWORD *pSurface=(DWORD*)lr.pBits; //color light;//=color(rand()%255,rand()%255,rand()%255); //color asdf; /* unsigned char r,g,b; r=(rand()%200)+55; g=rand()%255; b=rand()%255; */ for(DWORD ix=0;ixUnlockRect(0); } HRESULT CTexture::LoadAllMipSurfaces(LPDIRECT3DBASETEXTURE8 ptex,long numMips, FILE *fp) { 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); } else { DWORD yp; BYTE* pbDest = (BYTE*)lr.pBits; for (yp = 0; yp < sd.Height; yp++) { fread(pbDest,dwBytesPerRow,1,fp); pbDest += lr.Pitch; } } if (pmiptex != NULL) hr = pmiptex->UnlockRect(iLevel); ReleasePpo(&psurf); } return S_OK; } void* CTexture::Lock() { LPDIRECT3DTEXTURE8 pddEmpty; pddEmpty=(LPDIRECT3DTEXTURE8)m_pddTexture; D3DLOCKED_RECT lr; pddEmpty->LockRect(0,&lr,NULL,0); return lr.pBits; } void CTexture::Unlock() { LPDIRECT3DTEXTURE8 pddEmpty; pddEmpty=(LPDIRECT3DTEXTURE8)m_pddTexture; pddEmpty->UnlockRect(0); } void CTexture::Unload() { if(m_pddTexture) m_TextureContainer.DeleteTexture(m_strName); m_pddTexture=NULL; } void CTexture::ChangeTextureIntension( byte *pImage, int iSize, float fColorFactor) { // Texture Color ³óµµº¯È­ (D3DFMT_R8G8B8 ¿ë) int i; for( i=0; i < iSize / 3; i++ ) { float fScale = 1.0f; float fTmp = 0.0f; float fR = 0.0f; float fG = 0.0f; float fB = 0.0f; fR = (float)pImage[0]; fG = (float)pImage[1]; fB = (float)pImage[2]; fR = fR * fColorFactor / 255.0f; fG = fG * fColorFactor / 255.0f; fB = fB * fColorFactor / 255.0f; if( ( fR > 1.0f ) && ( fTmp = ( 1.0f / fR ) ) < fScale ) fScale = fTmp; if( ( fG > 1.0f ) && ( fTmp = ( 1.0f / fG ) ) < fScale ) fScale = fTmp; if( ( fB > 1.0f ) && ( fTmp = ( 1.0f / fB ) ) < fScale ) fScale = fTmp; fScale *= 255.0f; fR *= fScale; fG *= fScale; fB *= fScale; pImage[0] = ( byte )fR; pImage[1] = ( byte )fG; pImage[2] = ( byte )fB; pImage +=3; } } void CTexture::CreateEmptyTexture( unsigned int uiX, unsigned int uiY, unsigned int uiMip,D3DFORMAT dFormat, D3DPOOL dPool) { DXTEXTURE lpEmptyTexture; HRESULT hr = m_pd3dDevice->CreateTexture( uiX,uiY,uiMip,0,dFormat,dPool,&lpEmptyTexture); if(hr == D3DERR_INVALIDCALL) MessageBox(NULL,"Err1","error",MB_OK); else if(hr == D3DERR_OUTOFVIDEOMEMORY) MessageBox(NULL,"Err2","error",MB_OK); else if(hr == E_OUTOFMEMORY) MessageBox(NULL,"Err3","error",MB_OK); m_pddTexture = lpEmptyTexture; m_dwWidth = uiX; m_dwHeight = uiY; } void CTexture::FillTexture( byte * pByte) { D3DSURFACE_DESC dTextureSurf; DXTEXTURE lpEmptyTexture; lpEmptyTexture = (DXTEXTURE)m_pddTexture; lpEmptyTexture->GetLevelDesc( 0, &dTextureSurf ); D3DLOCKED_RECT lRect; HRESULT hr = lpEmptyTexture->LockRect( 0, &lRect, NULL, 0); if(hr == D3DERR_INVALIDCALL) MessageBox(NULL,"te","tt",MB_OK); byte *pSurface = (byte *)lRect.pBits; unsigned int iImageSize = dTextureSurf.Size;//dTextureSurf.Width * dTextureSurf.Height; memcpy( pSurface,pByte,sizeof(byte) * iImageSize); lpEmptyTexture->UnlockRect( 0 ); } void CTexture::SetBitTexture( int iWidth, int iHeight, WORD* pSrc ) { D3DSURFACE_DESC dTextureSurf ; DXTEXTURE lpEmptyTexture ; D3DLOCKED_RECT lRect ; lpEmptyTexture = ( DXTEXTURE )m_pddTexture ; lpEmptyTexture->GetLevelDesc( 0, &dTextureSurf ) ; HRESULT hr = lpEmptyTexture->LockRect( 0, &lRect, NULL, 0 ) ; if ( hr == D3DERR_INVALIDCALL ) MessageBox( NULL,"te","tt",MB_OK ) ; WORD* pSurface = ( WORD * )lRect.pBits ; // unsigned int iImageSize = dTextureSurf.Size;//dTextureSurf.Width * dTextureSurf.Height; // memset( pSurface, 0, sizeof(WORD) * iImageSize ) ; BYTE* pbyTempBuff = ( BYTE* )pSrc ; WORD* pwTempBuff = ( WORD* )( pbyTempBuff + 1 ) ; int CurSrc = 0 ; int CurDest = 0 ; for ( DWORD ix = 0 ;ix < iHeight ; ix ++ ) { CurDest = dTextureSurf.Width * ix ; for ( DWORD iy = 0 ; iy < iWidth ;iy ++ ) { pSurface[ CurDest ] = pwTempBuff[ CurSrc ] ; ++ CurDest ; ++ CurSrc ; } } lpEmptyTexture->UnlockRect( 0 ) ; } void CTexture::DeleteAllCashTexture() { m_TextureContainer.DeleteAllTexture(); }