移植游戏循环

总结

演示如何实现通用 Windows 平台(UWP)游戏的窗口以及如何引入游戏循环,包括如何构建 IFrameworkView 来控制全屏 CoreWindow将简单的 Direct3D 9 应用移植到 DirectX 11 和 UWP 演练的第 3 部分。

创建窗口

若要使用 Direct3D 9 视区设置桌面窗口,我们必须为桌面应用实现传统的窗口化框架。 我们必须创建一个 HWND,设置窗口大小,提供一个窗口处理回调函数,使其可见,等等。

UWP 环境具有更简单的系统。 Microsoft Store 游戏不设置传统窗口,而是使用 DirectX 实现IFrameworkView。 DirectX 应用和游戏存在此接口,可在应用容器内的 CoreWindow 中直接运行。

注意 Windows 为资源(如源应用程序对象和 CoreWindow)提供托管指针。 请参阅 对象运算符句柄(^)

 

“main”类需要继承自 IFrameworkView,并实现五个 IFrameworkView 方法:初始化SetWindowLoadRunUninitialize。 除了创建基本上作为游戏所在位置的 IFrameworkView之外,还需要实现一个工厂类,用于创建 IFrameworkView的实例。 您的游戏仍然有一个名为 main()的方法的可执行文件,但其唯一功能是使用工厂创建 IFrameworkView 实例。

主要功能

//-----------------------------------------------------------------------------
// 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 实现中的游戏循环。 此代码存在于应用的主函数中。 此循环的每个迭代都会处理窗口消息或呈现一个帧。

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 类中运行。

我们可以调用内置于应用窗口的 CoreDispatcher中的 ProcessEvents 方法,而不是实现消息处理框架和调用 PeekMessage。 无需游戏循环来分支和处理消息 - 只需调用 ProcessEvents 并继续即可。

Direct3D 11 Microsoft 应用商店游戏中的游戏循环

// 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 移植常见问题解答添加书签。

DirectX UWP 模板包括一个可靠的 Direct3D 设备基础结构,可供游戏使用。 有关选择正确的模板的指导,请参阅 从模板创建 DirectX 游戏项目

请访问以下深入Microsoft应用商店游戏开发文章: