Direct2D 几何图形绘制基础

您所在的位置:网站首页 几何组合图形怎么画图 Direct2D 几何图形绘制基础

Direct2D 几何图形绘制基础

2024-07-09 22:06| 来源: 网络整理| 查看: 265

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3