添加文本
DXUT框架对文本绘制进行了封装,提供了类CDXUTHelper来简化文本显示,使用该接口大体分为3个步骤:初始化ID3DXSprite和ID3DXFont对象,显示文本,释放ID3DXSprite和ID3DXFont对象。
首先来看看CDXUTHelper的定义部分:
//--------------------------------------------------------------------------------------
// Manages the insertion point when drawing text
//--------------------------------------------------------------------------------------
class CDXUTTextHelper
{
public:
CDXUTTextHelper( ID3DXFont* pFont, ID3DXSprite* pSprite, int nLineHeight );
void SetInsertionPos( int x, int y ) { m_pt.x = x; m_pt.y = y; }
void SetForegroundColor( D3DXCOLOR clr ) { m_clr = clr; }
void Begin();
HRESULT DrawFormattedTextLine( const WCHAR* strMsg, );
HRESULT DrawTextLine( const WCHAR* strMsg );
HRESULT DrawFormattedTextLine( RECT &rc, DWORD dwFlags, const WCHAR* strMsg, );
HRESULT DrawTextLine( RECT &rc, DWORD dwFlags, const WCHAR* strMsg );
void End();
protected:
ID3DXFont* m_pFont;
ID3DXSprite* m_pSprite;
D3DXCOLOR m_clr;
POINT m_pt;
int m_nLineHeight;
};
接着来看看CDXUTHelper的实现部分:
//--------------------------------------------------------------------------------------
CDXUTTextHelper::CDXUTTextHelper( ID3DXFont* pFont, ID3DXSprite* pSprite, int nLineHeight )
{
m_pFont = pFont;
m_pSprite = pSprite;
m_clr = D3DXCOLOR(1,1,1,1);
m_pt.x = 0;
m_pt.y = 0;
m_nLineHeight = nLineHeight;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTTextHelper::DrawFormattedTextLine( const WCHAR* strMsg, )
{
WCHAR strBuffer[512];
va_list args;
va_start(args, strMsg);
StringCchVPrintf( strBuffer, 512, strMsg, args );
strBuffer[511] = L'\0';
va_end(args);
return DrawTextLine( strBuffer );
}
HRESULT CDXUTTextHelper::DrawTextLine( const WCHAR* strMsg )
{
if( NULL == m_pFont )
return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG );
RECT rc;
SetRect( &rc, m_pt.x, m_pt.y, 0, 0 );
HRESULT hr = m_pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
if( FAILED(hr) )
return DXTRACE_ERR_MSGBOX( L"DrawText", hr );
m_pt.y += m_nLineHeight;
return S_OK;
}
HRESULT CDXUTTextHelper::DrawFormattedTextLine( RECT &rc, DWORD dwFlags, const WCHAR* strMsg, )
{
WCHAR strBuffer[512];
va_list args;
va_start(args, strMsg);
StringCchVPrintf( strBuffer, 512, strMsg, args );
strBuffer[511] = L'\0';
va_end(args);
return DrawTextLine( rc, dwFlags, strBuffer );
}
HRESULT CDXUTTextHelper::DrawTextLine( RECT &rc, DWORD dwFlags, const WCHAR* strMsg )
{
if( NULL == m_pFont )
return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG );
HRESULT hr = m_pFont->DrawText( m_pSprite, strMsg, -1, &rc, dwFlags, m_clr );
if( FAILED(hr) )
return DXTRACE_ERR_MSGBOX( L"DrawText", hr );
m_pt.y += m_nLineHeight;
return S_OK;
}
//--------------------------------------------------------------------------------------
void CDXUTTextHelper::Begin()
{
if( m_pSprite )
m_pSprite->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE );
}
void CDXUTTextHelper::End()
{
if( m_pSprite )
m_pSprite->End();
}
代码相当简洁明了,需要说明的是函数StringCchVPrintf:
StringCchVPrintf is a replacement for vsprintf. It
accepts a format string and its arguments, provided as a va_list, and
returns a formatted string. The size, in characters, of the destination
buffer is provided to the function to ensure that StringCchVPrintf
does not write past the end of this buffer.
Syntax
HRESULT StringCchVPrintf(
LPTSTR pszDest,
size_t cchDest,
LPCTSTR pszFormat,
va_list argList
);
Parameters
- pszDest
- [out] Pointer to a buffer which receives
the formatted, null-terminated string created from pszFormat
and argList.
- cchDest
- [in] Size of the destination buffer, in
characters. This value must be sufficiently large to accommodate
the final formatted string plus 1 to account for the terminating
null character. The maximum number of characters allowed is
STRSAFE_MAX_CCH.
- pszFormat
- [in] Pointer to a buffer containing a printf-style
format string. This string must be null-terminated.
- argList
- [in] A va_list containing the arguments to
be inserted into pszFormat.
Return Value
Note that this function returns an HRESULT
as opposed to vsprintf, which returns the number of characters
written. It is strongly recommended that you use the SUCCEEDED and
FAILED macros to
test the return value of this function.
S_OK |
There was
sufficient space for the result to be copied to pszDest
without truncation and the buffer is null-terminated. |
STRSAFE_E_INVALID_PARAMETER |
The value in
cchDest is either 0 or larger than STRSAFE_MAX_CCH. |
STRSAFE_E_INSUFFICIENT_BUFFER |
The copy
operation failed due to insufficient buffer space. The
destination buffer contains a truncated, null-terminated version
of the intended result. In situations where truncation is
acceptable, this may not necessarily be seen as a failure
condition. |
Remarks
StringCchVPrintf provides additional
processing for proper buffer handling in your code. Poor buffer handling
is implicated in many security issues that involve buffer overruns.
StringCchVPrintf always null-terminates a non-zero-length
destination buffer.
For more information on va_lists, see the
conventions defined in Stdarg.h.
StringCchVPrintf can be used in its
generic form, or specifically as StringCchVPrintfA (for ANSI
strings) or StringCchVPrintfW (for Unicode strings). The form to
use is determined by your data.
String Data Type |
String Literal |
Function |
char |
"string" |
StringCchVPrintfA |
TCHAR |
TEXT("string") |
StringCchVPrintf |
WCHAR |
L"string" |
StringCchVPrintfW |
StringCchVPrintf and its ANSI and
Unicode variants are replacements for these functions:
- vsprintf
- vswprintf
- wvsprintf
- wvnsprintf
- _vstprintf
- _vsnprintf
- _vsnwprintf
- _vsntprintf
Behavior is undefined if the strings pointed to
by pszDest, pszFormat, or any argument strings overlap.
Neither pszFormat nor pszDest
should be NULL. See StringCchVPrintfEx
if you require the handling of null string pointer values.
以及ID3DXSprite::Begin()的声明:
Prepares a device for drawing sprites.
HRESULT Begin(
DWORD Flags
);
Parameters
- Flags
- [in] Combination of zero or more flags that
describe sprite rendering options. For this method, the valid flags are:
- D3DXSPRITE_ALPHABLEND
- D3DXSprite__BILLBOARD
- D3DXSPRITE_DONOTMODIFY_RENDERSTATE
- D3DXSPRITE_DONOTSAVESTATE
- D3DXSPRITE_OBJECTSPACE
- D3DXSprite__SORT_DEPTH_BACKTOFRONT
- D3DXSprite__SORT_DEPTH_FRONTTOBACK
- D3DXSprite__SORT_TEXTURE
For a description of the flags and for information on
how to control device state capture and device view transforms, see
D3DXSPRITE.
Return Values
If the method succeeds, the return value is S_OK. If
the method fails, the return value can be one of the following:
D3DERR_INVALIDCALL, D3DERR_OUTOFVIDEOMEMORY, D3DXERR_INVALIDDATA, E_OUTOFMEMORY.
Remarks
This method must be called from inside a
IDirect3DDevice9::BeginScene . . . IDirect3DDevice9::EndScene sequence.
ID3DXSprite::Begin cannot be used as a substitute for either
IDirect3DDevice9::BeginScene or ID3DXRenderToSurface::BeginScene.
This method will set the following states on the
device.
Render States:
Type
(D3DRENDERSTATETYPE) |
Value |
D3DRS_ALPHABLENDENABLE |
TRUE |
D3DRS_ALPHAFUNC |
D3DCMP_GREATER |
D3DRS_ALPHAREF |
0x00 |
D3DRS_ALPHATESTENABLE |
AlphaCmpCaps |
D3DRS_BLENDOP |
D3DBLENDOP_ADD |
D3DRS_CLIPPING |
TRUE |
D3DRS_CLIPPLANEENABLE |
FALSE |
D3DRS_COLORWRITEENABLE |
D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE |
D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED |
D3DRS_CULLMODE |
D3DCULL_NONE |
D3DRS_DESTBLEND |
D3DBLEND_INVSRCALPHA |
D3DRS_DIFFUSEMATERIALSOURCE |
D3DMCS_COLOR1 |
D3DRS_ENABLEADAPTIVETESSELLATION |
FALSE |
D3DRS_FILLMODE |
D3DFILL_SOLID |
D3DRS_FOGENABLE |
FALSE |
D3DRS_INDEXEDVERTEXBLENDENABLE |
FALSE |
D3DRS_LIGHTING |
FALSE |
D3DRS_RANGEFOGENABLE |
FALSE |
D3DRS_SEPARATEALPHABLENDENABLE |
FALSE |
D3DRS_SHADEMODE |
D3DSHADE_GOURAUD |
D3DRS_SPECULARENABLE |
FALSE |
D3DRS_SRCBLEND |
D3DBLEND_SRCALPHA |
D3DRS_SRGBWRITEENABLE |
FALSE |
D3DRS_STENCILENABLE |
FALSE |
D3DRS_VERTEXBLEND |
FALSE |
D3DRS_WRAP0 |
0 |
Texture Stage States:
Stage
Identifier |
Type
(D3DTEXTURESTAGESTATETYPE) |
Value |
0 |
D3DTSS_ALPHAARG1 |
D3DTA_TEXTURE |
0 |
D3DTSS_ALPHAARG2 |
D3DTA_DIFFUSE |
0 |
D3DTSS_ALPHAOP |
D3DTOP_MODULATE |
0 |
D3DTSS_COLORARG1 |
D3DTA_TEXTURE |
0 |
D3DTSS_COLORARG2 |
D3DTA_DIFFUSE |
0 |
D3DTSS_COLOROP |
D3DTOP_MODULATE |
0 |
D3DTSS_TEXCOORDINDEX |
0 |
0 |
D3DTSS_TEXTURETRANSFORMFLAGS |
D3DTTFF_DISABLE |
1 |
D3DTSS_ALPHAOP |
D3DTOP_DISABLE |
1 |
D3DTSS_COLOROP |
D3DTOP_DISABLE |
Sampler States:
Sampler Stage Index |
Type
(D3DSAMPLERSTATETYPE) |
Value |
0 |
D3DSAMP_ADDRESSU |
D3DTADDRESS_CLAMP |
0 |
D3DSAMP_ADDRESSV |
D3DTADDRESS_CLAMP |
0 |
D3DSAMP_MAGFILTER |
D3DTEXF_ANISOTROPIC if
TextureFilterCaps includes D3DPTFILTERCAPS_MAGFANISOTROPIC; otherwise
D3DTEXF_LINEAR |
0 |
D3DSAMP_MAXMIPLEVEL |
0 |
0 |
D3DSAMP_MAXANISOTROPY |
MaxAnisotropy |
0 |
D3DSAMP_MINFILTER |
D3DTEXF_ANISOTROPIC if
TextureFilterCaps includes D3DPTFILTERCAPS_MINFANISOTROPIC; otherwise
D3DTEXF_LINEAR |
0 |
D3DSAMP_MIPFILTER |
D3DTEXF_LINEAR if
TextureFilterCaps includes D3DPTFILTERCAPS_MIPFLINEAR; otherwise
D3DTEXF_POINT |
0 |
D3DSAMP_MIPMAPLODBIAS |
0 |
0 |
D3DSAMP_SRGBTEXTURE |
0 |
Note This method disables
N-patches.
D3DXSPRITE
The following flags are used to specify sprite
rendering options to the flags parameter in the ID3DXSprite::Begin method:
#define |
Description |
D3DXSPRITE_DONOTSAVESTATE |
The device state is not
to be saved or restored when ID3DXSprite::Begin or
ID3DXSprite::End is called. |
D3DXSPRITE_DONOTMODIFY_RENDERSTATE |
The device render state
is not to be changed when ID3DXSprite::Begin is called. The
device is assumed to be in a valid state to draw vertices containing
UsageIndex = 0 in the D3DDECLUSAGE_POSITION, D3DDECLUSAGE_TEXCOORD, and
D3DDECLUSAGE_COLOR data. |
D3DXSPRITE_OBJECTSPACE |
The world, view, and
projection transforms are not modified. The transforms currently set to
the device are used to transform the sprites when the batched sprites
are drawn (when ID3DXSprite::Flush or ID3DXSprite::End is
called). If this flag is not specified, then world, view, and projection
transforms are modified so that sprites are drawn in screen-space
coordinates. |
D3DXSPRITE_BILLBOARD |
Each sprite will be
rotated about its center so that it is facing the viewer.
ID3DXSprite::SetWorldViewLH or ID3DXSprite::SetWorldViewRH must be
called first. |
D3DXSPRITE_ALPHABLEND |
Enables alpha blending
with D3DRS_ALPHATESTENABLE set to TRUE (for nonzero alpha).
D3DBLEND_SRCALPHA will be the source blend state, and
D3DBLEND_INVSRCALPHA will be the destination blend state in calls to
IDirect3DDevice9::SetRenderState. See Alpha Blending State (Direct3D 9).
ID3DXFont expects this flag to be set when drawing text. |
D3DXSPRITE_SORT_TEXTURE |
Sort sprites by texture
prior to drawing. This can improve performance when drawing
non-overlapping sprites of uniform depth.
You may also combine
D3DXSPRITE_SORT_TEXTURE with either D3DXSPRITE_SORT_DEPTH_FRONTTOBACK or
D3DXSPRITE_SORT_DEPTH_BACKTOFRONT. This will sort the list of sprites by
depth first and texture second.
|
D3DXSPRITE_SORT_DEPTH_FRONTTOBACK |
Sprites are sorted by
depth in front-to-back order prior to drawing. This procedure is
recommended when drawing opaque sprites of varying depths.
You may combine
D3DXSPRITE_SORT_DEPTH_FRONTTOBACK with D3DXSPRITE_SORT_TEXTURE to sort
first by depth, and second by texture.
|
D3DXSPRITE_SORT_DEPTH_BACKTOFRONT |
Sprites are sorted by
depth in back-to-front order prior to drawing. This procedure is
recommended when drawing transparent sprites of varying depths.
You may combine
D3DXSPRITE_SORT_DEPTH_BACKTOFRONT with D3DXSPRITE_SORT_TEXTURE to sort
first by depth, and second by texture.
|
D3DXSPRITE_DO_NOT_ADDREF_TEXTURE |
Disables calling
AddRef() on every draw, and Release() on Flush() for better performance. |
初始化ID3DXSprite和ID3DXFont对象
在回调函数OnCreateDevice()中创建ID3DXFont对象:
//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
D3DXCreateFont(pd3dDevice, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, L"Arial", &g_font);
return S_OK;
}
绘制文本
//--------------------------------------------------------------------------------------
// Render the helper information
//--------------------------------------------------------------------------------------
void RenderText()
{
CDXUTTextHelper text_helper(g_font, g_text_sprite, 20);
text_helper.Begin();
// show frame and device states
text_helper.SetInsertionPos(5, 5);
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 0.475f, 0.0f, 1.0f) );
text_helper.DrawTextLine( DXUTGetFrameStats(true) );
text_helper.DrawTextLine( DXUTGetDeviceStats() );
// show other simple information
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f) );
text_helper.DrawTextLine(L"Put whatever misc status here");
// show helper information
const D3DSURFACE_DESC* surface_desc = DXUTGetBackBufferSurfaceDesc();
if(g_show_help)
{
text_helper.SetInsertionPos(10, surface_desc->Height - 15 * 6);
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 0.475f, 0.0f, 1.0f) );
text_helper.DrawTextLine(L"Controls (F1 to hide):");
text_helper.SetInsertionPos(40, surface_desc->Height - 15 * 5);
text_helper.DrawTextLine(L"Quir: ESC");
}
else
{
text_helper.SetInsertionPos(10, surface_desc->Height - 15 * 4);
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f) );
text_helper.DrawTextLine(L"Press F1 for help");
}
text_helper.End();
}
处理键盘消息
程序通过键盘上的"F1"键切换来表明是否显示简单帮助文本,处理代码如下:
//--------------------------------------------------------------------------------------
// Handle keybaord event
//--------------------------------------------------------------------------------------
void CALLBACK OnKeyboardProc(UINT charater, bool is_key_down, bool is_alt_down, void* user_context)
{
if(is_key_down)
{
switch(charater)
{
case VK_F1:
g_show_help = !g_show_help;
break;
}
}
}
运行效果图:
主程序:
#include "dxstdafx.h"
#include "resource.h"
#pragma warning(disable : 4127)
ID3DXFont* g_font;
ID3DXSprite* g_text_sprite;
bool g_show_help = true;
#define release_com(p) do { if(p) { (p)->Release(); (p) = NULL; } } while(0)
//--------------------------------------------------------------------------------------
// Rejects any devices that aren't acceptable by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
{
// Typically want to skip backbuffer formats that don't support alpha blending
IDirect3D9* pD3D = DXUTGetD3DObject();
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat,
D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
return false;
return true;
}
//--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed.
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
{
// If video card does not support hardware vertex processing, then uses sofaware vertex processing.
if((pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
static bool is_first_time = true;
if(is_first_time)
{
is_first_time = false;
// if using reference device, then pop a warning message box.
if(pDeviceSettings->DeviceType == D3DDEVTYPE_REF)
DXUTDisplaySwitchingToREFWarning();
}
return true;
}
//--------------------------------------------------------------------------------------
// Create any D3DPOOL_MANAGED resources here
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
D3DXCreateFont(pd3dDevice, 18, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, L"Arial", &g_font);
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create any D3DPOOL_DEFAULT resources here
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
g_font->OnResetDevice();
D3DXCreateSprite(pd3dDevice, &g_text_sprite);
// setup view matrix
D3DXMATRIX mat_view;
D3DXVECTOR3 eye(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 at(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&mat_view, &eye, &at, &up);
pd3dDevice->SetTransform(D3DTS_VIEW, &mat_view);
// set projection matrix
D3DXMATRIX mat_proj;
float aspect = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
D3DXMatrixPerspectiveFovLH(&mat_proj, D3DX_PI/4, aspect, 1.0f, 100.0f);
pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_proj);
return S_OK;
}
//--------------------------------------------------------------------------------------
// Release resources created in the OnResetDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
g_font->OnLostDevice();
release_com(g_text_sprite);
}
//--------------------------------------------------------------------------------------
// Release resources created in the OnCreateDevice callback here
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
release_com(g_font);
}
//--------------------------------------------------------------------------------------
// Handle updates to the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// Render the helper information
//--------------------------------------------------------------------------------------
void RenderText()
{
CDXUTTextHelper text_helper(g_font, g_text_sprite, 20);
text_helper.Begin();
// show frame and device states
text_helper.SetInsertionPos(5, 5);
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 0.475f, 0.0f, 1.0f) );
text_helper.DrawTextLine( DXUTGetFrameStats(true) );
text_helper.DrawTextLine( DXUTGetDeviceStats() );
// show other simple information
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f) );
text_helper.DrawTextLine(L"Put whatever misc status here");
// show helper information
const D3DSURFACE_DESC* surface_desc = DXUTGetBackBufferSurfaceDesc();
if(g_show_help)
{
text_helper.SetInsertionPos(10, surface_desc->Height - 15 * 6);
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 0.475f, 0.0f, 1.0f) );
text_helper.DrawTextLine(L"Controls (F1 to hide):");
text_helper.SetInsertionPos(40, surface_desc->Height - 15 * 5);
text_helper.DrawTextLine(L"Quir: ESC");
}
else
{
text_helper.SetInsertionPos(10, surface_desc->Height - 15 * 4);
text_helper.SetForegroundColor( D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f) );
text_helper.DrawTextLine(L"Press F1 for help");
}
text_helper.End();
}
//--------------------------------------------------------------------------------------
// Render the scene
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr;
// Clear the render target and the zbuffer
V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 5, 5, 5), 1.0f, 0) );
// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
RenderText();
V( pd3dDevice->EndScene() );
}
}
//--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext )
{
return 0;
}
//--------------------------------------------------------------------------------------
// Handle keybaord event
//--------------------------------------------------------------------------------------
void CALLBACK OnKeyboardProc(UINT charater, bool is_key_down, bool is_alt_down, void* user_context)
{
if(is_key_down)
{
switch(charater)
{
case VK_F1:
g_show_help = !g_show_help;
break;
}
}
}
//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
// Set the callback functions
DXUTSetCallbackDeviceCreated( OnCreateDevice );
DXUTSetCallbackDeviceReset( OnResetDevice );
DXUTSetCallbackDeviceLost( OnLostDevice );
DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackFrameRender( OnFrameRender );
DXUTSetCallbackFrameMove( OnFrameMove );
DXUTSetCallbackKeyboard(OnKeyboardProc);
// TODO: Perform any application-level initialization here
// Initialize DXUT and create the desired Win32 window and Direct3D device for the application
DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
DXUTCreateWindow( L"AddText" );
DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
// Start the render loop
DXUTMainLoop();
// TODO: Perform any application-level cleanup here
return DXUTGetExitCode();
}
下载示例工程