您的位置:首页 > 产品设计 > UI/UE

【翻(xue)译(xi)】3D Game Programming With DirectX11 - 4.4

2016-02-19 03:47 363 查看

4.4 DEMO应用程序框架

d3dUtil.h, d3dApp.h, d3dApp.cpp这三个文件是我们要用的DEMO文件,可以去这本书的网站下载。这些文件在每个demo都会用到。在本书的第二和第三部分将会把这个文件放进一个Common路径然后我们不就用老复制它了。它们的作用如文件名所述。建议读者自行学习这些文件因为我们不会一行一行讲,比如创建窗口什么的就是假设读者已经知道了。这个框架的目的就是隐藏创建窗口和初始化Direct3D的代码,转而让你专注于例子代码所做的事情。

4.4.1 D3DApp类

这个类提供了基于Direct3D的,创建窗口、进行消息循环、处理窗口消息、初始化Direct3D的函数,还提供了一些框架需要的其他函数。其他客户端都会源自于D3DApp这个类,从此处重写虚函数,然后实例化一个D3DApp类。

4.4.2 非框架的方法(见代码)

4.4.3 框架的方法(见代码)

本书的例子中,我们始终只重写D3DApp的那5个虚函数!重要的事情加感叹号。这五个函数可以将每个例子做成不同的用途。隐藏了那些初始化和消息处理之类的函数之后,派生的类就可以只关注程序的个性化的用途了。

4.4.4 框架统计数据

我们经常需要计算FPS(frams per second)。我们只需统计固定时间t内的帧数n即可。然后fps = n/t。我们代码中用t = 1因为这样不用做除法了,而且1秒也是不长不短正合适。

计算帧率的这个函数必须每一帧都调用。我们的代码里边除了计算帧率之外,还有帧率的倒数——每一帧所花费的平均时间。不过这俩也不是完全互为倒数,我们计算后者的时候单位是毫秒而不是秒的说。

每帧平均耗时是一个与fps不同的度量时间的方式。实际上这个数值比fps更有用,因为我们可以直接看到当我们改变场景的时候渲染一帧的耗时增减。也就是说,fps不够即时。而且,在【Dunlop03】里边详细比较了二者——fps因其非线性会导致一些误导的结果。

考虑以下这些情形:

1) 如果CPU以1000fps的帧率运行,那么它1ms渲染1帧。如果帧率降低到250fps,那么它需要4ms来渲染一帧;

2) 如果CPU以100fps的帧率运行,那么它10ms渲染一帧。如果降低到了76.9fps,那么需要大约13ms来渲染一帧。

在这两种情形下,每一帧的耗时都增加了3秒,但是直接看fps的话我们看不到这个相等关系。看上去1000fps到250fps是更大的降落,不过实际上它们俩所增加的耗时是一样哒。

4.4.5 消息句柄

我们为窗口应用程序创建的框架会尽可能少的暴露接口。也就是说我们不用经常处理Win32消息。实际上,我们的核心代码一直都在空转,没有消息。不过我们还是有很多重要消息要处理的。这里我们不详细介绍每一个消息,不过建议读者自己下载代码看看,毕竟这是以后的例子的基础。

1) WN_ACTIVE 当窗口被激活或者反激活的时候会受到这个消息

case WM_ACTIVE:

if(LWORD(wParam) == WA_INACTIVE)

{

mAppPaused = true;

mTimer.Stop();

}

else

{

mAppPaused = false;

mTimer.Start();

}

return 0;

代码中我们在激活窗口的时候把计时器开始,然后mAppPause这个标签记为false,反激活的时候反之。也就是说当窗口不激活的时候我们停止计时了。可以再去看Run这个函数,当mAppPause是false的时候我们就不刷新窗口了,也就不占用CPU循环了。

2) WN_SIZE 窗口改变大小的时候触发

我们接收这个消息的主要原因是重设后台缓冲区和深度模板缓冲区的大小,让它匹配窗口大小,避免图像拉伸。我们可以直接使用IDXGISwapChain::ResizeBuffers来重设后台缓冲区的大小,不过我们要重新创建深度模板缓存。注意每次拉伸的时候我们都会发送这个消息,包括用户拖拽窗口边缘的时候。所以实际上我们要判断一下用户是正在拖拽窗口边缘还是拖拽结束。我们可以用WM_EXITSIZEMOVE这个消息来接收这一信息。这个消息在用户放开拖拽窗口边缘的时候触发。

(代码略)

4.4.6 切换到全屏

IDXGISwapChain接口会自动捕获alt+enter组合键,在全屏与否之间切换。在切换过程中,窗口大小变化,并且发送WM_SIZE消息到应用窗口,好让应用程序重设后台缓冲区和深度模板缓冲区的大小。而且窗口风格也会切换到全屏友好的风格。你可以看Visual Studio Spy++来查看alt+enter是如何产生这样的改变大小的消息的。

(我们的练习中会让你研究下怎么取消这个功能。)

(你可能也想起来的DXGI_SWAP_CHAIN_DESC结构体的Flags属性了。)

4.4.7 看!是你的DEMO

其实大多事情都被之前所说的D3DApp类做了。我们需要的就是派生一下然后重载那几个虚函数。以后我们都会这么做的。

(代码略)

翻译存疑:

performance timer: 性能计数器

counts: the performance timer measures time in units called计数

The window procedure we implement for our application framework does the bare minimum. : 我们为窗口应用程序创建的框架会尽可能少的暴露接口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: