文档章节

DXUT框架剖析(6)

rise-worlds
 rise-worlds
发布于 2016/06/20 13:39
字数 1590
阅读 0
收藏 0

在窗口和设备创建好之后,应用程序需要使用消息循环处理窗口消息、更新和渲染场景、处理设备事件。应用程序可以实现自己的消息循环,也可以使用DXUT消息循环,注册相应的回调函数,可以让DXUT处理设备、帧消息事件。

进入消息循环

为使用DXUT框架的消息循环,可以调用DXUTMainLoop()函数:

Starts the main execution loop of DXUT.

HRESULT DXUTMainLoop(
HACCEL hAccel
);
Parameters
hAccel
[in] Handle to an accelerator table to use in translating keyboard messages from the Windows message queue, or NULL if not using an accelerator table. The default value is NULL.
Return Values

If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the error codes in DXUTERR.

Remarks

This function starts the message loop that will run for the lifetime of the application. During execution, DXUTMainLoop calls the registered callback functions to ask the application to update and render the frame, as well as handle any device or input events.

Custom Main Loop

For some advanced applications a custom main loop may be a better design. It is possible to use DXUT with a custom main loop. An example of how to do this is shown below.

INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
{
DXUTSetCallbackD3D9DeviceAcceptable( IsDeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnCreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnResetDevice );
DXUTSetCallbackD3D9FrameRender( OnFrameRender );
DXUTSetCallbackD3D9DeviceLost( OnLostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnDestroyDevice );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackKeyboard( KeyboardProc );
DXUTSetCallbackFrameMove( OnFrameMove );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );

DXUTInit( true, true );
DXUTCreateWindow( L"Example" );
DXUTCreateDevice( 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();
}

This example calls DXUTRender3DEnvironment to have DXUT update and render the scene and handle device events. While it is possible for the application to completely replicate this functionality, it is not recommended.

DXUTRender3DEnvironment

Renders the 3D environment.

VOID DXUTRender3DEnvironment();
Parameters

None.

Return Values

No return value.

Remarks

This method does not normally need to be called. It is useful only when the application does not use DXUTMainLoop but still wants DXUT to assist with rendering.

This method checks whether the device is lost. If so, the method attempts to reset the device and then calls the LPDXUTCALLBACKFRAMEMOVE and LPDXUTCALLBACKD3D10FRAMERENDER callback functions.

If the application window is minimized or the application is paused, CPU time is yielded to other processes.

处理事件

框架使用回调函数机制来使应用程序对事件做出反应。应用程序只需对框架注册和设置相应的函数指针,则当事件发生时,框架就会调用相应的函数。框架不需要注册所有的回调函数,所以应用程序只须对所需要的回调函数进行注册即可。通过为回调函数设置参数pUserContext,回调函数可以从应用程序接受内容,比如将该参数设置为一个指向类对象的指针。

DXUT框架可以处理以下事件类型:

(1)设备事件

当应用程序使用Direct3D设备渲染图形时,该设备有可能处于丢失状态。这种情况的发生有多种原因,例如按下Alt + Tab键离开一个全屏模式的应用程序,或者按下Ctrl + Alt + Del键,或者启动了另一个全屏3D应用程序。发生这种情况时,当调用一些函数(如Present)时,Direct3D API通过返回D3DERR_DEVICELOST通知应用程序设备丢失。

当设备丢失时,应用程序负责释放所有不能在设备丢失时存在的Direct3D资源对象,如在D3DPOOL_DEFAULT内存池中创建的对象。如果没有释放这些对象,那么该设备从丢失状态返回时就不能被重新设置。当设备丢失时,应用程序必须等待。当设备返回时,应用程序必须调用函数IDirect3DDevice9::Reset(),并重新创建所有不能在Reset()函数中存在的对象。

通过DXUT框架,这个过程可以通过在应用程序中使用回调函数来简化,这些回调函数处理各种设备事件:设备改变、创建、重新设置、丢失或销毁。当设备丢失时,框架会有提示;当它从丢失状态返回时,框架会适当调用相应的回调函数,重新设置该设备,即框架使用应用程序的回调函数在适当的时间释放和重新创建设备对象。应用程序需要做的是注册并实现相关回调函数,各回调函数的类型、注册、调用时机等细节见下表:

注册函数
应用程序回调函数
框架调用时机
创建资源
释放资源

DXUTSetCallback-
DeviceChanging
LPDXUTCALLBACK-
MODIFYDEVICESETTINGS
在创建Direct3D设备之前调用,应用程序可以返回FALSE,拒绝改变该设备。
x
x

DXUTSetCallback-
D3D9DeviceCreated
LPDXUTCALLBACK-
D3D9DEVICECREATED
当应用程序初始化和重新创建设备时,在Direct3D设备创建之后立即调用。
创建D3DPOOL_MANAGED资源,因为这些资源无论什么时候被销毁都需要重新加载,但这些资源被重新设置时不需要重新加载。在这里创建的资源需要在LPDXUTCALLBACK-DEVICEDESTROYED中释放。
x

DXUTSetCallback-
D3D9DeviceReset
LPDXUTCALLBACK-
D3D9DEVICERESET
当Direct3D设备丢失又被重新设置后立即调用。
创建D3DPOOL_DEFAULT资源,因为这些资源无论什么时候丢失或重新设置时都需要重新加载,在这里创建的资源需要在LPDXUTCALLBACK-DEVICELOST中释放。
x

DXUTSetCallback-
D3D9DeviceLost
LPDXUTCALLBACK-
D3D9DEVICELOST
当Direct3D设备变为丢失状态且在Reset调用之前,立即调用。
x
释放在回调函数LPDXUTCALLBACK-D3D9DEVICERESET中创建的资源,这些资源通常包括所有的D3DPOOL_DEFAULT资源。

DXUTSetCallback-
D3D9DeviceDestroyed
LPDXUTCALLBACK-
D3D9DEVICEDESTROYED
当应用程序终止或重新创建设备时,Direct3D设备被销毁后,立即调用。
x
释放在回调函数LPDXUTCALLBACK-
D3D9DEVICECREATED中创建的资源,这些资源通常包括所有的D3DPOOL_MANAGED资源。

当设备在窗口和全屏模式间切换时常常需要重新设置,但有时它必须通过Direct3D重新创建。

调用这些回调函数是可选的,但如果应用程序没有使用函数DXUTSetCallbackD3D9DeviceDestroyed()和DXUTSetCallbackD3D9DeviceCreated()注册销毁回调函数和创建回调函数,则改变设备或在硬件抽象层设备和参考设备间切换都不能进行。

类似地,如果没有用函数DXUTSetCallbackD3D9DeviceLost()和DXUTSetCallbackD3D9DeviceReset()注册丢失回调函数和重置回调函数,则当设备丢失或重置设备时,框架无法通知应用程序。这样一来,所有不在D3DPOOL_MANAGED内存中的设备对象都不能重新设置。

本文转载自:http://www.cnblogs.com/flying_bat/archive/2008/05/17/1201313.html

rise-worlds

rise-worlds

粉丝 3
博文 1760
码字总数 1380
作品 0
深圳
程序员
私信 提问
如何使用DXUT框架

DXUT是什么? DXUT即DirectX Utility Library,它是微软为DirectX Samples写的一个框架,有了这个框架,Sample的构建就方便多了,这个框架实际上抽取了构建Sample的公共代码,比如处理窗口消...

吞吞吐吐的
2017/10/12
0
0
并发框架Disruptor译文

Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易。这个系统是建立在JVM平台上,其核心是一个业务逻辑处...

石头哥哥
2013/06/30
850
0
DXUT

DXUT 是一个建立在 Direct3D 之上的一个层,简化 了 Windows 和 Direct3D 的 API。它能帮助开发者建立一个更健壮、更易于生成的示例,原型,工具或游戏,...

大胖森
2015/04/30
732
0
libevent源码深度剖析

作者:http://blog.csdn.net/sparkliang/article/category/660506 libevent源码深度剖析十三——libevent信号处理注意点 libevent源码深度剖析十三——libevent信号处理注意点前面讲到了lib...

晨曦之光
2012/03/09
2.8K
0
Direct3D学习(三):光影贴图

刚看完了DXUT,拿来练练手 这个框架却实方便啊,终于不用写那些令人恶心的API函数了 光影贴图,说白了就是在纹理上表现出来光影效果,并不是实时计算的,所以适用于固定的场影平面,如地面,...

长平狐
2012/11/12
82
0

没有更多内容

加载失败,请刷新页面

加载更多

Java注解合并,注解继承

spring中有时候一个类上面标记很多注解。 实际上Java注解可以进行继承(也就是把多个注解合并成1个) 比如说SpringMVC的注解 @RestController@RequestMapping("/person") 可以合并为一个 @P...

物种起源-达尔文
23分钟前
4
0
撤消Git中一个文件的工作副本修改?

在最后一次提交之后,我修改了工作副本中的一堆文件,但是我想撤消对这些文件之一的更改,例如将其重置为与最新提交相同的状态。 但是,我只想撤消仅一个文件的工作副本更改,而没有其他操作...

技术盛宴
58分钟前
4
0
Qt编写气体安全管理系统28-模拟工具

一、前言 模拟工具在一些涉及到硬件通信的程序中特别有用,也特别需要,回顾这十年来做过的项目,95%的项目都是软硬件交互的,貌似软硬件结合的项目更有生命力一些,纯软件的或者纯硬件的,并...

飞扬青云
今天
4
0
关于生活方式

生活就是生活,但难免和工作混在一起,所以要建立自己的生活方式,把工作稍微隔开点。 首先呢,每周放假的两天肯定会: 洗衣服,收拾屋子,列计划是必须要做的事情。 (这里可能还包含一些处...

T型人才追梦者
今天
6
0
JVM

一、JVM一些基本概念 1、JVM和普通虚拟机 JVM:Java Virtual Machine,程序自己独立的运行环境;堆栈、寄存器、字节码指令;可以运行多种语言:Java、Scala、Grovvy; 普通虚拟机:能完整提供...

请把小熊还给我_m
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部