Direct2D入门
来源:互联网 发布:淘宝自动发货机器人 编辑:程序博客网 时间:2024/06/05 22:49
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程序的结构
- 在程序初始化函数处(Constructor)创建设备独立资源,如ID2D1Factory,IDWriteFactory等;
- 创建设备依赖资源WM_CREATE,如果运行过程中出现设备丢失,需要重新创建;
- 响应WM_PAINT消息,在OnPaint()或OnDraw()等处,用创建的资源Render;
- 响应WM_SIZE消息,在OnSize()处调用ID2D1RenderTarget::Resize();
- 响应WM_ERASEBKGND,在OnEraseBkgnd()处返回FALSE,阻止GDI重绘客户区背景色,设置背景色的工作交给Direct2D在Render时设置,否则在Resize时会出现窗口闪烁的问题;
- 退出程序前WM_DESTROY,清理资源。
为提高程序的性能,尽量减少资源的创建和销毁操作,将能够重复利用的资源接口变量申明为View类的成员变量。
三. Direct2D demo
一个简单的MFC程序,用于演示Direct2D程序的结构和一些简单绘图操作。
1.Direct2D prerequisite
D2dPrerequisite.h,包含一些编译Direct2D程序所需要用到的头文件,lib库文件,帮助宏和预处理指令:
//D2dPrerequisite.h#pragma once////////////////////////////////////////////////////////////////////////////Header files and lib files for Direct2D and DirectWrite#include <d2d1.h>//Direct2D,for normal rendering task#include <d2d1helper.h>#include <dwrite.h>//DirectWrite,for drawing text#include <wincodec.h>//Windows imaging component,for image decoding#pragma comment(lib,"d2d1.lib")#pragma comment(lib,"dwrite.lib")#pragma comment(lib,"windowscodecs.lib")using namespace D2D1;////////////////////////////////////////////////////////////////////////////Helper template for resource releasingtemplate<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_THISCOMPONENTEXTERN_C IMAGE_DOS_HEADER __ImageBase;#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)#endif
2.View类中的成员变量:#include "D2dPrerequisite.h"//View.hprivate://Direct2D interfaceID2D1Factory* m_pD2d1Factory;ID2D1HwndRenderTarget* m_pHwndRenderTarget;ID2D1SolidColorBrush* m_pSolidColorBrush;ID2D1LinearGradientBrush* m_pLinearGradientBrush;ID2D1RadialGradientBrush* m_pRadialGradientBrush;//DirectWrite interfaceIDWriteFactory* m_pDWriteFactory;IDWriteTextFormat* m_pTextFormat;
3.创建设备独立资源//View.cppBOOL CD2D1_startView::CreateDeviceIndependentResource(){HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,&m_pD2d1Factory);ASSERT(hr == S_OK);if (SUCCEEDED(hr)){hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,__uuidof(m_pDWriteFactory),reinterpret_cast<IUnknown**>(&m_pDWriteFactory));ASSERT(hr == S_OK);}//Create TextFormat object with IDWriteFactoryif (SUCCEEDED(hr)){const CString fontName = _T("Verdana");const FLOAT fontSize = 32.0f;hr = m_pDWriteFactory->CreateTextFormat(fontName,NULL,DWRITE_FONT_WEIGHT_NORMAL,DWRITE_FONT_STYLE_NORMAL,DWRITE_FONT_STRETCH_NORMAL,fontSize,L"",//locale&m_pTextFormat);ASSERT(hr == S_OK);if (SUCCEEDED(hr)){//Center alignment vertically and horizontallym_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);}}return (hr == S_OK);}
4.创建设备依赖资源//View.cppBOOL CD2D1_startView::CreateDeviceDependentResource(){ASSERT(m_pD2d1Factory != NULL);if (m_pHwndRenderTarget != NULL)//There is no need to create render targetreturn TRUE;RECT rc;GetClientRect(&rc);D2D1_SIZE_U size = SizeU(rc.right-rc.left,rc.bottom-rc.top);HRESULT hr = m_pD2d1Factory->CreateHwndRenderTarget(RenderTargetProperties(),HwndRenderTargetProperties(m_hWnd,size),//Bind the HwndRenderTarget to view window&m_pHwndRenderTarget);ASSERT(hr == S_OK);if (SUCCEEDED(hr)){//Create solid color brushhr = m_pHwndRenderTarget->CreateSolidColorBrush(ColorF(ColorF::LightGreen),&m_pSolidColorBrush);ASSERT(hr == S_OK);//Create gradient stops collection,//used by linear gradient brush or radial gradient brushID2D1GradientStopCollection* pGradientStops = NULL;D2D1_GRADIENT_STOP stops[2];stops[0].color = ColorF(ColorF::Yellow);stops[0].position = 0.0f;stops[1].color = ColorF(ColorF::Red);stops[1].position = 1.0f;HRESULT hr = m_pHwndRenderTarget->CreateGradientStopCollection(stops,2,D2D1_GAMMA_2_2,D2D1_EXTEND_MODE_CLAMP,&pGradientStops);ASSERT(hr == S_OK);//Create linear gradient brushhr = m_pHwndRenderTarget->CreateLinearGradientBrush(LinearGradientBrushProperties(Point2F(210,110),Point2F(290,190)),pGradientStops,&m_pLinearGradientBrush);ASSERT(hr == S_OK);//Create radial gradient brushhr = m_pHwndRenderTarget->CreateRadialGradientBrush(RadialGradientBrushProperties(Point2F(350,150),Point2F(0,0),50,50),pGradientStops,&m_pRadialGradientBrush);ASSERT(hr == S_OK);SafeRelease(&pGradientStops);}return (hr == S_OK);}
5.Render//View.cppvoid CD2D1_startView::Render(){ASSERT(m_pD2d1Factory != NULL);if (!m_pHwndRenderTarget)//Render target need to be recreated{//Recreate device dependent resourceBOOL succeeded = CreateDeviceDependentResource();if (!succeeded)return;}const D2D1_COLOR_F redColor = ColorF(ColorF::Red);const D2D1_COLOR_F greenColor = ColorF(ColorF::Green);const D2D1_COLOR_F blueColor = ColorF(ColorF::Blue);const D2D1_COLOR_F yellowColor = ColorF(ColorF::Yellow);const D2D1_COLOR_F pinkColor = ColorF(ColorF::Pink);const D2D1_COLOR_F lightBlue = ColorF(ColorF::LightBlue);const D2D1_COLOR_F lightGreen = ColorF(ColorF::LightGreen);m_pHwndRenderTarget->BeginDraw();m_pHwndRenderTarget->Clear(ColorF(ColorF::White));//Clear the background//Draw line//We can set the color and opacity of solid color brush at any time,//so there is no need to create brushes for different colorsm_pSolidColorBrush->SetColor(redColor);D2D1_POINT_2F startPoint = Point2F(10,10);D2D1_POINT_2F endPoint = Point2F(90,90);m_pHwndRenderTarget->DrawLine(startPoint,endPoint,m_pSolidColorBrush,5.0);//Draw rectanglem_pSolidColorBrush->SetColor(greenColor);D2D1_RECT_F rect = RectF(110,10,190,90);m_pHwndRenderTarget->DrawRectangle(rect,m_pSolidColorBrush,4.0f);//Draw rounded rectanglem_pSolidColorBrush->SetColor(blueColor);rect = RectF(210,10,290,90);D2D1_ROUNDED_RECT roundedRect = RoundedRect(rect,10,10);m_pHwndRenderTarget->DrawRoundedRectangle(roundedRect,m_pSolidColorBrush,3.0f);//Draw ellipsem_pSolidColorBrush->SetColor(redColor);D2D1_POINT_2F center = D2D1::Point2F(350,50);D2D1_ELLIPSE ellipse = D2D1::Ellipse(center,40,30);m_pHwndRenderTarget->DrawEllipse(ellipse,m_pSolidColorBrush,3.0f);//Fill rectanglem_pSolidColorBrush->SetColor(pinkColor);rect = RectF(10,110,90,190);m_pHwndRenderTarget->FillRectangle(rect,m_pSolidColorBrush);//Fill rounded rectanglem_pSolidColorBrush->SetColor(blueColor);m_pSolidColorBrush->SetOpacity(0.3f);rect = RectF(110,110,190,190);roundedRect = RoundedRect(rect,20,20);m_pHwndRenderTarget->FillRoundedRectangle(roundedRect,m_pSolidColorBrush);//Fill rectangle with linear gradient brushrect = RectF(210,110,290,190);m_pHwndRenderTarget->FillRectangle(rect,m_pLinearGradientBrush);//Fill ellipse with gradient brushellipse = D2D1::Ellipse(Point2F(350,150),40,40);m_pHwndRenderTarget->FillEllipse(ellipse,m_pRadialGradientBrush);//Draw text with a linear gradient brushconst CString text = _T("Text drawed with Direct2D & DWrite!");rect = RectF(20,210,380,290);m_pHwndRenderTarget->DrawTextW(text,text.GetLength(),m_pTextFormat,rect,m_pLinearGradientBrush);HRESULT hr = m_pHwndRenderTarget->EndDraw();if (hr == D2DERR_RECREATE_TARGET)//Render target need to be recreated{//Discard all device dependent resources,//and recreate them in the next render procedureDiscardDeviceDependentResource();}}
6. 销毁设备依赖资源,以备下次Render时再次创建//View.cppvoid CD2D1_startView::DiscardDeviceDependentResource(){SafeRelease(&m_pRadialGradientBrush);SafeRelease(&m_pLinearGradientBrush);SafeRelease(&m_pSolidColorBrush);SafeRelease(&m_pHwndRenderTarget);}
7.Resize//View.cppvoid CD2D1_startView::Resize(int width,int height){if (m_pHwndRenderTarget){m_pHwndRenderTarget->Resize(SizeU(width,height));}}
四. 程序运行结果
- Direct2D入门
- Direct2D入门
- Direct2D编程入门
- Direct2D 快速入门
- Direct2D 快速入门
- Direct2D 编程入门
- Direct2D快速入门
- 高效的渲染引擎——Direct2D入门
- Direct2D 1.1
- Direct2D 几何图形
- Direct2D 变换
- Introducing Direct2D
- Direct2D QuickStart
- Direct2d , WICBITMAP
- Direct2d effects
- Direct2D 简介
- Direct2D介绍
- 关于Direct2D
- 关于OBJECT标签
- 比较变量地址并不可靠
- 风雨十年:一个老程序员的心里话(上)
- jqGrid表格插件——参数配置
- 使用SqlDependency监听MSSQL数据库表变化通知
- Direct2D入门
- java发送udp广播包
- 外观模式(Facade)
- C++面试宝典
- The iPad Split
- 简单排序
- 傻嘎,IOC原来是这样子的
- java多进程
- 纪念公司关张一周年 IT的老兵:我们缺什么二(2013.6)