您的位置:首页 > 其它

【转贴】DXUT 框架入门 2

2016-06-20 00:00 459 查看
这章主要介绍一下DXUT 里面的GUI元素。要在图形界面中添加GUI元素,首先要定义一个DialogResourceManager对象用来管理对话框资源。DialogResourceManager 管理渲染时状态、Sprite控制批量显示更新、对话框字体、纹理等等。CDXUTDialog 相当于MFC里面的对话框,作为各种控件资源的容器。CD3DSettingsDlg 是一个ms已经写好的对话框类,可以用来设置各种Direct3DDevice9 创建时的参数。点击该对话框的ok 按钮,D3D设备将会重建。

这里先建立了DialogResourceManager全局变量g_DialogResourceManager和CD3DSettingsDlg 全局变量g_SettingsDlg。并且要在 OnCreateDevice OnResetDevice MsgProc OnLostDevice OnDestroyDevice 回调函数中调用自己相应的函数如g_DialogResourceManager.OnCreateDevice(...) 等等。

对于对话框对象使用前必须初始化 init() 参数为DialogResourceManager类对象,即g_DialogResourceManager.之后对于CDXUTDialog类对象g_HUD需要设置自己的消息回调函数 OnGUIEvent()。并且在 dxut 的消息处理函数MsgProc中调用自己的消息处理函数 g_HUD->MsgProc(), 如果是该对话框的消息,Dxut回调函数将不再处理这个消息。而交由对话框处理。



//
使用DXUT 框架GUI程序



#include
<
dxstdafx.h
>





//
自定义顶点结构



struct
CUSTOMVERTEX







{


float x,y,z,rhw;


DWORD diffuse;


}
;




ID3DXFont
*
g_pFont
=
NULL;
//
Font for drawing text



ID3DXSprite
*
g_pTextSprite
=
NULL;
//
Sprite for batching draw text calls



bool
g_bShowHelp
=

true
;
//
If true, it renders the UI control text



CDXUTDialogResourceManager g_DialogResourceManager;
//
manager for shared resources of dialogs



CD3DSettingsDlg g_SettingsDlg;
//
Device settings dialog



CDXUTDialog g_HUD;
//
dialog for standard controls



static

const

int
D3DFVF_CUSTOMVERTEX
=
D3DFVF_XYZRHW
|
D3DFVF_DIFFUSE;


LPDIRECT3DVERTEXBUFFER9 g_pVB;



bool
g_vsb
=

true
;





//
定义g_HUD对话框上按钮ID



static

const

int
IDC_TOGGLEFULLSCREEN
=
1
;



static

const

int
IDC_TOGGLEREF
=
2
;



static

const

int
IDC_CHANGEDEVICE
=
3
;




HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9
*
pd3dDevice,
const
D3DSURFACE_DESC
*
pBackBufferSurfaceDesc,
void
*
pUserContext );


HRESULT CALLBACK OnResetDevice( IDirect3DDevice9
*
pd3dDevice,
const
D3DSURFACE_DESC
*
pBackBufferSurfaceDesc,
void
*
pUserContext );



void
CALLBACK OnFrameMove( IDirect3DDevice9
*
pd3dDevice,
double
fTime,
float
fElapsedTime,
void
*
pUserContext );



void
CALLBACK OnFrameRender( IDirect3DDevice9
*
pd3dDevice,
double
fTime,
float
fElapsedTime,
void
*
pUserContext );


LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool
*
pbNoFurtherProcessing,
void
*
pUserContext );



void
CALLBACK KeyboardProc( UINT nChar,
bool
bKeyDown,
bool
bAltDown,
void
*
pUserContext );



void
CALLBACK OnGUIEvent( UINT nEvent,
int
nControlID, CDXUTControl
*
pControl,
void
*
pUserContext );



void
CALLBACK OnLostDevice(
void
*
pUserContext );



void
CALLBACK OnDestroyDevice(
void
*
pUserContext );



void
InitApp();



void
RenderText();




INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR,
int
)







{


//为DEBUG模式激活运行时内存检查


#if defined(DEBUG) | defined(_DEBUG)


_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );


#endif


// 设置回调函数,这些函数允许DXUT通知应用程序更换设备,用户输入和窗口消息。


// 回调函数是可选的,因此你要做的仅是设置你感兴趣的事件的回调函数。


DXUTSetCallbackDeviceCreated( OnCreateDevice );


DXUTSetCallbackDeviceReset( OnResetDevice );


DXUTSetCallbackDeviceLost( OnLostDevice );


DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );


DXUTSetCallbackFrameRender( OnFrameRender );


DXUTSetCallbackFrameMove( OnFrameMove );


DXUTSetCallbackMsgProc( MsgProc );


DXUTSetCallbackKeyboard( KeyboardProc );


// 全屏时显示鼠标


DXUTSetCursorSettings( true, true );


//InitApp();


// 初始化DXUT并创建想要的Win32窗口和应用程序的Direct3D设备。调用这些


// 可选函数中的每一个,此外它们允许你设置几个选项来控制框架的行为。


DXUTInit( TRUE, TRUE, TRUE );


DXUTCreateWindow( L"ameng" );


DXUTCreateDevice( D3DADAPTER_DEFAULT, TRUE, 640, 480 );


// 通过DXUT来处理消息循环并分派渲染调用。当在空闲时间和处理窗口消息的


// 时间间隔时,框架将调用OnFrameMove和OnFrameRender回调函数。


DXUTMainLoop();


return DXUTGetExitCode();


}



void
InitApp()







{


// 初始化对话框


g_SettingsDlg.Init(&g_DialogResourceManager );


g_HUD.Init(&g_DialogResourceManager );


//设置对话框消息处理函数。


g_HUD.SetCallback( OnGUIEvent );


int iY = 10;


g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );


g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22,VK_F3 );


g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );


}






HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9
*
pd3dDevice,
const
D3DSURFACE_DESC
*
pBackBufferSurfaceDesc,
void
*
pUserContext )







{


HRESULT hr;


V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );


InitApp();


V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );


// Initialize the font


V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,


OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,


L"Arial", &g_pFont ) );


return S_OK;


}


HRESULT CALLBACK OnResetDevice( IDirect3DDevice9
*
pd3dDevice,
const
D3DSURFACE_DESC
*
pBackBufferSurfaceDesc,
void
*
pUserContext )







{


HRESULT hr;


static CUSTOMVERTEX vertices[] =






{






{ 300.0f, 50.0f, 0.1f, 1.0f, D3DCOLOR_ARGB(255,255,0,0) }, // x, y, z, rhw, color






{ 500.0f, 350.0f, 0.1f, 1.0f, D3DCOLOR_ARGB(255,0,255,0) },






{ 100.0f, 350.0f, 0.1f, 1.0f, D3DCOLOR_ARGB(255,0,0,255) },


};


pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVB,NULL);


BYTE* pVertices;


if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 )))


return E_FAIL;


memcpy(pVertices,vertices,sizeof(vertices));


g_pVB->Unlock();


V_RETURN( g_DialogResourceManager.OnResetDevice() );


V_RETURN( g_SettingsDlg.OnResetDevice() );


if( g_pFont )


V_RETURN( g_pFont->OnResetDevice() );


// Create a sprite to help batch calls when drawing many lines of text


V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );


g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );


g_HUD.SetSize( 170, 170 );


return S_OK;


}



void
CALLBACK OnFrameMove( IDirect3DDevice9
*
pd3dDevice,
double
fTime,
float
fElapsedTime,
void
*
pUserContext )







{




}



void
CALLBACK OnFrameRender( IDirect3DDevice9
*
pd3dDevice,
double
fTime,
float
fElapsedTime,
void
*
pUserContext )







{


HRESULT hr;


V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) );


V(pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX)));


V(pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX));


if( g_SettingsDlg.IsActive() )






{


g_SettingsDlg.OnRender( fElapsedTime );


return;


}


if(SUCCEEDED(pd3dDevice->BeginScene()))






{


//更新图像


V(pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,1));


if(g_vsb)






{


RenderText();


}


V( g_HUD.OnRender( fElapsedTime ) );


// V( g_SampleUI.OnRender( fElapsedTime ) );


pd3dDevice->EndScene();


}


}



void
RenderText()







{


// The helper object simply helps keep track of text position, and color


// and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );


// If NULL is passed in as the sprite object, then it will work however the


// pFont->DrawText() will not be batched together. Batching calls will improves performance.


CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );


// Output statistics


txtHelper.Begin();


txtHelper.SetInsertionPos( 5, 5 );


txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );


txtHelper.DrawTextLine( DXUTGetFrameStats(true) ); //为true 显现FPS,默认为false不显使FPS


txtHelper.DrawTextLine( DXUTGetDeviceStats() );






//TODO: add UI text as needed


txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );


txtHelper.DrawTextLine( L"Put whatever misc status here" );




// 获取图象后备缓冲区


const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();


if( g_bShowHelp )






{


txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*6 );


txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );


txtHelper.DrawTextLine( L"Controls (F1 to hide):" );


txtHelper.SetInsertionPos( 40, pd3dsdBackBuffer->Height-15*5 );


txtHelper.DrawTextLine( L"Quit: ESC" );


}


else






{


//txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*2 );


txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );


txtHelper.DrawTextLine( L"Press F1 for help" );


}




txtHelper.End();


}





//
--------------------------------------------------------------------------------------



//
Before handling window messages, DXUT passes incoming windows



//
messages to the application through this callback function. If the application sets



//
*pbNoFurtherProcessing to TRUE, then DXUT will not process this message.



//
--------------------------------------------------------------------------------------



LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool
*
pbNoFurtherProcessing,
void
*
pUserContext )







{


// Always allow dialog resource manager calls to handle global messages


// so GUI state is updated correctly


*pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );


if( *pbNoFurtherProcessing )


return 0;


if( g_SettingsDlg.IsActive() )






{


g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );


return 0;


}


// Give the dialogs a chance to handle the message first


*pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );


if( *pbNoFurtherProcessing )


return 0;


return 0;


}





//
--------------------------------------------------------------------------------------



//
As a convenience, DXUT inspects the incoming windows messages for



//
keystroke messages and decodes the message parameters to pass relevant keyboard



//
messages to the application. The framework does not remove the underlying keystroke



//
messages, which are still passed to the application's MsgProc callback.



//
--------------------------------------------------------------------------------------



void
CALLBACK KeyboardProc( UINT nChar,
bool
bKeyDown,
bool
bAltDown,
void
*
pUserContext )







{


if( bKeyDown )






{


switch( nChar )






{


case VK_F1:


g_bShowHelp = !g_bShowHelp;


break;


case VK_F4:


g_HUD.SetVisible(!g_HUD.GetVisible());


g_vsb = !g_vsb;


break;


default:


break;


}


}


}





//
--------------------------------------------------------------------------------------



//
Handles the GUI events



//
--------------------------------------------------------------------------------------



void
CALLBACK OnGUIEvent( UINT nEvent,
int
nControlID, CDXUTControl
*
pControl,
void
*
pUserContext )







{


switch( nControlID )






{


case IDC_TOGGLEFULLSCREEN:


DXUTToggleFullScreen();


break;


case IDC_TOGGLEREF:


DXUTToggleREF();


break;


case IDC_CHANGEDEVICE:


g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() );


break;


}


}



void
CALLBACK OnLostDevice(
void
*
pUserContext )







{


if(g_pVB != NULL)






{


g_pVB->Release();


g_pVB = NULL;


}


g_DialogResourceManager.OnLostDevice();


g_SettingsDlg.OnLostDevice();


if( g_pFont )


g_pFont->OnLostDevice();




SAFE_RELEASE( g_pTextSprite );


}



void
CALLBACK OnDestroyDevice(
void
*
pUserContext )







{


g_DialogResourceManager.OnDestroyDevice();


g_SettingsDlg.OnDestroyDevice();


SAFE_RELEASE( g_pFont );


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: