DXUT编程指南(五):通过DXUT使用主循环

通过DXUT使用主循环
在窗口和设备创建之后,应用程序需要一个主循环(也称渲染循环或者消息循环)来响应windows消息,更新和渲染场景,处理设备事件。应用程序既可以自己实现主循环也可以让DXUT来实现。注册回调函数允许DXUT处理设备,帧,消息事件。

进入主循环
要使用框架的主循环,简单的调用DXUTMainLoop,并设置唯一的参数为NULL。
尽管框架处理主循环是最简单的,但是对一些更高级的应用程序定制一个主循环将是更高级的设计。可以使用DXUTMainLoop函数定制一个主循环,但则在应用程序中需要更多的代码,比如下面的代码示例:
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
{
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );

    DXUTInit( TRUE, TRUE, TRUE );
    DXUTCreateWindow( L"BasicHLSL" );
    DXUTCreateDevice( D3DADAPTER_DEFAULT, TRUE, 640, 480 );

    // Custom main loop
    HWND hWnd = DXUTGetHWND();
    BOOL bGotMsg;
    MSG  msg;
    msg.message = WM_NULL;
    PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

    while( WM_QUIT != msg.message  )
    {
    // Use PeekMessage() so we can use idle time to render the scene
 bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
 
 if( bGotMsg )
 {
     // Translate and dispatch the message
     if( 0 == TranslateAccelerator( hWnd, NULL, &msg ) )
     {
  TranslateMessage( &msg );
  DispatchMessage( &msg );
     }
 }
 else
 {
     // Render a frame during idle time (no messages are waiting)
     DXUTRender3DEnvironment();
 }
    }

    return DXUTGetExitCode();
}
在这个代码示例中,应用程序调用函数DXUTRender3DEnvironment来让框架更新场景和处理设备事件。应用程序也可以完全的重做这项功能,然而这不被推荐。

处理事件
框架使用回调函数机制允许应用程序相应事件。应用程序只需要简单的向框架注册设置一个函数指针,当事件发生时框架就会调用这些函数。框架并不要求所有的回调函数都被注册,所以应用程序只需要自由得注册它需要的回调函数。
对于DirectX April 2005 SDK Update,回调函数从DXUTSetCallback* 函数传递一个void* pUserContext 给回调机制。这允许回调函数从应用程序处接受一个上下文比如类指针。
有3种发生在框架中
设备事件
当应用程序向一个Direct3D设备渲染时,设备有可能丢失。这可能有很多原因,比如用户按下ALT+TAB离开全屏应用程序。或者按CTRL+ALT+DEL,或者运行了另一个3D全屏应用程序。当这种情况发生时,Direct3D API通知应用程序,这通过在调用某个函数比如Present的时候返回D3DERR_DEVICELOST来实现。
当设备丢失的时候,应用程序有责任释放所有的Direct3D对象(当设备丢失的时候它们也无法幸存),比如在D3DPOOL_DEFAULT内存中创建的对象。如果这些对象没有释放,设备从丢失状态返回的时候将无法重置。
当设备丢失的时候应用程序必须等待。当设备返回时,应用程序必须调用Reset重建所有重置过程中无法幸存的设备对象 。
通过框架,这个过程被简化了。通过在应用程序中使用回调函数处理各种设备事件:设备改变,创建,重置,丢失,销毁。框架会注意到设备的丢失,并且当设备从丢失状态返回时正确的重置。框架在适当的时候使用应用程序的回调函数释放并重建设备对象。应用程序要做的就是向下面一样注册和实现回调函数

Callback Registration FunctionApplication Callback FunctionWhen Called By the FrameworkResource CreationResource Release
DXUTSetCallbackDeviceChanging LPDXUTCALLBACKMODIFYDEVICESETTINGS Called before the Direct3D device is created. This gives the application a chance to reject the device change by returning false.--
DXUTSetCallbackDeviceCreated LPDXUTCALLBACKDEVICECREATED Called immediately after the Direct3D device has been created, which will happen during application initialization and device recreation.Create D3DPOOL_MANAGED resources because these resources need to be reloaded whenever the device is destroyed.-
DXUTSetCallbackDeviceReset LPDXUTCALLBACKDEVICERESET Called immediately after the Direct3D device has been reset, which will happen after the device is lost.Create D3DPOOL_DEFAULT resources because these resources need to be reloaded whenever the device is lost.-
DXUTSetCallbackDeviceLost LPDXUTCALLBACKDEVICELOST Called immediately after the Direct3D device has entered a lost state and before Reset is called. -Resources created in the device reset callback function (LPDXUTCALLBACKDEVICERESET ), which generally includes all D3DPOOL_DEFAULT resources, should be released by this application callback function.
DXUTSetCallbackDeviceDestroyed LPDXUTCALLBACKDEVICEDESTROYED Called immediately after the Direct3D device has been destroyed, which generally happens as a result of application termination or device recreation.-Resources created in the device created callback function (LPDXUTCALLBACKDEVICECREATED ), which generally includes all D3DPOOL_MANAGED resources, should be released by this application callback function.

当设备在全屏与窗口模式之间切换时,通常要重置。但有时他们需要由Direct3D重新创建。
调用这些注册的回调函数是可选的。然而,如果应用程序没有通过DXUTSetCallbackDeviceDestroyed 和DXUTSetCallbackDeviceCreated注册设备销毁和创建的回调函数,框架就不能重建设备,因为它没有办法通知应用程序设备被创建或销毁。在这种情况下,改变设备或者在HAL与REF之间切换将无法工作。
同样地,如果应用程序没有通过DXUTSetCallbackDeviceLost 和DXUTSetCallbackDeviceReset注册设备的丢失与重置回调函数,当设备丢失或重置的时候框架就没有办法通知应用程序。在这种情况下,典型的,如果设备对象不在D3DPOOL_MANAGED内存中Direct3D重置设备将会失败。
同时注意,如果应用程序使用 DXUTCreateDevice,就不需要调用DXUTSetCallbackDeviceChanging 因为框架会记住LPDXUTCALLBACKMODIFYDEVICESETTINGS 函数。

帧事件
框架同样提供了帧事件,它在渲染过程中的每一帧被调用。应用程序需要像下面一样注册并实现回调函数:

Application Callback FunctionCallback Registration FunctionWhen Called By the FrameworkScene Rendering
LPDXUTCALLBACKFRAMEMOVE DXUTSetCallbackFrameMove Called once at the beginning of every frame.This callback function is the best location for your application to handle updates to the scene, but it should not contain actual rendering calls, which should instead be placed in the frame render callback function (LPDXUTCALLBACKFRAMERENDER ).
LPDXUTCALLBACKFRAMERENDER DXUTSetCallbackFrameRender Called at the end of every frame, or if the window needs to be repainted.All the rendering calls for the scene should be performed in this callback function. After this callback function has returned, the framework will call Present to display the contents of the next buffer in the swap chain.


消息事件
框架通过下面的回调函数以及他们对应的注册函数向应用程序传递窗口消息,键盘事件,和鼠标事件。应用编程对这些事件提供适当的响应。

Application Callback FunctionCallback Registration FunctionDescription
LPDXUTCALLBACKMSGPROC DXUTSetCallbackMsgProc Processes window messages from the DXUT message pump.
LPDXUTCALLBACKKEYBOARD DXUTSetCallbackKeyboard Processes keyboard events from the DXUT message pump.
LPDXUTCALLBACKMOUSE DXUTSetCallbackMouse Processes mouse events from the DXUT message pump.

 

结语:DXUT编程指南并未到此为止,只是因为在GameRes上发现已经有人翻译过这个部分了,并且是Word格式的便于下载,我也就没有必要再做重复的工作了,这里是下载地址.
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值