博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Direct2D 几何图形绘制基础
阅读量:2505 次
发布时间:2019-05-11

本文共 5036 字,大约阅读时间需要 16 分钟。

之前说过,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;
还是比较简单。

转载地址:http://mmlgb.baihongyu.com/

你可能感兴趣的文章
Excel 如何制作时间轴
查看>>
matplotlib绘图跳过时间段的处理方案
查看>>
vnpy学习_04回测评价指标的缺陷
查看>>
读书笔记_量化交易如何建立自己的算法交易01
查看>>
设计模式05_单例
查看>>
设计模式06_原型
查看>>
设计模式07_建造者
查看>>
设计模式09_代理模式
查看>>
设计模式10_桥接
查看>>
满屏的指标?删了吧,手把手教你裸 K 交易!
查看>>
不吹不黑 | 聊聊为什么要用99%精度的数据回测
查看>>
量化策略回测唐安奇通道
查看>>
量化策略回测DualThrust
查看>>
量化策略回测DCCV2
查看>>
mongodb查询优化
查看>>
五步git操作搞定Github中fork的项目与原作者同步
查看>>
git 删除远程分支
查看>>
删远端分支报错remote refs do not exist或git: refusing to delete the current branch解决方法
查看>>
python multiprocessing遇到Can’t pickle instancemethod问题
查看>>
APP真机测试及发布
查看>>