📄 d3dtextr.cpp
字号:
//-----------------------------------------------------------------------------
// File: D3DTextr.cpp
//
// Desc: Functions to manage textures, including creating (loading from a
// file), restoring lost surfaces, invalidating, and destroying.
//
// Note: the implementation of these fucntions maintain an internal list
// of loaded textures. After creation, individual textures are referenced
// via their ASCII names.
//
// Copyright (c) 1996-1999 Microsoft Corporation. All rights reserved
//-----------------------------------------------------------------------------
//#define STRICT
#include "StdAfx.h"
//#include <tchar.h>
//#include <stdio.h>
//#include "D3DTextr.h"
//#include "D3DUtil.h"
//-----------------------------------------------------------------------------
// Macros, function prototypes and static variable
//-----------------------------------------------------------------------------
static TCHAR g_strTexturePath[512] = _T(""); // Path for files
//-----------------------------------------------------------------------------
// Name: TextureContainer
// Desc: Linked list structure to hold info per texture
//-----------------------------------------------------------------------------
struct TextureContainer
{
TextureContainer* m_pNext; // Linked list ptr
TCHAR m_strName[80]; // Name of texture (doubles as image filename)
DWORD m_dwWidth;
DWORD m_dwHeight;
DWORD m_dwStage; // Texture stage (for multitexture devices)
DWORD m_dwBPP;
DWORD m_dwFlags;
BOOL m_bHasAlpha;
LPDIRECTDRAWSURFACE7 m_pddsSurface; // Surface of the texture
HBITMAP m_hbmBitmap; // Bitmap containing texture image
DWORD* m_pRGBAData;
public:
HRESULT LoadImageData();
HRESULT LoadBitmapFile( TCHAR* strPathname );
HRESULT LoadTargaFile( TCHAR* strPathname );
HRESULT Restore( LPDIRECT3DDEVICE7 pd3dDevice );
HRESULT CopyBitmapToSurface();
HRESULT CopyRGBADataToSurface();
TextureContainer( TCHAR* strName, DWORD dwStage, DWORD dwFlags );
~TextureContainer();
};
// Local list of textures
static TextureContainer* g_ptcTextureList = NULL;
//-----------------------------------------------------------------------------
// Name: CD3DTextureManager
// Desc: Class used to automatically construct and destruct the static
// texture engine class.
//-----------------------------------------------------------------------------
class CD3DTextureManager
{
public:
CD3DTextureManager() {}
~CD3DTextureManager() { if( g_ptcTextureList ) delete g_ptcTextureList; }
};
// Global instance
CD3DTextureManager g_StaticTextureEngine;
//-----------------------------------------------------------------------------
// Name: struct TEXTURESEARCHINFO
// Desc: Structure used to search for texture formats
//-----------------------------------------------------------------------------
struct TEXTURESEARCHINFO
{
DWORD dwDesiredBPP; // Input for texture format search
BOOL bUseAlpha;
BOOL bUsePalette;
BOOL bFoundGoodFormat;
DDPIXELFORMAT* pddpf; // Output of texture format search
};
//-----------------------------------------------------------------------------
// Name: TextureSearchCallback()
// Desc: Enumeration callback routine to find a best-matching texture format.
// The param data is the DDPIXELFORMAT of the best-so-far matching
// texture. Note: the desired BPP is passed in the dwSize field, and the
// default BPP is passed in the dwFlags field.
//-----------------------------------------------------------------------------
static HRESULT CALLBACK TextureSearchCallback( DDPIXELFORMAT* pddpf,
VOID* param )
{
if( NULL==pddpf || NULL==param )
return DDENUMRET_OK;
TEXTURESEARCHINFO* ptsi = (TEXTURESEARCHINFO*)param;
// Skip any funky modes
if( pddpf->dwFlags & (DDPF_LUMINANCE|DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV) )
return DDENUMRET_OK;
// Check for palettized formats
if( ptsi->bUsePalette )
{
if( !( pddpf->dwFlags & DDPF_PALETTEINDEXED8 ) )
return DDENUMRET_OK;
// Accept the first 8-bit palettized format we get
memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) );
ptsi->bFoundGoodFormat = TRUE;
return DDENUMRET_CANCEL;
}
// Else, skip any paletized formats (all modes under 16bpp)
if( pddpf->dwRGBBitCount < 16 )
return DDENUMRET_OK;
// Skip any FourCC formats
if( pddpf->dwFourCC != 0 )
return DDENUMRET_OK;
// Skip any ARGB 4444 formats (which are best used for pre-authored
// content designed speciafically for an ARGB 4444 format).
if( pddpf->dwRGBAlphaBitMask == 0x0000f000 )
return DDENUMRET_OK;
// Make sure current alpha format agrees with requested format type
if( (ptsi->bUseAlpha==TRUE) && !(pddpf->dwFlags&DDPF_ALPHAPIXELS) )
return DDENUMRET_OK;
if( (ptsi->bUseAlpha==FALSE) && (pddpf->dwFlags&DDPF_ALPHAPIXELS) )
return DDENUMRET_OK;
// Check if we found a good match
if( pddpf->dwRGBBitCount == ptsi->dwDesiredBPP )
{
memcpy( ptsi->pddpf, pddpf, sizeof(DDPIXELFORMAT) );
ptsi->bFoundGoodFormat = TRUE;
return DDENUMRET_CANCEL;
}
return DDENUMRET_OK;
}
//-----------------------------------------------------------------------------
// Name: FindTexture()
// Desc: Searches the internal list of textures for a texture specified by
// its name. Returns the structure associated with that texture.
//-----------------------------------------------------------------------------
static TextureContainer* FindTexture( TCHAR* strTextureName )
{
TextureContainer* ptcTexture = g_ptcTextureList;
while( ptcTexture )
{
if( !lstrcmpi( strTextureName, ptcTexture->m_strName ) )
return ptcTexture;
ptcTexture = ptcTexture->m_pNext;
}
return NULL;
}
//-----------------------------------------------------------------------------
// Name: TextureContainer()
// Desc: Constructor for a texture object
//-----------------------------------------------------------------------------
TextureContainer::TextureContainer( TCHAR* strName, DWORD dwStage,
DWORD dwFlags )
{
lstrcpy( m_strName, strName );
m_dwWidth = 0;
m_dwHeight = 0;
m_dwStage = dwStage;
m_dwBPP = 0;
m_dwFlags = dwFlags;
m_bHasAlpha = 0;
m_pddsSurface = NULL;
m_hbmBitmap = NULL;
m_pRGBAData = NULL;
// Add the texture to the head of the global texture list
m_pNext = g_ptcTextureList;
g_ptcTextureList = this;
}
//-----------------------------------------------------------------------------
// Name: ~TextureContainer()
// Desc: Destructs the contents of the texture container
//-----------------------------------------------------------------------------
TextureContainer::~TextureContainer()
{
SAFE_RELEASE( m_pddsSurface );
SAFE_DELETE( m_pRGBAData );
DeleteObject( m_hbmBitmap );
// Remove the texture container from the global list
if( g_ptcTextureList == this )
g_ptcTextureList = m_pNext;
else
{
for( TextureContainer* ptc=g_ptcTextureList; ptc; ptc=ptc->m_pNext )
if( ptc->m_pNext == this )
ptc->m_pNext = m_pNext;
}
}
//-----------------------------------------------------------------------------
// Name: LoadImageData()
// Desc: Loads the texture map's image data
//-----------------------------------------------------------------------------
HRESULT TextureContainer::LoadImageData()
{
TCHAR* strExtension;
TCHAR strPathname[256];
FILE* file;
// Check the executable's resource. If it's there, we're done!
m_hbmBitmap = (HBITMAP)LoadImage( GetModuleHandle(NULL), m_strName,
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
if( m_hbmBitmap )
return S_OK;
// First check if the file exists in the global texture path
lstrcpy( strPathname, g_strTexturePath );
lstrcat( strPathname, m_strName );
if( NULL == ( file = fopen( strPathname, "rb" ) ) )
{
// Then check if the file exists in the DirectX SDK media path
lstrcpy( strPathname, D3DUtil_GetDXSDKMediaPath() );
lstrcat( strPathname, m_strName );
if( NULL == ( file = fopen( strPathname, "rb" ) ) )
return DDERR_NOTFOUND;
}
fclose( file );
// Get the filename extension
if( NULL == ( strExtension = _tcsrchr( m_strName, _T('.') ) ) )
return DDERR_UNSUPPORTED;
// Load bitmap files
if( !lstrcmpi( strExtension, _T(".bmp") ) )
return LoadBitmapFile( strPathname );
// Load targa files
if( !lstrcmpi( strExtension, _T(".tga") ) )
return LoadTargaFile( strPathname );
// Can add code here to check for other file formats before failing
return DDERR_UNSUPPORTED;
}
//-----------------------------------------------------------------------------
// Name: LoadBitmapFile()
// Desc: Loads data from a .bmp file, and stores it in a bitmap structure.
//-----------------------------------------------------------------------------
HRESULT TextureContainer::LoadBitmapFile( TCHAR* strPathname )
{
// Try to load the bitmap as a file
m_hbmBitmap = (HBITMAP)LoadImage( NULL, strPathname, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE|LR_CREATEDIBSECTION );
if( m_hbmBitmap )
return S_OK;
return DDERR_NOTFOUND;
}
//-----------------------------------------------------------------------------
// Name: LoadTargaFile()
// Desc: Loads RGBA data from a .tga file, and stores it in allocated memory
// for the specified texture container
//-----------------------------------------------------------------------------
HRESULT TextureContainer::LoadTargaFile( TCHAR* strPathname )
{
FILE* file = fopen( strPathname, "rb" );
if( NULL == file )
return E_FAIL;
struct TargaHeader
{
BYTE IDLength;
BYTE ColormapType;
BYTE ImageType;
BYTE ColormapSpecification[5];
WORD XOrigin;
WORD YOrigin;
WORD ImageWidth;
WORD ImageHeight;
BYTE PixelDepth;
BYTE ImageDescriptor;
} tga;
fread( &tga, sizeof(TargaHeader), 1, file );
// Only true color, non-mapped images are supported
if( ( 0 != tga.ColormapType ) ||
( tga.ImageType != 10 && tga.ImageType != 2 ) )
{
fclose( file );
return E_FAIL;
}
// Skip the ID field. The first byte of the header is the length of this field
if( tga.IDLength )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -