?? d3dtextr.cpp
字號:
fseek( file, tga.IDLength, SEEK_CUR );
m_dwWidth = tga.ImageWidth;
m_dwHeight = tga.ImageHeight;
m_dwBPP = tga.PixelDepth;
m_pRGBAData = new DWORD[m_dwWidth*m_dwHeight];
if( m_pRGBAData == NULL )
{
fclose(file);
return E_FAIL;
}
for( DWORD y=0; y<m_dwHeight; y++ )
{
DWORD dwOffset = y*m_dwWidth;
if( 0 == ( tga.ImageDescriptor & 0x0010 ) )
dwOffset = (m_dwHeight-y-1)*m_dwWidth;
for( DWORD x=0; x<m_dwWidth; x )
{
if( tga.ImageType == 10 )
{
BYTE PacketInfo = getc( file );
WORD PacketType = 0x80 & PacketInfo;
WORD PixelCount = ( 0x007f & PacketInfo ) + 1;
if( PacketType )
{
DWORD b = getc( file );
DWORD g = getc( file );
DWORD r = getc( file );
DWORD a = 0xff;
if( m_dwBPP == 32 )
a = getc( file );
while( PixelCount-- )
{
m_pRGBAData[dwOffset+x] = (r<<24L)+(g<<16L)+(b<<8L)+(a);
x++;
}
}
else
{
while( PixelCount-- )
{
BYTE b = getc( file );
BYTE g = getc( file );
BYTE r = getc( file );
BYTE a = 0xff;
if( m_dwBPP == 32 )
a = getc( file );
m_pRGBAData[dwOffset+x] = (r<<24L)+(g<<16L)+(b<<8L)+(a);
x++;
}
}
}
else
{
BYTE b = getc( file );
BYTE g = getc( file );
BYTE r = getc( file );
BYTE a = 0xff;
if( m_dwBPP == 32 )
a = getc( file );
m_pRGBAData[dwOffset+x] = (r<<24L)+(g<<16L)+(b<<8L)+(a);
x++;
}
}
}
fclose( file );
// Check for alpha content
for( DWORD i=0; i<(m_dwWidth*m_dwHeight); i++ )
{
if( m_pRGBAData[i] & 0x000000ff != 0xff )
{
m_bHasAlpha = TRUE;
break;
}
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Restore()
// Desc: Rebuilds the texture surface using the new device.
//-----------------------------------------------------------------------------
HRESULT TextureContainer::Restore( LPDIRECT3DDEVICE7 pd3dDevice )
{
// Release any previously created objects
SAFE_RELEASE( m_pddsSurface );
// Check params
if( NULL == pd3dDevice )
return DDERR_INVALIDPARAMS;
// Get the device caps
D3DDEVICEDESC7 ddDesc;
if( FAILED( pd3dDevice->GetCaps( &ddDesc) ) )
return E_FAIL;
// Setup the new surface desc
DDSURFACEDESC2 ddsd;
D3DUtil_InitSurfaceDesc( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|
DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE;
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
ddsd.dwTextureStage = m_dwStage;
ddsd.dwWidth = m_dwWidth;
ddsd.dwHeight = m_dwHeight;
// Turn on texture management for hardware devices
if( ddDesc.deviceGUID == IID_IDirect3DHALDevice )
ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
else if( ddDesc.deviceGUID == IID_IDirect3DTnLHalDevice )
ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
// Adjust width and height to be powers of 2, if the device requires it
if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 )
{
for( ddsd.dwWidth=1; m_dwWidth>ddsd.dwWidth; ddsd.dwWidth<<=1 );
for( ddsd.dwHeight=1; m_dwHeight>ddsd.dwHeight; ddsd.dwHeight<<=1 );
}
// Limit max texture sizes, if the driver can't handle large textures
DWORD dwMaxWidth = ddDesc.dwMaxTextureWidth;
DWORD dwMaxHeight = ddDesc.dwMaxTextureHeight;
ddsd.dwWidth = min( ddsd.dwWidth, ( dwMaxWidth ? dwMaxWidth : 256 ) );
ddsd.dwHeight = min( ddsd.dwHeight, ( dwMaxHeight ? dwMaxHeight : 256 ) );
// Make the texture square, if the driver requires it
if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY )
{
if( ddsd.dwWidth > ddsd.dwHeight ) ddsd.dwHeight = ddsd.dwWidth;
else ddsd.dwWidth = ddsd.dwHeight;
}
// Setup the structure to be used for texture enumration.
TEXTURESEARCHINFO tsi;
tsi.bFoundGoodFormat = FALSE;
tsi.pddpf = &ddsd.ddpfPixelFormat;
tsi.dwDesiredBPP = m_dwBPP;
tsi.bUsePalette = ( m_dwBPP <= 8 );
tsi.bUseAlpha = m_bHasAlpha;
if( m_dwFlags & D3DTEXTR_16BITSPERPIXEL )
tsi.dwDesiredBPP = 16;
else if( m_dwFlags & D3DTEXTR_32BITSPERPIXEL )
tsi.dwDesiredBPP = 32;
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
{
if( tsi.bUsePalette )
{
if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE )
{
tsi.bUseAlpha = TRUE;
tsi.bUsePalette = TRUE;
}
else
{
tsi.bUseAlpha = TRUE;
tsi.bUsePalette = FALSE;
}
}
}
// Enumerate the texture formats, and find the closest device-supported
// texture pixel format
pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi );
// If we couldn't find a format, let's try a default format
if( FALSE == tsi.bFoundGoodFormat )
{
tsi.bUsePalette = FALSE;
tsi.dwDesiredBPP = 16;
pd3dDevice->EnumTextureFormats( TextureSearchCallback, &tsi );
// If we still fail, we cannot create this texture
if( FALSE == tsi.bFoundGoodFormat )
return E_FAIL;
}
// Get the DirectDraw interface for creating surfaces
LPDIRECTDRAW7 pDD;
LPDIRECTDRAWSURFACE7 pddsRender;
pd3dDevice->GetRenderTarget( &pddsRender );
pddsRender->GetDDInterface( (VOID**)&pDD );
pddsRender->Release();
// Create a new surface for the texture
HRESULT hr = pDD->CreateSurface( &ddsd, &m_pddsSurface, NULL );
// Done with DDraw
pDD->Release();
if( FAILED(hr) )
return hr;
// For bitmap-based textures, copy the bitmap image.
if( m_hbmBitmap )
return CopyBitmapToSurface();
if( m_pRGBAData )
return CopyRGBADataToSurface();
// At this point, code can be added to handle other file formats (such as
// .dds files, .jpg files, etc.).
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CopyBitmapToSurface()
// Desc: Copies the image of a bitmap into a surface
//-----------------------------------------------------------------------------
HRESULT TextureContainer::CopyBitmapToSurface()
{
// Get a DDraw object to create a temporary surface
LPDIRECTDRAW7 pDD;
m_pddsSurface->GetDDInterface( (VOID**)&pDD );
// Get the bitmap structure (to extract width, height, and bpp)
BITMAP bm;
GetObject( m_hbmBitmap, sizeof(BITMAP), &bm );
// 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 = bm.bmWidth;
ddsd.dwHeight = bm.bmHeight;
// Create a new surface for the texture
LPDIRECTDRAWSURFACE7 pddsTempSurface;
HRESULT hr;
if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTempSurface, NULL ) ) )
{
pDD->Release();
return hr;
}
// Get a DC for the bitmap
HDC hdcBitmap = CreateCompatibleDC( NULL );
if( NULL == hdcBitmap )
{
pddsTempSurface->Release();
pDD->Release();
return hr;
}
SelectObject( hdcBitmap, m_hbmBitmap );
// Handle palettized textures. Need to attach a palette
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 )
{
LPDIRECTDRAWPALETTE pPalette;
DWORD dwPaletteFlags = DDPCAPS_8BIT|DDPCAPS_ALLOW256;
DWORD pe[256];
WORD wNumColors = GetDIBColorTable( hdcBitmap, 0, 256, (RGBQUAD*)pe );
// Create the color table
for( WORD i=0; i<wNumColors; i++ )
{
pe[i] = RGB( GetBValue(pe[i]), GetGValue(pe[i]), GetRValue(pe[i]) );
// Handle textures with transparent pixels
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
{
// Set alpha for opaque pixels
if( m_dwFlags & D3DTEXTR_TRANSPARENTBLACK )
{
if( pe[i] != 0x00000000 )
pe[i] |= 0xff000000;
}
else if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE )
{
if( pe[i] != 0x00ffffff )
pe[i] |= 0xff000000;
}
}
}
// Add DDPCAPS_ALPHA flag for textures with transparent pixels
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
dwPaletteFlags |= DDPCAPS_ALPHA;
// Create & attach a palette
pDD->CreatePalette( dwPaletteFlags, (PALETTEENTRY*)pe, &pPalette, NULL );
pddsTempSurface->SetPalette( pPalette );
m_pddsSurface->SetPalette( pPalette );
SAFE_RELEASE( pPalette );
}
// Copy the bitmap image to the surface.
HDC hdcSurface;
if( SUCCEEDED( pddsTempSurface->GetDC( &hdcSurface ) ) )
{
BitBlt( hdcSurface, 0, 0, bm.bmWidth, bm.bmHeight, hdcBitmap, 0, 0,
SRCCOPY );
pddsTempSurface->ReleaseDC( hdcSurface );
}
DeleteDC( hdcBitmap );
// Copy the temp surface to the real texture surface
m_pddsSurface->Blt( NULL, pddsTempSurface, NULL, DDBLT_WAIT, NULL );
// Done with the temp surface
pddsTempSurface->Release();
// For textures with real alpha (not palettized), set transparent bits
if( ddsd.ddpfPixelFormat.dwRGBAlphaBitMask )
{
if( m_dwFlags & (D3DTEXTR_TRANSPARENTWHITE|D3DTEXTR_TRANSPARENTBLACK) )
{
// Lock the texture surface
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof(ddsd);
while( m_pddsSurface->Lock( NULL, &ddsd, 0, NULL ) ==
DDERR_WASSTILLDRAWING );
DWORD dwAlphaMask = ddsd.ddpfPixelFormat.dwRGBAlphaBitMask;
DWORD dwRGBMask = ( ddsd.ddpfPixelFormat.dwRBitMask |
ddsd.ddpfPixelFormat.dwGBitMask |
ddsd.ddpfPixelFormat.dwBBitMask );
DWORD dwColorkey = 0x00000000; // Colorkey on black
if( m_dwFlags & D3DTEXTR_TRANSPARENTWHITE )
dwColorkey = dwRGBMask; // Colorkey on white
// Add an opaque alpha value to each non-colorkeyed pixel
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -