WarmGUI(3-0) 对DirectX2D绘图类封装、多线程绘图和优化处理(0)

这一篇距离上一篇整整隔了3个月,主要的原因大部分在学习绘图和DirectX2D的用法,学习C++,学习各种东西,另外部分原因是工作忙,不过这是借口。我学习DirectX2D的过程并不很愉快,经常看到不理解的古怪的行为,这可能是我没有开发过图形界面,现在把我学习到的总结出来,请高人们指正。

关于绘图方法应该有很很话题可以讨论,第0篇只是简单把基础的封装类作个说明,下一篇开始讨论多线程绘图和优化的一些方法作个铺垫。我用的平台是Win7+VC2010+SDK7.0a+DirectX June 2010

1.CDxFactorys对工厂封装

首先用CDxFactorys对几个工厂作个封装,他的工作有:
1 初始化的时候生成ID2D1Factory,IWICImagingFactory,IDWriteFactory的实例。
2.创建ID2D1HwndRenderTarget
3.获取屏幕Dpi
CDxFactorys应是Sigleton模式,在程序的各处都可以访问到唯一的实例。
这个类很平常,没有太多可说的。
 1 class WARMGUI_API CDxFactorys {
 2 private:
 3     CDxFactorys();
 4     ~CDxFactorys();
 5 
 6 public:
 7     HRESULT CreateRenderTarget(HWND hwnd, ID2D1HwndRenderTarget ** pHwndRenderTarget);
 8     ID2D1Factory*       GetD2DFactory();
 9     IWICImagingFactory* GetImgFactory();
10     IDWriteFactory*     GetDWriteFactory();
11 
12     HRESULT InitDxFactory();
13     void ReleaseResource();
14 
15     static CDxFactorys * GetInstance();
16 public:
17     float m_dpiScaleX;
18     float m_dpiScaleY;
19 
20 protected:
21     ID2D1Factory          * m_pD2DFactory;
22     IWICImagingFactory    * m_pImgFactory;
23     IDWriteFactory        * m_pDWriteFactory;
24 };

2. eArtist对绘图函数作封装

MFC用CDC类对绘制图形和文本作封装,我对应的类叫做艺术家,前面加个e表示电子艺术家eArtist,以区别传统的作画方法,以后会有特效动画什么的,但目前我用到的,还仅仅是对绘图和文字部分作的封装.有几点需要说明:

1. 在Direct2D的文档中特别强调绘图资源在GPU上的时间开销很大,因此建议尽量保留已有的绘图资源,不要频繁的创建和删除绘图资源。这写在文档Improving the Performance of Direct2D Applications中,因此上eArtist初始化如下的资源,直到应用程序退出再销毁他们:一个Hwnd-RenderTarget和从他派生出来的Bitmap-RenderTarget,默认的画刷SolidColorBrush,一个默认的StrokeStyle,以及默认的TextFormat等等。
2. Dx2D的绘图要在ID2D1RenderTarget接口的BeginDraw()和EndDraw()之中完成,这两个函数成对出现。如果想要在屏幕上看到图形,则必须在Hwnd-RT的调用EndDraw之后,才会把结果呈现出来。
3. 坐标变换在绘图过程中经常用到,最好在GPU上完成,必须小心的使用才能在正确的位置画出图形,我现在还经常被这个搞晕菜,这点在后面的例程中再讨论。
4. 指定artist当前使用Hwnd-RT或Bitmap-RT,Bitmap-RT有点类似于以前常用的MemoryDC,这两种RenderTarget各种用场,要参考DX2D的文档。
5. 用CreateBitmap创建一个位图,用CopyFromRenderTarget从当前的RenderTarget上拷贝到位图,Again,创建资源是消耗GPU时间的,应尽量避免,创建之后尽可能多的使用CopyFromXXX函数

eArtist的代码看起来是这样的:
 1 class WARMGUI_API eArtist
 2 {
 3 public:
 4     eArtist(void);
 5     ~eArtist(void);
 6 
 7     ///初始化
 8     void Init(HWND hwnd);
 9     ///重新设置RenderTarget大小
10     inline HRESULT ResizeRenderTarget(int cx, int cy);
11 
12     ///设定资源属性
13     inline HRESULT SetStrokeStyle(.);
14     inline HRESULT SetSolidColorBrush();
15     inline HRESULT SetTextFormat();
16 
17     ///绘图函数
18     inline void DrawText();
19     inline void DrawLine();
20     inline void DrawBitmap();
21     inline void DrawRectangle();
22     inline void FillRectangle();
23     inline void DrawEllipse();
24     inline void FillEllipse();
25 
26     ///用默认的Bitmap-RenderTarget绘图
27     inline void BeginBmpDraw(bool clear = false);
28     inline HRESULT EndBmpDraw();
29     ///用默认的Hwnd-RenderTarget绘图
30     inline void BeginDraw(bool clear = false);
31     inline HRESULT EndDraw();
32 
33     ///设定当前使用的RenderTarget为Hwnd-RenderTarget
34     inline void UsingHwndRT();
35     ///设定当前使用的RenderTarget为Bitmap-RenderTarget
36     inline void UsingBmpRT();
37     ///执行所有阻塞的绘图动作
38     inline HRESULT Flush();
39 
40     ///坐标变换
41     inline void SetTransform(MATRIX_2D_t* trans, bool bIsHwndRT = true);
42     inline void GetTransform(MATRIX_2D_t* trans, bool bIsHwndRT = true);
43 
44     ///创建一个Bitmap
45     inline HRESULT CreateBitmap(ID2D1Bitmap** pBitmap, RECT& rect);
46     ///拷贝RenderTarget图形到位图
47     inline HRESULT CopyFromRenderTarget(ID2D1Bitmap* pBitmap, POINT pointDest, RECT rectSrc);
48 
49 
50 private:
51     ID2D1HwndRenderTarget*         _pHwndRT;
52     ID2D1BitmapRenderTarget* _pDefaultBmpRT;
53     ID2D1SolidColorBrush*         _pscBrush;
54     ID2D1StrokeStyle*              _pStroke;
55     IDWriteTextFormat*         _pTextFormat;
56     IDWriteTextLayout*         _pTextLayout;
57     HWND _hwnd;
58 };
59

posted on 2012-12-15 16:24 毕达哥拉斯半圆 阅读(2550) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

导航

统计

常用链接

留言簿(3)

随笔档案

相册

contact

搜索

最新评论

阅读排行榜

评论排行榜