最近在做个游戏,因为不能用游戏引擎,所以一开始就选了MFC+GDI的组合,毕竟CImage类是相当好用的,结果发现游戏竟然在还没有加什么功能的时候就只能跑到30帧出头,我觉得有点悬,将来如果加上更多的功能的话,一旦卡到30帧以下就没法忍了。所以我去学了一下Direct2D,这个传说当中的GDI替代品。
网上现在Direct2D的资料不是很多,其中我感觉MSDN的几个样例比较适合新手入门,上面的例子都是Win32的,可能迁移到MFC有点障碍。这篇博客主要针对已经会用GDI做各种操作的人,使他们能够快速地迁移到Direct2D上。
我打算记录三件事在这里:一是基本准备,就是在正式干活之前你要做的事情(这一部分应该说是跟GDI最不一样的),第二是贴图,第三是渲染文字;这篇博客主要说说第一部分。
这几篇博客代码量会很大,但是这些代码都是可以复用的,也就是说,我们只需要将它扒下来,然后直接用就好了…………虽然我也研究了一整天;难点主要在于每部分之间的关系,这也使这篇笔记将着重讲的,实现当中的细节请去查阅MSDN。
首先,按照微软的示例所说的,我们应该创建一个.h文件,里面包括了我们常用的头文件:
#pragma once
// Windows Header Files:
#include <windows.h>
// C RunTime Header Files:
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <wchar.h>
#include <math.h>
#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>
#include <wincodec.h>
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "dwrite.lib")
template<class Interface>
inline void SafeRelease(Interface **ppInterfaceToRelease)
{
if (*ppInterfaceToRelease != NULL)
{
(*ppInterfaceToRelease)->Release();
(*ppInterfaceToRelease) = NULL;
}
}
#ifndef Assert
#if defined( DEBUG ) || defined( _DEBUG )
#define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)
#else
#define Assert(b)
#endif //DEBUG || _DEBUG
#endif
#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif
这里面比较重要的可能就是那个SafeRelease宏,我相信各位都知道它是干什么的……其他的我们可以暂时不关心。
然后就要说到资源,如果使用GDI的话,我们不需要什么前期准备,直接拿到DC往上面画就行了,但是D2D不一样,在干活之前,我们要先做些准备。这里是我自己封装的一个类,里面包含了常用的几种D2D需要的资源,在MFC中这些可以直接添加到View中,也可以让View继承这个类,享有这个类的成员和函数。
class CDirect2DMFCBase
{
private:
HWND m_hwnd;
ID2D1Factory* m_pDirect2dFactory;