移植游戏循环
摘要
- 第 1 部分:初始化 Direct3D 11
- 第 2 部分:转换呈现框架
- 第 3 部分:移植游戏循环
介绍如何实现通用 Windows 平台 (UWP) 游戏的窗口,以及如何显示游戏循环,包括如何构建 IFrameworkView 来控制全屏 CoreWindow。 将简单的 Direct3D 9 应用移植到 DirectX 11 和 UWP 操作实例的第 3 部分。
创建窗口
若要设置一个具有 Direct3D 9 视区的桌面窗口,我们必须为桌面应用实现传统的窗口框架。 必须创建 HWND、设置窗口大小、 提供窗口处理回调、使其可见等。
UWP 环境具有更简单的系统。 不再设置传统的窗口,Microsoft Store 游戏使用 DirectX 实现 IFrameworkView。 对于要直接在应用容器内的 CoreWindow 中运行的 DirectX 应用和游戏来说,存在该接口。
注意 Windows 提供指向资源(如源应用程序对象和 CoreWindow)的托管指针。 请参阅对象句柄运算符 (^)。
你的“main”类需要从 IFrameworkView 继承并且实现五种 IFrameworkView 方法:Initialize、SetWindow、Load、Run 和 Uninitialize。 除了创建 IFrameworkView(从本质上说,这是你的游戏所在的位置)之外,你还需要实现一个用于创建 IFrameworkView 实例的工厂类。 你的游戏仍然包含一个可执行文件,该文件具有一个名为 main() 的方法,但所有 main 均可以使用工厂来创建 IFrameworkView 实例。
main 函数
//-----------------------------------------------------------------------------
// Required method for a DirectX-only app.
// The main function is only used to initialize the app's IFrameworkView class.
//-----------------------------------------------------------------------------
[Platform::MTAThread]
int main(Platform::Array<Platform::String^>^)
{
auto direct3DApplicationSource = ref new Direct3DApplicationSource();
CoreApplication::Run(direct3DApplicationSource);
return 0;
}
IFrameworkView 工厂
//-----------------------------------------------------------------------------
// This class creates our IFrameworkView.
//-----------------------------------------------------------------------------
ref class Direct3DApplicationSource sealed :
Windows::ApplicationModel::Core::IFrameworkViewSource
{
public:
virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView()
{
return ref new Cube11();
};
};
移植游戏循环
下面我们看一看 Direct3D 9 实现中的游戏循环。 该代码位于应用的 main 函数中。 该循环的每次迭代都处理一个窗口消息或呈现一个帧。
Direct3D 9 桌面游戏中的游戏循环
while(WM_QUIT != msg.message)
{
// Process window events.
// 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
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// Render a new frame.
// Render frames during idle time (when no messages are waiting).
RenderFrame();
}
}
该游戏循环非常相似 - 但在游戏的 UWP 版本中却更加简单:
游戏循环进入 IFrameworkView::Run 方法(而不是 main()),因为我们的游戏在 IFrameworkView 类中起作用。
不再实现消息处理框架和调用 PeekMessage,我们可以调用为我们的应用窗口的 CoreDispatcher 构建的 ProcessEvents 方法。 游戏循环无需分流和处理消息 - 只需调用 ProcessEvents 并继续。
Direct3D 11 Microsoft Store 游戏中的游戏循环
// UWP apps should not exit. Use app lifecycle events instead.
while (true)
{
// Process window events.
auto dispatcher = CoreWindow::GetForCurrentThread()->Dispatcher;
dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
// Render a new frame.
RenderFrame();
}
现在,我们已经拥有一个 UWP 应用,该应用设置与我们的 DirectX 9 示例相同的基本图形基础结构并呈现相同的彩色立方体。
我此时该如何操作?
为 DirectX 11 移植 FAQ 创建书签。
DirectX UWP 模板包含可随时与游戏结合使用的强大 Direct3D 设备基础结构。 有关选取正确模板的指南,请参阅从模板创建 DirectX 游戏项目。
请访问下列做深入阐述的 Microsoft Store 游戏开发文章: