gstexture.cpp
来自「网络泡泡被.net管理」· C++ 代码 · 共 1,490 行 · 第 1/3 页
CPP
1,490 行
// GsTexture.cpp: implementation of the CGsTexture class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GSLib_Internal.h"
#include "gif89a.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGsTexture::CGsTexture(CGsEngine* pEngine) : CGsSurface( pEngine )
{
m_nUser = 1;
m_keySource = "";
m_BasePoint = GPOINT(0,0);
m_dwNumMipMaps = 0;
m_width = 0;
m_height = 0;
m_dxsf = D3DX_SF_A8R8G8B8;
m_isTexture = TRUE;
m_cache_memory = NULL;
m_link_cache_gif = NULL;
m_mode_cache = 0;
m_cache_pos = 0;
m_cache_fft = GSF_UNKNOWN;
}
CGsTexture::~CGsTexture()
{
Cleanup();
}
VOID CGsTexture::Cleanup()
{
CDxSurface::Cleanup();
m_BasePoint = GPOINT(0,0);
m_dwNumMipMaps = 0;
m_width = 0;
m_height = 0;
if (m_cache_fft==GSF_GIF)
{
m_link_cache_gif = NULL;
m_cache_pos = 0;
}
else
{
SAFE_DELETE_ARRAY(m_cache_memory);
}
m_cache_fft = GSF_UNKNOWN;
// m_is_use_cache = FALSE;
}
HRESULT CGsTexture::CreateEx( DWORD width, DWORD height, DXSF dxsf, DWORD dwNumMipMaps )
{
HRESULT hr;
if(width<=0 || height<=0)
return S_OK;
if(NULL == m_pEngine)
return E_FAIL;
LPDIRECT3DDEVICE7 pD3dDevice = m_pEngine->GetD3dDevice();
if(!pD3dDevice)
return E_FAIL;
SAFE_RELEASE(m_pdds);
m_dwNumMipMaps = dwNumMipMaps;
m_dxsf = dxsf;
hr = D3DXCreateTexture( pD3dDevice, NULL, &width, &height, &dxsf, NULL, &m_pdds, &m_dwNumMipMaps );
if(FAILED(hr))
{
if(g_pDebug)
{
g_pDebug->ADD_LOG("failed to create texture(width=%dheight=%d) (name=%s)", width, height, m_keySource.c_str());
}
return hr;
}
OnCreate();
m_BasePoint = GPOINT(0,0);
m_width = width;//m_ddsd.dwWidth;
m_height = height;//m_ddsd.dwHeight;
m_isTexture = TRUE;
return hr;
}
HRESULT CGsTexture::CreateShare(CGsTexture *pTexture)
{
if(pTexture==NULL || pTexture->m_pdds==NULL)
return E_FAIL;
//if (m_pdds==pTexture->m_pdds)
//{
// return S_OK;
//}
HRESULT hr = Create(pTexture->m_pdds);
//pTexture->m_keySource = m_keySource;
//m_BasePoint = GPOINT(0,0);
//m_width = m_ddsd.dwWidth;
//m_height = m_ddsd.dwHeight;
//m_isTexture = TRUE;
return hr;
}
HRESULT CGsTexture::CreateFromFile( const TCHAR* strFile, DWORD width, DWORD height, DXSF dxsf, DWORD dwNumMipMaps )
{
HRESULT hr;
if(NULL == m_pEngine)
return E_FAIL;
LPDIRECT3DDEVICE7 pD3dDevice = m_pEngine->GetD3dDevice();
if(!pD3dDevice)
return E_FAIL;
SAFE_RELEASE(m_pdds);
m_dwNumMipMaps = dwNumMipMaps;
m_dxsf = dxsf;
hr = D3DXCreateTextureFromFile( pD3dDevice, NULL, &width, &height, &dxsf, NULL, &m_pdds, &m_dwNumMipMaps, (TCHAR*)strFile, D3DX_FT_DEFAULT );
m_pdds->GetSurfaceDesc( &m_ddsd );
m_dwColorCount = m_ddsd.ddpfPixelFormat.dwRGBBitCount;
m_BasePoint = GPOINT(0,0);
m_width = m_ddsd.dwWidth;
m_height = m_ddsd.dwHeight;
m_isTexture = TRUE;
return OnCreate();
}
HRESULT CGsTexture::CreateFromFileEx(const TCHAR *strFile, PIX24 *pCK, DXSF dxsf, DWORD dwNumMipMaps)
{
HRESULT hr;
if(NULL == m_pEngine)
return E_FAIL;
SAFE_RELEASE(m_pdds);
if(CGsFunc::FileCompareExt(strFile,"jpg"))
{
GSFBUF fbuf = CGsFunc::GSFBUF_Create(strFile, "rb");
if(fbuf.p_fstream==NULL)
return E_FAIL;
SIZE size = CGsFunc::FileGetJpegSize(&fbuf);
if(size.cx<=2048 || size.cy<=2048)
{
if(FAILED(hr=CreateEx(size.cx, size.cy, dxsf, dwNumMipMaps)))
{
fclose(fbuf.p_fstream);
return hr;
}
}
if(size.cx > m_width || size.cy > m_height)
{
CGsSurface::CreateEx(size.cx, size.cy);
m_isTexture = FALSE;
}
if(FAILED(hr=LoadFromJpegFile(&fbuf, pCK)))
{
fclose(fbuf.p_fstream);
return hr;
}
m_width = size.cx;
m_height = size.cy;
fclose(fbuf.p_fstream);
}
else if(CGsFunc::FileCompareExt(strFile,"tga"))
{
if(FAILED(hr = CreateFromTGA(strFile)))
{
return hr;
}
}
else
{
return CreateFromFile(strFile, 0, 0, dxsf, dwNumMipMaps);
}
return OnCreate();
}
VOID CGsTexture::CreateVirtual(LONG width, LONG height, LONG baseX, LONG baseY)
{
SAFE_RELEASE(m_pdds);
m_dwNumMipMaps = 0;
m_ddsd.dwWidth = width;
m_ddsd.dwHeight = height;
m_BasePoint = GPOINT(baseX,baseY);
m_width = m_ddsd.dwWidth;
m_height = m_ddsd.dwHeight;
}
//-----------------------------------------------------------------------------
// Name: Lock()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CGsTexture::BeginLock(BYTE* &pDes, LONG &lPitch)
{
if(!m_pdds)
return E_FAIL;
HRESULT hr;
DDSURFACEDESC2 ddsd;
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
hr = m_pdds->Lock (NULL, &ddsd, DDLOCK_WAIT, NULL);
if(FAILED(hr))
return hr;
pDes = (BYTE*)ddsd.lpSurface;
lPitch = ddsd.lPitch;
return hr;
}
//-----------------------------------------------------------------------------
// Name: UnLock()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CGsTexture::EndLock()
{
if(!m_pdds)
return E_FAIL;
return m_pdds->Unlock(NULL);
}
#pragma pack(push, 1)
struct t_texture_file_head
{
DWORD texture_width;
DWORD texture_height;
DXSF dxsf;
DWORD num_data;
GPOINT point_base;
BOOL bCompress;
};
struct t_compress_head
{
BYTE flag; //0-行开始标识, 1-透明标识, 2-象素标识, 0x80-结束标识
WORD count;
};
#pragma pack(pop)
HRESULT CGsTexture::Import( const TCHAR* strFile )
{
// fstream fbuf;
// fbuf.open(strFile, ios::in | ios::out | ios::binary);
// if(!fbuf)
// return false;
GSFBUF gsbuf;
if((gsbuf.p_fstream = fopen(strFile, "rb"))==NULL)
return E_FAIL;
gsbuf.pos_begin = 0;
gsbuf.file_size = 0;
HRESULT hr = Import(gsbuf);
fclose(gsbuf.p_fstream);
// fbuf.close();
return hr;
}
HRESULT CGsTexture::Import( GSFBUF &gsbuf )
{
HRESULT hr;
DWORD dwBytes = 0;
t_texture_file_head head;
fseek(gsbuf.p_fstream, gsbuf.pos_begin, SEEK_SET);
ZeroMemory((void*)&head, sizeof(t_texture_file_head));
fread(&head, sizeof(head), 1, gsbuf.p_fstream);
Cleanup();
m_BasePoint = head.point_base;
m_cache_fft = GSF_TEX;
if(head.dxsf==D3DX_SF_UNKNOWN)
{
fread(&m_ddsd, sizeof(m_ddsd), 1, gsbuf.p_fstream);
hr = Create(&m_ddsd);
Clear(0);
if(FAILED(hr))
return hr;
BYTE* pData;
LONG lPitch;
if(FAILED(hr = BeginLock(pData, lPitch)))
return hr;
char* pLine = (char*)pData;
//widthm_dwColorCount/8
for(int i=0; i<m_ddsd.dwHeight; i++)
{
fread(pLine, 1, head.num_data, gsbuf.p_fstream);
pLine += lPitch;
}
m_width = head.texture_width;
m_height = head.texture_height;
EndLock();
}
else
{
if(head.num_data!=0)
{
if(m_cache_memory==NULL)
{
m_cache_memory = new char[head.num_data];
fseek(gsbuf.p_fstream, gsbuf.pos_begin, SEEK_SET);
fread(m_cache_memory, 1, head.num_data, gsbuf.p_fstream);
}
hr = LoadFromMemory(m_cache_memory);
if(m_mode_cache==0)
{
SAFE_DELETE_ARRAY(m_cache_memory);
}
//if(FAILED(hr))
return hr;
}
else
{
hr = CreateEx(head.texture_width, head.texture_height, head.dxsf, head.num_data);
Clear(0);
if(FAILED(hr))
return hr;
if(head.dxsf!=m_dxsf)
return E_FAIL;
BYTE* pData;
LONG lPitch;
if(FAILED(hr = BeginLock(pData, lPitch)))
return hr;
char* pLine = (char*)pData;
t_compress_head ch;
for(int i=0; i<head.texture_height; i++)
{
if(false == head.bCompress)
{
// pFileBuf->read(pLine, head.texture_width*m_dwColorCount/8);
fread(pLine, 1, head.texture_width*m_dwColorCount/8, gsbuf.p_fstream);
}
else
{
char* pPixel = pLine;
while(1)
{
// pFileBuf->read((char*)&ch, sizeof(t_compress_head));
fread(&ch, sizeof(ch), 1, gsbuf.p_fstream);
switch (ch.flag)
{
case 0:
if(ch.count!=0)
goto exit_line;
break;
case 1:
pPixel += ch.count*m_dwColorCount/8;
break;
case 2:
// pFileBuf->read(pPixel, ch.count*m_dwColorCount/8);
fread(pPixel, 1, ch.count*m_dwColorCount/8, gsbuf.p_fstream);
pPixel += ch.count*m_dwColorCount/8;
break;
case 0x80:
goto exit_line;
break;
default:
assert(false);
}
}
}
exit_line:
pLine += lPitch;
}
// m_width = m_ddsd.dwWidth;
// m_height = m_ddsd.dwHeight;
m_width = head.texture_width;
m_height = head.texture_height;
EndLock();
}
}
return S_OK;
}
HRESULT CGsTexture::UpdateFromCache()
{
if(m_mode_cache>0)
{
switch(m_cache_fft) {
case GSF_TEX:
{
return LoadFromMemory(m_cache_memory);
}
break;
case GSF_GIF:
{
if(m_pEngine->CreateShareTexture(this, m_width, m_height, m_dxsf))
{
Clear(0);
return LoadFromGifCache(m_link_cache_gif, m_cache_pos);
}
return S_OK;
}
break;
}
}
return S_OK;
}
HRESULT CGsTexture::LoadFromMemory(char *pMem, D3DCOLOR crEdge)
{
HRESULT hr;
t_texture_file_head head = *((t_texture_file_head*)pMem);
pMem += sizeof(head);
// if(head.bCompress)
{
// if(m_pdds && head.dxsf==m_dxsf && GetWidth()>=head.texture_width && GetHeight()>=head.texture_height)
// {
// Clear(0);
// }
// else
// {
// SAFE_RELEASE(m_pdds);
// }
// if(m_pdds==NULL)
{
if(m_mode_cache>=2)
{
if(!m_pEngine->CreatePublicTexture(this, head.texture_width, head.texture_height, head.dxsf))
{
return S_OK;
}
Clear(0);
}
else if (m_mode_cache==1)
{
if(!m_pEngine->CreateShareTexture(this, head.texture_width, head.texture_height, head.dxsf))
{
return S_OK;
}
Clear(0);
}
else
{
hr = CreateEx(head.texture_width, head.texture_height, head.dxsf, head.num_data);
m_BasePoint = head.point_base;
if(FAILED(hr))
return hr;
}
//m_BasePoint = head.point_base;
}
}
if(head.dxsf!=m_dxsf)
return E_FAIL;
BYTE* pData;
LONG lPitch;
if(FAILED(hr = BeginLock(pData, lPitch)))
return hr;
if(head.bCompress)
{
char* pLine = (char*)pData;
t_compress_head ch;
for(int i=0; i<head.texture_height; i++)
{
char* pPixel = pLine;
int color_byte = m_dwColorCount/8;
int ch_byte;
while(1)
{
ch = *((t_compress_head*)pMem);
pMem += sizeof(t_compress_head);
switch (ch.flag)
{
case 0:
if(ch.count!=0)
goto exit_line;
break;
case 1:
pPixel += ch.count*color_byte;
break;
case 2:
ch_byte = ch.count*color_byte;
memcpy(pPixel, pMem, ch_byte);
pMem += ch_byte;
pPixel += ch_byte;
break;
case 0x80:
goto exit_line;
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?