|
本帖最后由 夜行的猫仔 于 2012-9-6 09:45 编辑
在Tut01_CreateWindwos 里已经介绍了MANGOGUI的程序框架,例题Tut01为了让结构看起来更简单,因此简化了很多的函数,这样做甚至牺牲了一部分框架的完整性。在本节例题中,将介绍较为完整的框架结构。以及如何控制创景管理器创建GUI界面。
Tut02中已经讲过了,每一个界面控制文件都对应游戏界面中的一个Scene,一系列的Scene组成了一个游戏的GUI界面。因此管理好Scene就管理了游戏界面。在MANGOGUI中是通过CMANGOSceneManager 来控制游戏中的Scene的。
本教程完整项目下载地址(工作目录是bin文件夹):
http://kuai.xunlei.com/d/SUFKNHVDLQLU
以下是完整调用代码- //=============================================================================
- // Desc: Direct3D应用程序框架
- //=============================================================================
- #include "../MangoInterface/interface/Mango.h"
- #include "MessageId.h"
- //-----------------------------------------------------------------------------
- // 全局变量
- //-----------------------------------------------------------------------------
- CMANGOSceneManager g_SceneManager;
- //-----------------------------------------------------------------------------
- // Desc: 函数声明
- // 以下罗列了MANGOGUI中使用到的回调函数。整个MANGOGUI都是在这些回调函数的驱动下工作的。
- //------------------------------------------------------------------------------
- bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
- bool CALLBACK ModifyDeviceSettings( MANGODeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
- 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, CMANGOControl* pControl, void* pUserContext );
- void CALLBACK OnLostDevice( void* pUserContext );
- void CALLBACK OnDestroyDevice( void* pUserContext );
- void InitApp();
- //-----------------------------------------------------------------------------
- // Desc: 入口函数
- //-----------------------------------------------------------------------------
- INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
- {
- //为Debug配置启用运行时内存检查功能
- #if defined(DEBUG) | defined(_DEBUG)
- _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
- #endif
- //设置回调函数
- MANGOSetDeviceCreated( OnCreateDevice );
- MANGOSetDeviceReset( OnResetDevice );
- MANGOSetDeviceLost( OnLostDevice );
- MANGOSetDeviceDestroyed( OnDestroyDevice );
- MANGOSetMsgProc( MsgProc );
- MANGOSetKeyboard( KeyboardProc );
- MANGOSetFrameRender( OnFrameRender );
- MANGOSetFrameMove( OnFrameMove );
- //应用程序相关的初始化
- InitApp();
- //初始化MANGO, 创建窗口, 创建Direct3D设备对象
- MANGOInit( true, true, true );
- MANGOSetCursorSettings( true, true );
- MANGOCreateWindow( L"MangoGUI System v 0.1.53" );
- MANGOCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
- //进入消息循环和场景渲染
- MANGOMainLoop();
- //在此进行应用程序相关的清除工作
- return MANGOGetExitCode();
- }
- //-----------------------------------------------------------------------------
- // Desc: 应用程序相关初始化
- //-----------------------------------------------------------------------------
- void InitApp()
- {
- //载入一个界面
- g_SceneManager.CreateScene("layout/scene.xml");
- }
- //-----------------------------------------------------------------------------
- // Desc: 设备能力检查
- //-----------------------------------------------------------------------------
- bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
- D3DFORMAT BackBufferFormat, bool bWindowed,
- void* pUserContext )
- {
- //检查后台缓冲区格式是否支持Alpha混合等操作(post pixel blending operations)
- IDirect3D9* pD3D = MANGOGetD3DObject();
- if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
- AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
- D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
- return false;
- return true;
- }
- //-----------------------------------------------------------------------------
- // Desc: 修改Direct3D渲染设备设置
- //-----------------------------------------------------------------------------
- bool CALLBACK ModifyDeviceSettings( MANGODeviceSettings* pDeviceSettings,
- const D3DCAPS9* pCaps, void* pUserContext )
- {
- pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
- //如果不支持硬件顶点处理则使用软件顶点处理
- if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
- {
- pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
- }
- //如果使用参考设备,则弹出警告对话框
- static bool s_bFirstTime = true;
- if( s_bFirstTime )
- {
- s_bFirstTime = false;
- if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
- MANGODisplaySwitchingToREFWarning();
- }
- return true;
- }
- //-----------------------------------------------------------------------------
- // Desc: 在此创建管理内存资源对象
- //-----------------------------------------------------------------------------
- HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice,
- const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
- void* pUserContext )
- {
- HRESULT hr;
- V_RETURN( g_SceneManager.OnCreateDevice( pd3dDevice ) );
- return S_OK;
- }
- //-----------------------------------------------------------------------------
- // Desc: 在此创建默认内存类型资源对象
- //-----------------------------------------------------------------------------
- HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
- const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
- void* pUserContext )
- {
- HRESULT hr;
- V_RETURN( g_SceneManager.OnResetDevice() );
- g_SceneManager.GetSceneByName(L"Mango")->SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );
- //设置观察矩阵
- D3DXMATRIXA16 matView;
- D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5 );
- D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
- D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
- D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
- pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
- //设置投影矩阵
- D3DXMATRIXA16 matProj;
- float fAspectRatio = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
- D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspectRatio, 1.0f, 100.0f );
- pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
- return S_OK;
- }
- //-----------------------------------------------------------------------------
- // Desc: 更新场景
- //-----------------------------------------------------------------------------
- void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime,
- float fElapsedTime, void* pUserContext )
- {
- }
- //-----------------------------------------------------------------------------
- // Desc: 渲染场景
- //-----------------------------------------------------------------------------
- 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, 45, 50, 170), 1.0f, 0) );
- //渲染场景
- if( SUCCEEDED( pd3dDevice->BeginScene() ) )
- {
- //渲染文本和控件
- MANGO_BeginPerfEvent( MANGO_PERFEVENTCOLOR, L"HUD / Stats" );
- g_SceneManager.OnRender(fElapsedTime);
- MANGO_EndPerfEvent();
- V( pd3dDevice->EndScene() );
- }
- }
- //-----------------------------------------------------------------------------
- // Desc: 消息处理
- //-----------------------------------------------------------------------------
- LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
- bool* pbNoFurtherProcessing, void* pUserContext )
- {
- *pbNoFurtherProcessing = g_SceneManager.MsgProc( hWnd, uMsg, wParam, lParam );
- if( *pbNoFurtherProcessing )
- return 0;
- return 0;
- }
- //-----------------------------------------------------------------------------
- // Desc: 键盘消息处理
- //-----------------------------------------------------------------------------
- void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
- {
- }
- //-----------------------------------------------------------------------------
- // Desc: 处理各种控件消息
- //-----------------------------------------------------------------------------
- void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CMANGOControl* pControl,
- void* pUserContext )
- {
- switch( nControlID )
- {
- case Button1:
- MANGOToggleFullScreen();
- break;
- case Button2:
- MANGOToggleREF();
- break;
- case Button3:
- break;
- }
- }
- //-----------------------------------------------------------------------------
- // Desc: 释放在OnResetDevice()中创建的资源
- //-----------------------------------------------------------------------------
- void CALLBACK OnLostDevice( void* pUserContext )
- {
- g_SceneManager.OnLostDevice();
- }
- //------------------------------------------------------------------------------
- // Desc: 释放在OnCreateDevice()中创建的资源
- //------------------------------------------------------------------------------
- void CALLBACK OnDestroyDevice( void* pUserContext )
- {
- g_SceneManager.OnDestroyDevice();
- }
复制代码 需要解释的几个地方:
"MessageId.h"是消息ID定义文件。在MangoGUI中每一个消息的识别是通过 所在Scene ID+控件ID来识别的。但是对于每一个Scene内部的控件用ID就足够了。MessageId.h中定义的就是控件ID。我们Tut02中已经展示了scene.xml中的数据:- <Button ID='101' name ="FullScreen" x='35' y='10' width ='135' height='45' >Toggle full screen</Button>
复制代码 显示Toggle full screen的按钮的ID是101,在“MessageId.h”中也定义了- //Window Massage map
- #define Button1 101
- #define Button2 102
- #define Button3 103
复制代码 在后面的OnGUIEvent()函数中,处理了对应的宏定义为Button1的方法。也就是说,当按下了Toggle full screen按钮就会发送nControlID 是101的消息,当我们在OnGUIEvent()中收到这个消息,就执行MANGOToggleFullScreen()这个全屏化操作。
如果大家对D3D不是太熟悉,那么以上的框架就不要改动,以为这个框架完全不影响游戏GUI的操作。我们要完成游戏GUI的所有操作,都是在限定的几个函数内完成的。只需要将我们的逻辑类放在框架内运行即可。
CMANGOSceneManager场景管理器最好在游戏中只创建一个,这个管理器已经集成了对界面控制文件的相关操作,因此需要在界面上显示例如按钮等控件,只需要在相应的界面控制XML文件中添加,控件产生的响应在OnGUIEvent()中对应处理即可。- g_SceneManager.CreateScene("layout/scene.xml");
复制代码 通过CreateScene方法载入UI数据。- g_SceneManager.OnRender(fElapsedTime);
复制代码 OnRender方法绘制UI数据。
|
|