📄 d3dtextr.cpp
字号:
for( DWORD y=0; y<ddsd.dwHeight; y++ )
{
WORD* p16 = (WORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
DWORD* p32 = (DWORD*)((BYTE*)ddsd.lpSurface + y*ddsd.lPitch);
for( DWORD x=0; x<ddsd.dwWidth; x++ )
{
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 16 )
{
if( ( *p16 &= dwRGBMask ) != dwColorkey )
*p16 |= dwAlphaMask;
p16++;
}
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 32 )
{
if( ( *p32 &= dwRGBMask ) != dwColorkey )
*p32 |= dwAlphaMask;
p32++;
}
}
}
m_pddsSurface->Unlock( NULL );
}
}
pDD->Release();
return S_OK;;
}
//-----------------------------------------------------------------------------
// Name: CopyRGBADataToSurface()
// Desc: Invalidates the current texture objects and rebuilds new ones
// using the new device.
//-----------------------------------------------------------------------------
HRESULT TextureContainer::CopyRGBADataToSurface()
{
// Get a DDraw object to create a temporary surface
LPDIRECTDRAW7 pDD;
m_pddsSurface->GetDDInterface( (VOID**)&pDD );
// Setup the new surface desc
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof(ddsd);
m_pddsSurface->GetSurfaceDesc( &ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|
DDSD_TEXTURESTAGE;
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_SYSTEMMEMORY;
ddsd.ddsCaps.dwCaps2 = 0L;
ddsd.dwWidth = m_dwWidth;
ddsd.dwHeight = m_dwHeight;
// Create a new surface for the texture
LPDIRECTDRAWSURFACE7 pddsTempSurface;
HRESULT hr;
if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) )
{
pDD->Release();
return NULL;
}
while( pddsTempSurface->Lock( NULL, &ddsd, 0, 0 ) == DDERR_WASSTILLDRAWING );
DWORD lPitch = ddsd.lPitch;
BYTE* pBytes = (BYTE*)ddsd.lpSurface;
DWORD dwRMask = ddsd.ddpfPixelFormat.dwRBitMask;
DWORD dwGMask = ddsd.ddpfPixelFormat.dwGBitMask;
DWORD dwBMask = ddsd.ddpfPixelFormat.dwBBitMask;
DWORD dwAMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
DWORD dwRShiftL = 8, dwRShiftR = 0;
DWORD dwGShiftL = 8, dwGShiftR = 0;
DWORD dwBShiftL = 8, dwBShiftR = 0;
DWORD dwAShiftL = 8, dwAShiftR = 0;
DWORD dwMask;
for( dwMask=dwRMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwRShiftR++;
for( ; dwMask; dwMask>>=1 ) dwRShiftL--;
for( dwMask=dwGMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwGShiftR++;
for( ; dwMask; dwMask>>=1 ) dwGShiftL--;
for( dwMask=dwBMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwBShiftR++;
for( ; dwMask; dwMask>>=1 ) dwBShiftL--;
for( dwMask=dwAMask; dwMask && !(dwMask&0x1); dwMask>>=1 ) dwAShiftR++;
for( ; dwMask; dwMask>>=1 ) dwAShiftL--;
for( DWORD y=0; y<ddsd.dwHeight; y++ )
{
DWORD* pDstData32 = (DWORD*)pBytes;
WORD* pDstData16 = (WORD*)pBytes;
for( DWORD x=0; x<ddsd.dwWidth; x++ )
{
DWORD dwPixel = m_pRGBAData[y*ddsd.dwWidth+x];
BYTE r = (BYTE)((dwPixel>>24)&0x000000ff);
BYTE g = (BYTE)((dwPixel>>16)&0x000000ff);
BYTE b = (BYTE)((dwPixel>> 8)&0x000000ff);
BYTE a = (BYTE)((dwPixel>> 0)&0x000000ff);
DWORD dr = ((r>>(dwRShiftL))<<dwRShiftR)&dwRMask;
DWORD dg = ((g>>(dwGShiftL))<<dwGShiftR)&dwGMask;
DWORD db = ((b>>(dwBShiftL))<<dwBShiftR)&dwBMask;
DWORD da = ((a>>(dwAShiftL))<<dwAShiftR)&dwAMask;
if( 32 == ddsd.ddpfPixelFormat.dwRGBBitCount )
pDstData32[x] = (DWORD)(dr+dg+db+da);
else
pDstData16[x] = (WORD)(dr+dg+db+da);
}
pBytes += ddsd.lPitch;
}
pddsTempSurface->Unlock(0);
// Copy the temp surface to the real texture surface
m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL );
// Done with the temp objects
pddsTempSurface->Release();
pDD->Release();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_SetTexturePath()
// Desc: Enumeration callback routine to find a best-matching texture format.
//-----------------------------------------------------------------------------
VOID D3DTextr_SetTexturePath( TCHAR* strTexturePath )
{
if( NULL == strTexturePath )
strTexturePath = _T("");
lstrcpy( g_strTexturePath, strTexturePath );
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_CreateTextureFromFile()
// Desc: Is passed a filename and creates a local Bitmap from that file.
// The texture can not be used until it is restored, however.
//-----------------------------------------------------------------------------
HRESULT D3DTextr_CreateTextureFromFile( TCHAR* strName, DWORD dwStage,
DWORD dwFlags )
{
// Check parameters
if( NULL == strName )
return E_INVALIDARG;
// Check first to see if the texture is already loaded
if( NULL != FindTexture( strName ) )
return S_OK;
// Allocate and add the texture to the linked list of textures;
TextureContainer* ptcTexture = new TextureContainer( strName, dwStage,
dwFlags );
if( NULL == ptcTexture )
return E_OUTOFMEMORY;
// Create a bitmap and load the texture file into it,
if( FAILED( ptcTexture->LoadImageData() ) )
{
delete ptcTexture;
return E_FAIL;
}
// Save the image's dimensions
if( ptcTexture->m_hbmBitmap )
{
BITMAP bm;
GetObject( ptcTexture->m_hbmBitmap, sizeof(BITMAP), &bm );
ptcTexture->m_dwWidth = (DWORD)bm.bmWidth;
ptcTexture->m_dwHeight = (DWORD)bm.bmHeight;
ptcTexture->m_dwBPP = (DWORD)bm.bmBitsPixel;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_CreateEmptyTexture()
// Desc: Creates an empty texture.
//-----------------------------------------------------------------------------
HRESULT D3DTextr_CreateEmptyTexture( TCHAR* strName, DWORD dwWidth,
DWORD dwHeight, DWORD dwStage,
DWORD dwFlags )
{
// Check parameters
if( NULL == strName )
return E_INVALIDARG;
// Check first to see if the texture is already loaded
if( NULL != FindTexture( strName ) )
return E_FAIL;
// Allocate and add the texture to the linked list of textures;
TextureContainer* ptcTexture = new TextureContainer( strName, dwStage,
dwFlags );
if( NULL == ptcTexture )
return E_OUTOFMEMORY;
// Save dimensions
ptcTexture->m_dwWidth = dwWidth;
ptcTexture->m_dwHeight = dwHeight;
ptcTexture->m_dwBPP = 16;
if( ptcTexture->m_dwFlags & D3DTEXTR_32BITSPERPIXEL )
ptcTexture->m_dwBPP = 32;
// Save alpha usage flag
if( dwFlags & D3DTEXTR_CREATEWITHALPHA )
ptcTexture->m_bHasAlpha = TRUE;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_Restore()
// Desc: Invalidates the current texture objects and rebuilds new ones
// using the new device.
//-----------------------------------------------------------------------------
HRESULT D3DTextr_Restore( TCHAR* strName, LPDIRECT3DDEVICE7 pd3dDevice )
{
TextureContainer* ptcTexture = FindTexture( strName );
if( NULL == ptcTexture )
return DDERR_NOTFOUND;
// Restore the texture (this recreates the new surface for this device).
return ptcTexture->Restore( pd3dDevice );
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_RestoreAllTextures()
// Desc: This function is called when a mode is changed. It updates all
// texture objects to be valid with the new device.
//-----------------------------------------------------------------------------
HRESULT D3DTextr_RestoreAllTextures( LPDIRECT3DDEVICE7 pd3dDevice )
{
TextureContainer* ptcTexture = g_ptcTextureList;
while( ptcTexture )
{
D3DTextr_Restore( ptcTexture->m_strName, pd3dDevice );
ptcTexture = ptcTexture->m_pNext;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_Invalidate()
// Desc: Used to bump a texture out of (video) memory, this function
// actually destroys the d3dtexture and ddsurface of the texture
//-----------------------------------------------------------------------------
HRESULT D3DTextr_Invalidate( TCHAR* strName )
{
TextureContainer* ptcTexture = FindTexture( strName );
if( NULL == ptcTexture )
return DDERR_NOTFOUND;
SAFE_RELEASE( ptcTexture->m_pddsSurface );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_InvalidateAllTextures()
// Desc: This function is called when a mode is changed. It invalidates
// all texture objects so their device can be safely released.
//-----------------------------------------------------------------------------
HRESULT D3DTextr_InvalidateAllTextures()
{
TextureContainer* ptcTexture = g_ptcTextureList;
while( ptcTexture )
{
SAFE_RELEASE( ptcTexture->m_pddsSurface );
ptcTexture = ptcTexture->m_pNext;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_DestroyTexture()
// Desc: Frees the resources for the specified texture container
//-----------------------------------------------------------------------------
HRESULT D3DTextr_DestroyTexture( TCHAR* strName )
{
TextureContainer* ptcTexture = FindTexture( strName );
SAFE_DELETE( ptcTexture );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: D3DTextr_GetSurface()
// Desc: Returns a pointer to a d3dSurface from the name of the texture
//-----------------------------------------------------------------------------
LPDIRECTDRAWSURFACE7 D3DTextr_GetSurface( TCHAR* strName )
{
TextureContainer* ptcTexture = FindTexture( strName );
return ptcTexture ? ptcTexture->m_pddsSurface : NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -