之前说过,D2D主要为了绘制有三种类型的数据:几何图形,图片,文字。这几种对象也叫做资源,资源就是要D2D流水线中要被加工的对象。

几何图形包括

  • 简单几何图形

    • 直线,DrawLine,由起点和终点构成,点用结构体:D2D1_POINT_2F描述。
    • 矩形,ID2D1RectangleGeometry,DrawRectangle,由距四条边的距离表示,用结构体:D2D1_RECT_F描述。
    • 圆角矩形,ID2D1RoundedRectangleGeometry ,DrawRoundedRectangle,同矩形,用结构体:D2D1_ROUNDED_RECT描述,另外还要加入圆角参数。
    • 椭圆,包括圆,ID2D1EllipseGeometry ,DrawEllipse,用结构体:D2D1_ELLIPSE 描述。
  • 路径,ID2D1PathGeometry
  • 组合图形,
    • 几何图形组合,ID2D1GeometryGroup
    • 变幻几何图形,ID2D1TransformedGeometry

准备绘制:

在开始绘制之前,至少要准备好3样东西:
  • D2D工厂对象,ID2D1Factory接口。用于创建绘制目标,用方法CreateHwndRenderTarget。
  • 渲染窗口,ID2D1HwndRenderTarget接口。如果是Win32程序就是默认的HWND窗口,如果是商店应用则是一个绘制表面的控件。
    渲染窗口同时还负责着绘制几何图形,文字和图片。
  • 画刷,ID2D1SolidColorBrush接口。绘制几何图形时用于指定图形的样式。
  • 绘制区域,如果是win32程序还需要指定渲染窗口中要绘制的区域。
首先要引入头文件和命名空间:
#include "windows.h"
#include "D2D1.h" using namespace D2D1;
别忘了加要链接的Lib,要input的lib如下:
d2d1.lib;
dxgi.lib;
dwrite.lib;
dxguid.lib;
windowscodecs.lib;

声明以上4个对象的代码如下:

	// Direct2D factory
ID2D1Factory* pD2DFactory;
// Render target
ID2D1HwndRenderTarget* pRenderTarget;
// A black brush, reflect the line color
ID2D1SolidColorBrush* pBlackBrush;
// Render area
RECT rc ;

初始化这些值的代码如下:

	//create d2d factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory) ;
//create render target (hwnd window)
GetClientRect(hWnd, &rc);
hr = pD2DFactory->CreateHwndRenderTarget( RenderTargetProperties(), HwndRenderTargetProperties(hWnd, SizeU(rc.right - rc.left, rc.bottom - rc.top)), &pRenderTarget);
//create brush
hr = pRenderTarget->CreateSolidColorBrush(ColorF(ColorF::Blue), &pBlackBrush);

然后就可以开始绘制了。笔者使用的程序是win32应用程序,绘制的代码都必须写在WndProc回调函数的case WM_PAINT:之后,并且要将所有绘制代码都包含在pRenderTarget->BeginDraw();和pRenderTarget->EndDraw();之间。例如:

	pRenderTarget->BeginDraw();

	//clear screen
pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White)); //draw line with 2 points
D2D1_POINT_2F ptStart = Point2F(0,0);
D2D1_POINT_2F ptEnd = Point2F(100,100);
pRenderTarget->DrawLine(ptStart,ptEnd,pBlackBrush); //draw rectangle
D2D1_RECT_F rect = RectF(rc.left + 100.0f, rc.top + 100.0f, rc.right - 100.0f, rc.bottom - 100.0f);
pRenderTarget->DrawRectangle(rect, pBlackBrush); //draw round rect
D2D1_ROUNDED_RECT roundrect = RoundedRect(RectF(rc.left + 100.0f, rc.top + 100.0f, rc.right - 100.0f, rc.bottom - 100.0f), 30.0f, 50.0f);
pRenderTarget->DrawRoundedRectangle(roundrect, pBlackBrush, 1.0f); pRenderTarget->EndDraw();

WM_PAINT是在窗口需要重绘时由系统调用的,所以我们不用主动地去调用它,它们不断地刷新的。

当然了,把代码都积压在WM_PAINT之后也太SB了,最好自己封装一个类,如下:

头文件如下:
#pragma once

#include "stdafx.h"
#include "windows.h"
#include "D2D1.h" using namespace D2D1; class D2DRender
{
public:
D2DRender(void);
~D2DRender(void); HRESULT CreateDeviceIndependentResources();
HRESULT CreateDeviceResources(HWND hWnd);
void OnRender();
void DiscardDeviceResources();
void OnResize(UINT width, UINT height); private:
// Direct2D factory
ID2D1Factory* pD2DFactory;
// Render target
ID2D1HwndRenderTarget* pRenderTarget;
// A black brush, reflect the line color
ID2D1SolidColorBrush* pBlackBrush;
// Render area
RECT rc ;
//result
HRESULT hr;
};

实现如下:

#include "stdafx.h"
#include "D2DRender.h" D2DRender::D2DRender()
{
// Direct2D factory
pD2DFactory = NULL;
// Render target
pRenderTarget = NULL;
// A black brush, reflect the line color
pBlackBrush = NULL;
} D2DRender::~D2DRender()
{
pD2DFactory->Release();
pRenderTarget->Release();
pBlackBrush->Release(); } void D2DRender::DiscardDeviceResources()
{
pD2DFactory->Release();
pRenderTarget->Release();
pBlackBrush->Release();
} void D2DRender::OnResize(UINT width, UINT height)
{
if(pRenderTarget)
{
pRenderTarget->Resize(SizeU(width,height));
}
} HRESULT D2DRender::CreateDeviceIndependentResources()
{
//create d2d factory
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory) ; return hr;
} HRESULT D2DRender::CreateDeviceResources(HWND hWnd)
{
//create render target (hwnd window)
GetClientRect(hWnd, &rc);
hr = pD2DFactory->CreateHwndRenderTarget( RenderTargetProperties(), HwndRenderTargetProperties(hWnd, SizeU(rc.right - rc.left, rc.bottom - rc.top)), &pRenderTarget); //create brush
hr = pRenderTarget->CreateSolidColorBrush(ColorF(ColorF::Blue), &pBlackBrush); return hr;
} void D2DRender::OnRender()
{
pRenderTarget->BeginDraw(); //clear screen
pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White)); //draw line with 2 points
D2D1_POINT_2F ptStart = Point2F(0,0);
D2D1_POINT_2F ptEnd = Point2F(100,100);
pRenderTarget->DrawLine(ptStart,ptEnd,pBlackBrush); //draw rectangle
D2D1_RECT_F rect = RectF(rc.left + 100.0f, rc.top + 100.0f, rc.right - 100.0f, rc.bottom - 100.0f);
pRenderTarget->DrawRectangle(rect, pBlackBrush); //draw round rect
D2D1_ROUNDED_RECT roundrect = RoundedRect(RectF(rc.left + 100.0f, rc.top + 100.0f, rc.right - 100.0f, rc.bottom - 100.0f), 30.0f, 50.0f);
pRenderTarget->DrawRoundedRectangle(roundrect, pBlackBrush, 1.0f); pRenderTarget->EndDraw();
}

然后在WM_PANIT里调用,默认生成的gdi绘制用到的hdc相关代码可以删掉。

	case WM_PAINT:
//hdc = BeginPaint(hWnd, &ps);
D2DRender pRender;
pRender.CreateDeviceIndependentResources();
pRender.CreateDeviceResources(hWnd);
pRender.OnRender();
//EndPaint(hWnd, &ps);
break;

还是比较简单。


Direct2D 几何图形绘制基础的更多相关文章

  1. android Graphics(一):概述及基本几何图形绘制

    前言:我最近想抽空研究研究android的各种特效,android的特效真是其它平台无法比拟的,而且一个漂亮的UI交互,会给APP增色不少,而学习特效之前,有关graphics绘图的基础知识是必不可少 ...

  2. 自定义View入门-绘制基础(1)

    ### 前言 说道自定义View,我们一定会想到,自定义View的绘制流程 - 测量阶段(measure) - 布局阶段(layout) - 绘制阶段(draw) 我们看到的一些炫酷的view效果,都 ...

  3. [Direct2D开发] 绘制网格

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.引言 最近在使用Direct2D进行绘制工作中,需要实现使用Direct2D绘制网格的功能.在网上查了很多资料,终于实 ...

  4. android Graphics类:概述及基本几何图形绘制

    当须要在Android上绘制图形时.就会用到Graphics类.Paint类.Paint就是相当于笔,而Canvas就是 纸.这里叫画布. 所以,凡有跟要要画的东西的设置相关的.比方大小,粗细,画笔颜 ...

  5. 2019-10-23-C#-从零开始写-SharpDx-应用-绘制基础图形

    title author date CreateTime categories C# 从零开始写 SharpDx 应用 绘制基础图形 lindexi 2019-10-23 21:16:35 +0800 ...

  6. Android自定控件基础(一)——几何图形绘制

    虽然本人有几年开发经验,但是自定义控件这一块儿,研究的很少,惭愧--用到的时候就是百度查找,复制粘贴.工时紧,总是想的快点完工就好.(都是借口啦,想学总会有时间哒) 作为一个Android开发 要说自 ...

  7. 《MATLAB从入门到放弃》二维曲线和图形绘制基础(二):使用Help文档学习line、plot、plotyy、subplot、hold绘图函数

    目录: »  plot 最常用的二维曲线绘图函数 >  帮助文档 >  基本使用语法 >  线条的样式.符号和颜色调整 >  图形属性调整 >  使用图形句柄进行设置 » ...

  8. Flutter自定义绘制(1)- 绘制基础

    CustomPainter Flutter 中实现绘制的主要是CustomPainter类. 我们一般继承这个类,来使用它: class MyPainter extends CustomPainter ...

  9. 自定义控件之Canvas图形绘制基础练习-青春痘笑脸^_^

    对于自定义控件的意义不言而喻,所以对它的深入研究是很有必要的,前些年写过几篇关于UI效果的学习过程,但是中途比较懒一直就停滞了,而对于实际工作还是面试来说系统深入的了解自定义控件那是很有必要的,所以接 ...

随机推荐

  1. 【原创】C++中对象的序列化

    1.对象序列化 对象的序列化是指将对象的状态信息转换为可以存储或者传输的形式的过程.对象的反序列化是与序列化相反的过程. 在序列化期间,对象将其当前的状态写入到临时或者永久性的存储区,可以通过从存储区 ...

  2. 【面试】Spring问答Top 25

    本文由 ImportNew - 一直在路上 翻译自 howtodoinjava.欢迎加入翻译小组.转载请见文末要求. 本人收集了一些在大家在面试时被经常问及的关于Spring的主要问题,这些问题有可能 ...

  3. ecshop的广告链接地址打开有问题修改affiche.php为普通链接

    相信很多用过ECSHOP的站长都知道,ECSHOP的广告链接地址形式为“affiche.php?ad_id=1&uri=http%3A%2F%2Fwww.ecmoban.com” 它中间用 a ...

  4. 文成小盆友python-num2 数据类型、列表、字典

    一.先聊下python的运行过程 计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程.这个过程分成两类,第一种是 ...

  5. 添加多盟SDK 库函数

  6. IOS 推送原理

    最近两天在研究ios的消息推送机制.研究这个东西,还是充满兴趣的. Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章 ...

  7. log4c 编译安装简单小结(ubuntu12)

    1 下载源码,解压 (假定解压到了当前用户的根目录下,位置是~/log4c-1.2.3) 2 编译安装log4c(指定--prefix极其重要,如果没有指定到/usr下会有一堆麻烦事,还有,不能按照他 ...

  8. 让libvirt支持win7运行2核以上

    现在人在部署OpenStack之后会发现按照配额运行Linux的虚拟机没有问题,但是运行windows的虚拟机会发现如果配置2个以上的核则无法识别,windows server也最多支持到4个核.无法 ...

  9. Effective Java实作equals() - 就是爱Java

    equals()这个方法,定义在Object class中,这个是所有class的base class,因此所有的class都继承这个方法,默认是比较内存地址,不过Mix需要的是商业规则上的比较,所以 ...

  10. GetSystemTime API可以得到毫秒级时间

    用Now返回的日期格式中年只有2位,即2000年显示为00, 这似乎不太令人满意. 此外Now和Time都只能获得精确到秒的时间,为了得到更精确的毫秒级时间,可以使用API函数GetSystemTim ...