Windows 8系统10月25日就要正式发布,其应用可与Windows Phone 8应用兼容,所以打算转到Windows 8系列的开发。之前虽然开发过应用,但对游戏开发更感兴趣,随意开始学习Metro风格的Directx开发。同WindowsPhone 7开发一样,首先从最基本的应用开始看。但使用Directx不像之前那么简单,自己写不出示例代码,只好选择VS2012的模板项目开始学习。
使用VS2012新建项目->WindowsStore应用->Directx3D项目建立模板,在一系列文件中挑DirectxApp.cpp和DirectxApp.h这两个文件入手,因为应用的main方法在DirectxApp.cpp中,感觉从main方法追踪程序的运行流程方便理解整个应用。DirectxApp.cpp里的main方法:
[Platform::MTAThread]
int main(Platform::Array<Platform::String^>^)
{
autodirect3DApplicationSource =refnewDirect3DApplicationSource();
CoreApplication::Run(direct3DApplicationSource);
return 0;
}
可以看出,应用启动时,系统创建一个源对象Direct3DApplicationSource,CoreApplication.Run 方法使用该对象来运行程序。既然如此,应用的各种配置应该在源对象Direct3DApplicationSource中设置。选中Direct3DApplicationSource按F12跳到该类定义:
ref class Direct3DApplicationSourcesealed :Windows::ApplicationModel::Core::IFrameworkViewSource
{
public:
virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
};
可以看到这个类实现了IFrameworkViewSource接口。IFrameworkViewSource中单独定义CreateView()方法,这个方法的实现如下:
IFrameworkView^ Direct3DApplicationSource::CreateView()
{
return ref new Direct3DApp();
}
这里看到App类有些眼熟,以前用MFC框架时也有一个App类。转到Direct3DApp的定义可以看到其中包含各种方法和事件处理程序,像鼠标点击、移动等事件。
ref class Direct3DApp sealed : publicWindows::ApplicationModel::Core::IFrameworkView
{
public:
Direct3DApp();
// IFrameworkView 方法。
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
virtual void Load(Platform::String^ entryPoint);
virtual void Run();
virtual void Uninitialize();
protected:
// 事件处理程序。
void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender,Windows::UI::Core::WindowSizeChangedEventArgs^ args);
void OnLogicalDpiChanged(Platform::Object^ sender);
void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView,Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
void OnSuspending(Platform::Object^ sender,Windows::ApplicationModel::SuspendingEventArgs^ args);
void OnResuming(Platform::Object^ sender, Platform::Object^ args);
void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender,Windows::UI::Core::CoreWindowEventArgs^ args);
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender,Windows::UI::Core::VisibilityChangedEventArgs^ args);
void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);
void OnPointerMoved(Windows::UI::Core::CoreWindow^ sender,Windows::UI::Core::PointerEventArgs^ args);
private:
CubeRenderer^ m_renderer;
bool m_windowClosed;
bool m_windowVisible;
};
Direct3DApp的构造方法初始化成员变量,设置应用为非关闭,可见状态。
Direct3DApp::Direct3DApp() :
m_windowClosed(false),
m_windowVisible(true)
{
}
从名称上看,接着构造方法的5个IFrameworkView公共方法:Initialize、SetWindow、Load、Run、Uninitialize分别用来初始化视图、设置窗口、载入资源、运行应用,及释放应用。其中Load和Uninitialize方法为空,因为模板应用简单,没有涉及资源。
Initialize为一系列基本事件添加了事件处理程序,并创建了一个CubeRender对象。这个方法为应用配置好基本功能,关联的事件也与应用生命周期相关,感觉这一步属于打基础。
void Direct3DApp::Initialize(CoreApplicationView^applicationView)
{
applicationView->Activated +=
ref new TypedEventHandler<CoreApplicationView^,IActivatedEventArgs^>(this, &Direct3DApp::OnActivated);
CoreApplication::Suspending +=
ref new EventHandler<SuspendingEventArgs^>(this, &Direct3DApp::OnSuspending);
CoreApplication::Resuming +=
ref new EventHandler<Platform::Object^>(this, &Direct3DApp::OnResuming);
m_renderer = ref new CubeRenderer();
}
SetWindow为基本操作事件添加事件处理程序,这些处理与窗口的显示相关,感觉属于应用搭建完成,准备显示的阶段。
void Direct3DApp::SetWindow(CoreWindow^window)
{
window->SizeChanged +=
ref new TypedEventHandler<CoreWindow^,WindowSizeChangedEventArgs^>(this, &Direct3DApp::OnWindowSizeChanged);
window->VisibilityChanged +=
ref new TypedEventHandler<CoreWindow^,VisibilityChangedEventArgs^>(this, &Direct3DApp::OnVisibilityChanged);
window->Closed +=
ref new TypedEventHandler<CoreWindow^,CoreWindowEventArgs^>(this, &Direct3DApp::OnWindowClosed);
window->PointerCursor =refnewCoreCursor(CoreCursorType::Arrow, 0);
window->PointerPressed +=
ref new TypedEventHandler<CoreWindow^,PointerEventArgs^>(this, &Direct3DApp::OnPointerPressed);
window->PointerMoved +=
ref new TypedEventHandler<CoreWindow^,PointerEventArgs^>(this, &Direct3DApp::OnPointerMoved);
m_renderer->Initialize(CoreWindow::GetForCurrentThread());
}
Run是应用的主循环,可以看到,在各项准备工作完成后,它控制整个应用的流程和消息分配,实际显示内容由CubeRenderer定义。
void Direct3DApp::Run()
{
BasicTimer^ timer = ref new BasicTimer();
while (!m_windowClosed)
{
if (m_windowVisible)
{
timer->Update();
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
m_renderer->Update(timer->Total,timer->Delta);
m_renderer->Render();
m_renderer->Present(); // 此调用将同步为显示帧速率。
}
else
{
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
}
}
}
整个应用的流程如图1,因为无法查看CoreApplication.Run方法的代码,只是推测一下细节流程,这样DirectxApp.cpp和DirectxApp.h两个文件的内容就看差不多了,接着需要看的是CubeRenderer的相关文件。
图1 应用流程