【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2826|回复: 0

【MangoGUI控件系列教程】MangoGUI Tut03_CreateSceneManager 创建场景管理器

[复制链接]
发表于 2012-9-6 09:05:19 | 显示全部楼层 |阅读模式
本帖最后由 夜行的猫仔 于 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


以下是完整调用代码
  1. //=============================================================================
  2. // Desc: Direct3D应用程序框架
  3. //=============================================================================
  4. #include "../MangoInterface/interface/Mango.h"
  5. #include "MessageId.h"
  6. //-----------------------------------------------------------------------------
  7. // 全局变量
  8. //-----------------------------------------------------------------------------
  9. CMANGOSceneManager                   g_SceneManager;

  10. //-----------------------------------------------------------------------------
  11. // Desc: 函数声明
  12. // 以下罗列了MANGOGUI中使用到的回调函数。整个MANGOGUI都是在这些回调函数的驱动下工作的。
  13. //------------------------------------------------------------------------------
  14. bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
  15. bool    CALLBACK ModifyDeviceSettings( MANGODeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
  16. HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
  17. HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
  18. void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
  19. void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
  20. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
  21. void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
  22. void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CMANGOControl* pControl, void* pUserContext );
  23. void    CALLBACK OnLostDevice( void* pUserContext );
  24. void    CALLBACK OnDestroyDevice( void* pUserContext );

  25. void    InitApp();

  26. //-----------------------------------------------------------------------------
  27. // Desc: 入口函数
  28. //-----------------------------------------------------------------------------
  29. INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
  30. {
  31.         //为Debug配置启用运行时内存检查功能
  32. #if defined(DEBUG) | defined(_DEBUG)
  33.         _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
  34. #endif

  35.         //设置回调函数
  36.         MANGOSetDeviceCreated( OnCreateDevice );
  37.         MANGOSetDeviceReset( OnResetDevice );
  38.         MANGOSetDeviceLost( OnLostDevice );
  39.         MANGOSetDeviceDestroyed( OnDestroyDevice );
  40.         MANGOSetMsgProc( MsgProc );
  41.         MANGOSetKeyboard( KeyboardProc );
  42.         MANGOSetFrameRender( OnFrameRender );
  43.         MANGOSetFrameMove( OnFrameMove );

  44.         //应用程序相关的初始化
  45.         InitApp();

  46.         //初始化MANGO, 创建窗口, 创建Direct3D设备对象
  47.         MANGOInit( true, true, true );
  48.         MANGOSetCursorSettings( true, true );
  49.         MANGOCreateWindow( L"MangoGUI System  v 0.1.53" );
  50.         MANGOCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );

  51.         //进入消息循环和场景渲染
  52.         MANGOMainLoop();

  53.         //在此进行应用程序相关的清除工作

  54.         return MANGOGetExitCode();
  55. }


  56. //-----------------------------------------------------------------------------
  57. // Desc: 应用程序相关初始化
  58. //-----------------------------------------------------------------------------
  59. void InitApp()
  60. {
  61.         //载入一个界面
  62.         g_SceneManager.CreateScene("layout/scene.xml");       
  63. }


  64. //-----------------------------------------------------------------------------
  65. // Desc: 设备能力检查
  66. //-----------------------------------------------------------------------------
  67. bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
  68.                                                                  D3DFORMAT BackBufferFormat, bool bWindowed,
  69.                                                                  void* pUserContext )
  70. {
  71.         //检查后台缓冲区格式是否支持Alpha混合等操作(post pixel blending operations)
  72.         IDirect3D9* pD3D = MANGOGetD3DObject();
  73.         if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
  74.                 AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
  75.                 D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
  76.                 return false;

  77.         return true;
  78. }


  79. //-----------------------------------------------------------------------------
  80. // Desc: 修改Direct3D渲染设备设置
  81. //-----------------------------------------------------------------------------
  82. bool CALLBACK ModifyDeviceSettings( MANGODeviceSettings* pDeviceSettings,
  83.                                                                    const D3DCAPS9* pCaps, void* pUserContext )
  84. {
  85.         pDeviceSettings->pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
  86.         //如果不支持硬件顶点处理则使用软件顶点处理
  87.         if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
  88.         {
  89.                 pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  90.         }

  91.         //如果使用参考设备,则弹出警告对话框
  92.         static bool s_bFirstTime = true;
  93.         if( s_bFirstTime )
  94.         {
  95.                 s_bFirstTime = false;
  96.                 if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
  97.                         MANGODisplaySwitchingToREFWarning();
  98.         }

  99.         return true;
  100. }


  101. //-----------------------------------------------------------------------------
  102. // Desc: 在此创建管理内存资源对象
  103. //-----------------------------------------------------------------------------
  104. HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice,
  105.                                                                 const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
  106.                                                                 void* pUserContext )
  107. {
  108.         HRESULT hr;

  109.         V_RETURN( g_SceneManager.OnCreateDevice( pd3dDevice ) );

  110.         return S_OK;
  111. }


  112. //-----------------------------------------------------------------------------
  113. // Desc: 在此创建默认内存类型资源对象
  114. //-----------------------------------------------------------------------------
  115. HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
  116.                                                            const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
  117.                                                            void* pUserContext )
  118. {
  119.         HRESULT hr;
  120.         V_RETURN( g_SceneManager.OnResetDevice() );

  121.         g_SceneManager.GetSceneByName(L"Mango")->SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );

  122.         //设置观察矩阵
  123.         D3DXMATRIXA16 matView;
  124.         D3DXVECTOR3 vEyePt( 0.0f, 0.0f,-5 );
  125.         D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
  126.         D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
  127.         D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
  128.         pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

  129.         //设置投影矩阵
  130.         D3DXMATRIXA16 matProj;
  131.         float fAspectRatio = (float)pBackBufferSurfaceDesc->Width / pBackBufferSurfaceDesc->Height;
  132.         D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspectRatio, 1.0f, 100.0f );
  133.         pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

  134.         return S_OK;
  135. }


  136. //-----------------------------------------------------------------------------
  137. // Desc: 更新场景
  138. //-----------------------------------------------------------------------------
  139. void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime,
  140.                                                   float fElapsedTime, void* pUserContext )
  141. {
  142. }


  143. //-----------------------------------------------------------------------------
  144. // Desc: 渲染场景
  145. //-----------------------------------------------------------------------------
  146. void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime,
  147.                                                         float fElapsedTime, void* pUserContext )
  148. {
  149.         HRESULT hr;
  150.         //清除后台颜色缓冲区和深度缓冲区
  151.         V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
  152.                 D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );

  153.         //渲染场景
  154.         if( SUCCEEDED( pd3dDevice->BeginScene() ) )
  155.         {
  156.                 //渲染文本和控件
  157.                 MANGO_BeginPerfEvent( MANGO_PERFEVENTCOLOR, L"HUD / Stats" );
  158.                 g_SceneManager.OnRender(fElapsedTime);
  159.                 MANGO_EndPerfEvent();

  160.                 V( pd3dDevice->EndScene() );
  161.         }
  162. }

  163. //-----------------------------------------------------------------------------
  164. // Desc: 消息处理
  165. //-----------------------------------------------------------------------------
  166. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
  167.                                                  bool* pbNoFurtherProcessing, void* pUserContext )
  168. {

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

  170.         if( *pbNoFurtherProcessing )
  171.                 return 0;

  172.         return 0;
  173. }

  174. //-----------------------------------------------------------------------------
  175. // Desc: 键盘消息处理
  176. //-----------------------------------------------------------------------------
  177. void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
  178. {
  179. }


  180. //-----------------------------------------------------------------------------
  181. // Desc: 处理各种控件消息
  182. //-----------------------------------------------------------------------------
  183. void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CMANGOControl* pControl,
  184.                                                  void* pUserContext )
  185. {
  186.         switch( nControlID )
  187.         {
  188.         case Button1:
  189.                 MANGOToggleFullScreen();
  190.                 break;

  191.         case Button2:
  192.                 MANGOToggleREF();
  193.                 break;

  194.         case Button3:
  195.                 break;
  196.         }
  197. }


  198. //-----------------------------------------------------------------------------
  199. // Desc: 释放在OnResetDevice()中创建的资源
  200. //-----------------------------------------------------------------------------
  201. void CALLBACK OnLostDevice( void* pUserContext )
  202. {
  203.         g_SceneManager.OnLostDevice();
  204. }


  205. //------------------------------------------------------------------------------
  206. // Desc: 释放在OnCreateDevice()中创建的资源
  207. //------------------------------------------------------------------------------
  208. void CALLBACK OnDestroyDevice( void* pUserContext )
  209. {
  210.         g_SceneManager.OnDestroyDevice();
  211. }
复制代码
需要解释的几个地方:
"MessageId.h"是消息ID定义文件。在MangoGUI中每一个消息的识别是通过 所在Scene ID+控件ID来识别的。但是对于每一个Scene内部的控件用ID就足够了。MessageId.h中定义的就是控件ID。我们Tut02中已经展示了scene.xml中的数据:
  1. <Button ID='101' name ="FullScreen" x='35' y='10' width ='135' height='45' >Toggle full screen</Button>
复制代码
显示Toggle full screen的按钮的ID是101,在“MessageId.h”中也定义了
  1. //Window Massage map
  2. #define Button1 101
  3. #define Button2 102
  4. #define Button3 103
复制代码
在后面的OnGUIEvent()函数中,处理了对应的宏定义为Button1的方法。也就是说,当按下了Toggle full screen按钮就会发送nControlID 是101的消息,当我们在OnGUIEvent()中收到这个消息,就执行MANGOToggleFullScreen()这个全屏化操作。

如果大家对D3D不是太熟悉,那么以上的框架就不要改动,以为这个框架完全不影响游戏GUI的操作。我们要完成游戏GUI的所有操作,都是在限定的几个函数内完成的。只需要将我们的逻辑类放在框架内运行即可。


CMANGOSceneManager场景管理器最好在游戏中只创建一个,这个管理器已经集成了对界面控制文件的相关操作,因此需要在界面上显示例如按钮等控件,只需要在相应的界面控制XML文件中添加,控件产生的响应在OnGUIEvent()中对应处理即可。
  1. g_SceneManager.CreateScene("layout/scene.xml");
复制代码
通过CreateScene方法载入UI数据。
  1. g_SceneManager.OnRender(fElapsedTime);
复制代码
OnRender方法绘制UI数据。

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-4-29 01:52

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表