当前位置: 首页 > news >正文

Direct2D入门

. 资源管理(Resource management)

Direct3D一样,Direct2D程序需要处理设备丢失(Device lost)问题。Direct2D中的资源分为设备独立资源(Device independent resource)和设备依赖资源(Device dependent resource)

设备独立资源包括:

  • ID2D1DrawingStateBlock
  • ID2D1Factory
  • ID2D1Geometry 和由此继承而来的接口
  • ID2D1GeometrySink and ID2D1SimplifiedGeometrySink
  • ID2D1StrokeStyle

设备依赖资源包括:

  • ID2D1Brush 和由此继承而来的接口
  • ID2D1Layer
  • ID2D1RenderTarget 和由此继承而来的接口
  • 其他资源

具体参见:http://msdn.microsoft.com/en-us/library/dd756757(v=VS.85).aspx

. Direct2D程序的结构

  1. 在程序初始化函数处创建设备独立资源,如ID2D1FactoryIDWriteFactory等;
  2. 创建设备依赖资源,如果运行过程中出现设备丢失,需要重新创建;
  3. 响应WM_PAINT消息,在OnPaint()OnDraw()等处,用创建的资源Render
  4. 响应WM_SIZE消息,在OnSize()处调用ID2D1RenderTarget::Resize();
  1. 响应WM_ERASEBKGND,在OnEraseBkgnd()处返回FALSE,阻止GDI重绘客户区背景色,设置背景色的工作交给Direct2DRender时设置,否则在Resize时会出现窗口闪烁的问题;
  1. 退出程序前,清理资源。

为提高程序的性能,尽量减少资源的创建和销毁操作,将能够重复利用的资源接口变量申明为View类的成员变量。

. Direct2D demo

一个简单的MFC程序,用于演示Direct2D程序的结构和一些简单绘图操作。

1.Direct2D prerequisite

D2dPrerequisite.h,包含一些编译Direct2D程序所需要用到的头文件,lib库文件,帮助宏和预处理指令:

 

  1: //D2dPrerequisite.h

  2: #pragma once

  3:

  4: //

  5: //Header files and lib files for Direct2D and DirectWrite

  6: #include <d2d1.h>                //Direct2D,for normal rendering task

  7: #include <d2d1helper.h>        

  8: #include <dwrite.h>                //DirectWrite,for drawing text

  9: #include <wincodec.h>                //Windows imaging component,for image decoding

 10:

 11: #pragma comment(lib,"d2d1.lib")

 12: #pragma comment(lib,"dwrite.lib")

 13: #pragma comment(lib,"windowscodecs.lib")

 14:

 15: //

 16: //Helper template for resource releasing

 17: template<class Interface>

 18: inlinevoid SafeRelease(Interface **ppInterfaceToRelease)

 19: {

 20:         if (*ppInterfaceToRelease != NULL)

 21:         {

 22:                 (*ppInterfaceToRelease)->Release();

 23:                 (*ppInterfaceToRelease) = NULL;

 24:         }

 25: }

 26:

 27: #ifndef Assert

 28: #if defined( DEBUG ) || defined( _DEBUG )

 29: #define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)

 30: #else

 31: #define Assert(b)

 32: #endif //DEBUG || _DEBUG

 33: #endif

 34:

 35: #ifndef HINST_THISCOMPONENT

 36: EXTERN_C IMAGE_DOS_HEADER __ImageBase;

 37: #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)

 38: #endif

2.View类中的成员变量:

 

  1: //View.h

  2: private:

  3:         //Direct2D interface

  4:         ID2D1Factory* m_pD2d1Factory;

  5:         ID2D1HwndRenderTarget* m_pHwndRenderTarget;

  6:         ID2D1SolidColorBrush* m_pSolidColorBrush;

  7:         ID2D1LinearGradientBrush* m_pLinearGradientBrush;

  8:         ID2D1RadialGradientBrush* m_pRadialGradientBrush;

  9:

 10:         //DirectWrite interface

 11:         IDWriteFactory* m_pDWriteFactory;

 12:         IDWriteTextFormat* m_pTextFormat;

3.创建设备独立资源

 

  1: //View.cpp

  2: BOOL CBasicView::CreateDeviceIndependentResource()

  3: {

  4:         HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,&m_pD2d1Factory);

  5:         ASSERT(hr == S_OK);

  6:

  7:         if (SUCCEEDED(hr))

  8:         {

  9:                 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,

 10:                         __uuidof(m_pDWriteFactory),

 11:                         reinterpret_cast<IUnknown**>(&m_pDWriteFactory));

 12:                 ASSERT(hr == S_OK);

 13:         }

 14:         

 15:         //Create TextFormat object with IDWriteFactory

 16:         if (SUCCEEDED(hr))

 17:         {

 18:                 const CString fontName = _T("Verdana");

 19:                 const FLOAT fontSize = 32.0f;

 20:                 hr = m_pDWriteFactory->CreateTextFormat(

 21:                         fontName,

 22:                         NULL,

 23:                         DWRITE_FONT_WEIGHT_NORMAL,

 24:                         DWRITE_FONT_STYLE_NORMAL,

 25:                         DWRITE_FONT_STRETCH_NORMAL,

 26:                         fontSize,

 27:                         L"",        //locale

 28:                         &m_pTextFormat

 29:                         );

 30:                 ASSERT(hr == S_OK);

 31:                 if (SUCCEEDED(hr))

 32:                 {

 33:                         //Center alignment vertically and horizontally

 34:                         m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);

 35:                         m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

 36:                 }

 37:         }

 38:         return (hr == S_OK);

 39: }

4.创建设备依赖资源

 

  1: //View.cpp

  2: BOOL CBasicView::CreateDeviceDependentResource()

  3: {

  4:         ASSERT(m_pD2d1Factory != NULL);

  5:         if (m_pHwndRenderTarget != NULL)        //There is no need to create render target

  6:                 return TRUE;

  7:

  8:         RECT rc;

  9:         GetClientRect(&rc);

 10:         D2D1_SIZE_U size = SizeU(rc.right-rc.left,rc.bottom-rc.top);

 11:         HRESULT hr = m_pD2d1Factory->CreateHwndRenderTarget(

 12:                 RenderTargetProperties(),

 13:                 HwndRenderTargetProperties(m_hWnd,size),//Bind the HwndRenderTarget to view window

 14:                 &m_pHwndRenderTarget);

 15:         ASSERT(hr == S_OK);

 16:         if (SUCCEEDED(hr))

 17:         {

 18:                 //Create solid color brush

 19:                 hr = m_pHwndRenderTarget->CreateSolidColorBrush(

 20:                         ColorF(ColorF::LightGreen),

 21:                         &m_pSolidColorBrush);

 22:                 ASSERT(hr == S_OK);

 23:

 24:                 //Create gradient stops collection,

 25:                 //used by linear gradient brush or radial gradient brush

 26:                 ID2D1GradientStopCollection* pGradientStops = NULL;

 27:                 D2D1_GRADIENT_STOP stops[2];

 28:                 stops[0].color = ColorF(ColorF::Yellow);

 29:                 stops[0].position = 0.0f;

 30:                 stops[1].color = ColorF(ColorF::Red);

 31:                 stops[1].position = 1.0f;

 32:                 HRESULT hr = m_pHwndRenderTarget->CreateGradientStopCollection(

 33:                         stops,

 34:                         2,

 35:                         D2D1_GAMMA_2_2,

 36:                         D2D1_EXTEND_MODE_CLAMP,

 37:                         &pGradientStops);

 38:                 ASSERT(hr == S_OK);

 39:

 40:                 //Create linear gradient brush

 41:                 hr = m_pHwndRenderTarget->CreateLinearGradientBrush(

 42:                         LinearGradientBrushProperties(Point2F(210,110),Point2F(290,190)),

 43:                         pGradientStops,

 44:                         &m_pLinearGradientBrush);

 45:                 ASSERT(hr == S_OK);

 46:

 47:                 //Create radial gradient brush

 48:                 hr = m_pHwndRenderTarget->CreateRadialGradientBrush(

 49:                         RadialGradientBrushProperties(Point2F(350,150),Point2F(0,0),50,50),

 50:                         pGradientStops,

 51:                         &m_pRadialGradientBrush);

 52:                 ASSERT(hr == S_OK);

 53:

 54:                 SafeRelease(&pGradientStops);

 55:         }

 56:         

 57:         return (hr == S_OK);

 58: }

5.Render

 

  1: //View.cpp

  2: void CBasicView::Render()

  3: {

  4:         ASSERT(m_pD2d1Factory != NULL);

  5:         if (!m_pHwndRenderTarget)        //Render target need to be recreated

  6:         {

  7:                 //Recreate device dependent resource

  8:                 BOOL succeeded = CreateDeviceDependentResource();

  9:                 if (!succeeded)

 10:                         return;

 11:         }

 12:         

 13:         const D2D1_COLOR_F redColor = ColorF(ColorF::Red);

 14:         const D2D1_COLOR_F greenColor = ColorF(ColorF::Green);

 15:         const D2D1_COLOR_F blueColor = ColorF(ColorF::Blue);

 16:         const D2D1_COLOR_F yellowColor = ColorF(ColorF::Yellow);

 17:         const D2D1_COLOR_F pinkColor = ColorF(ColorF::Pink);

 18:         const D2D1_COLOR_F lightBlue = ColorF(ColorF::LightBlue);

 19:         const D2D1_COLOR_F lightGreen = ColorF(ColorF::LightGreen);

 20:

 21:         m_pHwndRenderTarget->BeginDraw();

 22:         m_pHwndRenderTarget->Clear(ColorF(ColorF::White));        //Clear the background

 23:         

 24:         //Draw line

 25:         //We can set the color and opacity of solid color brush at any time,

 26:         //so there is no need to create brushes for different colors

 27:         m_pSolidColorBrush->SetColor(redColor);        

 28:         D2D1_POINT_2F startPoint = Point2F(10,10);

 29:         D2D1_POINT_2F endPoint = Point2F(90,90);

 30:         m_pHwndRenderTarget->DrawLine(startPoint,endPoint,m_pSolidColorBrush,5.0);

 31:

 32:         //Draw rectangle

 33:         m_pSolidColorBrush->SetColor(greenColor);

 34:         D2D1_RECT_F rect = RectF(110,10,190,90);

 35:         m_pHwndRenderTarget->DrawRectangle(rect,m_pSolidColorBrush,4.0f);

 36:

 37:         //Draw rounded rectangle

 38:         m_pSolidColorBrush->SetColor(blueColor);

 39:         rect = RectF(210,10,290,90);

 40:         D2D1_ROUNDED_RECT roundedRect = RoundedRect(rect,10,10);

 41:         m_pHwndRenderTarget->DrawRoundedRectangle(roundedRect,m_pSolidColorBrush,3.0f);

 42:

 43:         //Draw ellipse

 44:         m_pSolidColorBrush->SetColor(redColor);

 45:         D2D1_POINT_2F center = D2D1::Point2F(350,50);

 46:         D2D1_ELLIPSE ellipse = D2D1::Ellipse(center,40,30);

 47:         m_pHwndRenderTarget->DrawEllipse(ellipse,m_pSolidColorBrush,3.0f);

 48:

 49:         //Fill rectangle

 50:         m_pSolidColorBrush->SetColor(pinkColor);

 51:         rect = RectF(10,110,90,190);

 52:         m_pHwndRenderTarget->FillRectangle(rect,m_pSolidColorBrush);

 53:

 54:         //Fill rounded rectangle

 55:         m_pSolidColorBrush->SetColor(blueColor);

 56:         m_pSolidColorBrush->SetOpacity(0.3f);

 57:         rect = RectF(110,110,190,190);

 58:         roundedRect = RoundedRect(rect,20,20);

 59:         m_pHwndRenderTarget->FillRoundedRectangle(roundedRect,m_pSolidColorBrush);

 60:

 61:         //Fill rectangle with linear gradient brush

 62:         rect = RectF(210,110,290,190);

 63:         m_pHwndRenderTarget->FillRectangle(rect,m_pLinearGradientBrush);

 64:         

 65:         //Fill ellipse with gradient brush

 66:         ellipse = D2D1::Ellipse(Point2F(350,150),40,40);

 67:         m_pHwndRenderTarget->FillEllipse(ellipse,m_pRadialGradientBrush);

 68:

 69:         //Draw text with a linear gradient brush

 70:         const CString text = _T("Text drawed with Direct2D & DWrite!");

 71:         rect = RectF(20,210,380,290);

 72:         m_pHwndRenderTarget->DrawTextW(

 73:                 text,

 74:                 text.GetLength(),

 75:                 m_pTextFormat,

 76:                 rect,

 77:                 m_pLinearGradientBrush);

 78:

 79:         HRESULT hr = m_pHwndRenderTarget->EndDraw();

 80:

 81:         if (hr == D2DERR_RECREATE_TARGET)        //Render target need to be recreated

 82:         {

 83:                 //Discard all device dependent resources,

 84:                 //and recreate them in the next render procedure

 85:                 DiscardDeviceDependentResource();

 86:         }

 87: }

6. 销毁设备依赖资源,以备下次Render时再次创建

 

  1: //View.cpp

  2: void CBasicView::DiscardDeviceDependentResource()

  3: {

  4:         SafeRelease(&m_pRadialGradientBrush);

  5:         SafeRelease(&m_pLinearGradientBrush);

  6:         SafeRelease(&m_pSolidColorBrush);

  7:         SafeRelease(&m_pHwndRenderTarget);

  8: }

7.Resize

 

  1: //View.cpp

  2: void CBasicView::Resize(int width,int height)

  3: {

  4:         if (m_pHwndRenderTarget)

  5:         {

  6:                 m_pHwndRenderTarget->Resize(SizeU(width,height));

  7:         }

  8: }

转载于:https://www.cnblogs.com/hhdllhflower/archive/2012/10/04/2711706.html

相关文章:

  • Mina2.0框架源码剖析(二)
  • 64位ubuntu下安装32位jdk
  • response.setHeader()的用法
  • PCIE BAR空间
  • HDU5115:Dire Wolf——题解+翻译
  • JS常用代码
  • [iOS]中字体样式设置 API
  • 20个Jquery表单插件
  • MAC上Git安装与GitHub基本使用
  • ORACLE -- RAC Debug 之路 CRS-0184错误与CRS初始化
  • chrome插件控制台
  • 英特尔研发神经元AI处理器,模仿大脑功能,无需训练数据集
  • android 里使用Socket进行发送消息案例
  • 进程间通信基础知识
  • 解决Please check that your locale settings
  • 时间复杂度分析经典问题——最大子序列和
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • JavaScript 奇技淫巧
  • Java到底能干嘛?
  • springboot_database项目介绍
  • vue 个人积累(使用工具,组件)
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 官方解决所有 npm 全局安装权限问题
  • 计算机在识别图像时“看到”了什么?
  • 技术胖1-4季视频复习— (看视频笔记)
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 聊聊sentinel的DegradeSlot
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 浅谈web中前端模板引擎的使用
  • 区块链分支循环
  • 山寨一个 Promise
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 详解移动APP与web APP的区别
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 进程与线程(三)——进程/线程间通信
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​决定德拉瓦州地区版图的关键历史事件
  • %@ page import=%的用法
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (ibm)Java 语言的 XPath API
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (一)Thymeleaf用法——Thymeleaf简介
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • ../depcomp: line 571: exec: g++: not found
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .NET Reactor简单使用教程
  • .NET 设计模式初探
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET(C#) Internals: as a developer, .net framework in my eyes
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • .Net转前端开发-启航篇,如何定制博客园主题
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录