移植遊戲迴圈
摘要
- 第 1 部分:初始化 Direct3D 11
- 第 2 部分:轉換轉譯架構
- 第 3 部分:移植遊戲迴圈
說明如何實作通用 Windows 平台 (UWP) 遊戲的視窗,以及如何轉移遊戲迴圈,包括如何建置 IFrameworkView 以控制全螢幕 CoreWindow。 《將簡單的 Direct3D 9 應用程式移植到 DirectX 11 和通用 Windows 平台 (UWP)》逐步解說的第 3 部分。
建立視窗
若要使用 Direct3D 9 檢視區設定桌面視窗,我們必須實作桌面應用程式適用的傳統型視窗化架構。 我們必須建立 HWND、設定視窗大小、提供視窗處理回呼、將其設為顯示等等。
UWP 環境的系統更簡單。 Microsoft Store 遊戲不會設定傳統視窗,而是使用 DirectX 實作 IFrameworkView。 此介面可讓 DirectX 應用程式和遊戲直接在應用程式容器內的 CoreWindow 中執行。
注意Windows 會提供受控指標給資源,例如來源應用程式物件和 CoreWindow。 請參閱<物件控制代碼運算子 (^)>。
「主要」類別需要繼承自 IFrameworkView,並實作以下五個 IFrameworkView 方法:Initialize、SetWindow、Load、Run 和 Uninitialize。 除了建立 IFrameworkView (也就是遊戲所在位置),您還需要實作用來建立 IFrameworkView 執行個體的 factory 類別。 遊戲還是會有內含 main() 方法的可執行檔,但所有主要類別可執行的是使用 factory 建立 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 factory
//-----------------------------------------------------------------------------
// 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 類別內運作。
我們並不是實作訊息處理架構及呼叫 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 應用程式,設定了相同的基本圖形基礎結構並轉譯相同的彩色 Cube,如 DirectX 9 範例所述。
接下來還可以做什麼?
請將 DirectX 11 移植常見問題頁面加入書籤。
DirectX UWP 範本包含健全的 Direct3D 裝置基礎結構,可直接搭配您的遊戲使用。 如需有關如何挑選合適範本的指引,請參閱<從範本建立 DirectX 遊戲專案>。
請參閱下列 Microsoft Store 遊戲開發文章,內含詳細說明: