关于Direct2D

2024-06-11 22:58
文章标签 direct2d

本文主要是介绍关于Direct2D,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

㈠ 关于Direct2D

    Direct2D是一个硬件加速的,提供立即模式的二维图形API。它提供了二维的几何体,位图,文本的高性能,高质量的渲染恶魔。十分方便的是,Direct2D与GDI,GDI+和D3D都是可以交互的。一项技术总是有其受众面,看看微软本身怎么说的灯泡

  • 大型企业级本机应用程序开发人员。
  • 创建供下游开发人员使用的控件工具包和库的开发人员。
  • 需要对二维图形进行服务器端呈现的开发人员。
  • 使用 Direct3D 图形,并且需要在菜单、用户界面 (UI) 元素和抬头显示器 (HUD) 中使用高性能的简单二维和文本呈现的开发人员。

㈡ Direct2D的架构

    Direct2D是基于使用Direct3D 10.1的API太阳,所以Direct2D的应用可以再渲染的时候受益于显卡的硬件加速。以下是其架构图,来源于Direct2D的document:

N$H}1[T4P1V2X{@7}27GJ}T

    在Direct2D的右下方,有一个软件光栅化(software rasterizer),假如显卡不支持硬件加速,那么Direct2D可以使用软件方式渲染,即便是这样,其效果还是要优于GDI的吐舌笑脸。在Direct 3D下面还有一层叫DXGI(DirectX Graphics Infrastructure (DXGI) ),对于DXGI,现在我还不是很了解,这里就不敢乱说了尴尬。抱歉抱歉。。

㈢ 视觉效果

    使用Direct2D渲染出来的效果要比GDI要好的多。因为Direct2D使用基于图元的反锯齿效果(这样会使线条更加的平滑),而且在渲染二维图元的时候,完全支持透明和alpha混合。以下是对比的照片:

_8TNDIII[(Y9ALE6)Q6PCPH

    两者的对比很明显吧!显然,右边的Direct2D的线条效果要好于左边的GDI。

㈢ 交互性

    介绍交互性,先看看下面这张图太阳

LYG0P)@L%9ZZZ)4`0`@X2}B

    此张图介绍了Direct2D与Direct3D,GDI+,GDI,DirectWrite,Windows Imaging Component (WIC)的交互性。在这张图中列出了与各个不同的平台交互的函数。虽然对其中的某些平台不了解,但看起来好像很厉害的样子尴尬

㈣ Direct2D的Hello World

⑴ Direct2D的头文件

    Direct2D API定义于以下头文件中:

头文件

描述

d2d1.h 定义了主要的Direct2D API
d2d1helper.h 定义了C++帮助函数,类和结构
d2dbasetypes.h 定义了Direct2D的主要绘图,例如:点,矩形等。其头文件也包含在d2d1.h之中。
d2derr.h 定义了异常代码在Direct2D中。其头文件也包含在d2d1.h之中。

    除了包含这些头文件,还有包含灯泡d2d1.lib这个库。你可以在Windows Software Development Kit (SDK) for Windows 7中可以找到以上这些东西。

⑵ 基本术语解释

① Direct2D Resources(资源)

    所谓的资源,指的是视频内存或系统内存的某种分配。举例来说,位图和画笔就是资源。Direct2D提供了更直接的映射来充分利用 GPU。它提供了两类资源:与设备无关的资源和与设备有关的资源。(以下两部分内容来自msdn上的解释书呆子

   ⅰ 与设备无关的资源(如 ID2D1Geometry)保留在 CPU 上。

  • ID2D1DrawingStateBlock
  • ID2D1Factory
  • ID2D1Geometry 以及从其继承的接口。
  • ID2D1GeometrySink 和 ID2D1SimplifiedGeometrySink
  • ID2D1StrokeStyle

   ⅱ 与设备有关的资源(如 ID2D1RenderTarget 和 ID2D1LinearGradientBrush)直接映射到 GPU 上的资源(如果硬件加速可用)。通过将来自几何对象的顶点和覆盖信息与由与设备有关的资源生成的纹理信息进行组合,来执行呈现调用。

  • ID2D1Brush 以及从其继承的接口。使用呈现器目标可创建画笔。
  • ID2D1Layer 使用呈现器目标可创建层。
  • ID2D1RenderTarget 以及从其继承的接口。若要创建呈现器目标,请使用工厂或其他呈现器目标。

② RenderTarget(渲染目标)

    渲染目标是从ID2D1RenderTarget 接口继承的资源。其用于创建绘制的资源,并执行实际的绘制操作。你可以通过以下方式使用多种类型的渲染目标来呈现图形:。(以下部分内容来自msdn上的解释书呆子

  • ID2D1HwndRenderTarget 对象将内容呈现到窗口。
  • ID2D1DCRenderTarget 对象呈现到 GDI 设备上下文。
  • 位图呈现器目标对象将内容呈现到屏幕外位图。
  • DXGI 呈现器目标对象呈现到用于 Direct3D 的 DXGI 图面。

③ Brush(画笔)

    画笔用其输出来“绘制”区域,不同的画笔具有不同的输出类型。Direct2D 提供了四种画笔:。(以下部分内容来自msdn上的解释书呆子

  • ID2D1SolidColorBrush 用纯色绘制区域
  • ID2D1LinearGradientBrush 用线性渐变绘制区域
  • ID2D1RadialGradientBrush 用径向渐变绘制区域
  • ID2D1BitmapBrush 用位图绘制区域

544A~@9H8U2GYCCW~2TUL)C

④ ID2D1Geometry(几何对象)

    Direct2D 几何对象是由 ID2D1Factory 创建的与设备无关的不可变资源。其对象可以是简单几何对象(ID2D1RectangleGeometry、ID2D1RoundedRectangleGeometry 或 ID2D1EllipseGeometry)、路径几何对象 (ID2D1PathGeometry) 或复合几何对象(ID2D1GeometryGroup 和ID2D1TransformedGeometry)。

⑤ Bitmap(位图)

    Direct2D 不提供用于加载或存储位图的方法;而是使您可以使用 Windows 图像处理组件 (WIC) 创建位图。位图资源可以使用 WIC 进行加载,然后通过 ID2D1RenderTarget::CreateBitmapFromWicBitmap 方法用于创建 ID2D1Bitmap。

⑶ Hello World来了大笑,创建一个矩形!

① 包含 Direct2D 头文件

// windows的头文件
#include <windows.h>
 
// Direct2D的头文件
#include <d2d1.h>

② 创建一个ID2D1Factory

    ID2D1Factory是使用 Direct2D 的起点,使用 ID2D1Factory 可创建 Direct2D 资源。

ID2D1Factory* pd2dfactory = null;
HRESULT hr = D2D1CreateFactory(
                D2D1_FACTORY_TYPE_SINGLE_THREADED,
                &pd2dfactory
                );

③ 创建 ID2D1HwndRenderTarget

    创建工厂之后,我们要创建渲染目标。具体见下面的代码:

HRESULT hr = S_OK;
 
if (!m_pRenderTarget)
{
    RECT rc;
    GetClientRect(m_hwnd, &rc);
 
    D2D1_SIZE_U size = D2D1::SizeU(
        rc.right - rc.left,
        rc.bottom - rc.top
        );
 
    // 创建一个Direct2D渲染目标,m_pRenderTarget这是我们要创建的。
    hr = m_pDirect2dFactory->CreateHwndRenderTarget(
        D2D1::RenderTargetProperties(),
        D2D1::HwndRenderTargetProperties(m_hwnd, size),
        &m_pRenderTarget
        );
 
    if (SUCCEEDED(hr))
    {
        // 创建一个灰色的画笔,调用的是CreateSolidColorBrush函数,LightSlateGray这是笔的颜色
        hr = m_pRenderTarget->CreateSolidColorBrush(
            D2D1::ColorF(D2D1::ColorF::LightSlateGray),
            &m_pLightSlateGrayBrush    
            );
    }
    if (SUCCEEDED(hr))
    {
        // 创建一个蓝色的画笔
            hr = m_pRenderTarget->CreateSolidColorBrush(
            D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
            &m_pCornflowerBlueBrush
            );
    }
}

④ 绘制矩形

HRESULT hr = S_OK;
 
hr = CreateDeviceResources();    // 创建好了m_pRenderTarget
 
if (SUCCEEDED(hr))
{
    m_pRenderTarget->BeginDraw();    // 绘制就在BeginDraw()和EndDraw()之间
 
    m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());    
 
    m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::SkyBlue));    // 背景颜色
 
    D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
 
    // 绘制一个网格背景
    int width = static_cast<int>(rtSize.width);
    int height = static_cast<int>(rtSize.height);
 
    for (int x = 0; x < width; x += 10)
    {
        m_pRenderTarget->DrawLine(
            D2D1::Point2F(static_cast<FLOAT>(x), 0.0f),
            D2D1::Point2F(static_cast<FLOAT>(x), rtSize.height),
            m_pLightSlateGrayBrush,
            0.5f
            );
    }
 
    for (int y = 0; y < height; y += 10)
    {
        m_pRenderTarget->DrawLine(
            D2D1::Point2F(0.0f, static_cast<FLOAT>(y)),
            D2D1::Point2F(rtSize.width, static_cast<FLOAT>(y)),
            m_pLightSlateGrayBrush,
            0.5f
            );
    }
 
    //绘制两个矩形
    D2D1_RECT_F rectangle1 = D2D1::RectF(
        rtSize.width/2 - 50.0f,
        rtSize.height/2 - 50.0f,
        rtSize.width/2 + 50.0f,
        rtSize.height/2 + 50.0f
        );
 
    D2D1_RECT_F rectangle2 = D2D1::RectF(
        rtSize.width/2 - 100.0f,
        rtSize.height/2 - 100.0f,
        rtSize.width/2 + 100.0f,
        rtSize.height/2 + 100.0f
        );
 
 
    // 绘制一个实心的矩形
    m_pRenderTarget->FillRectangle(&rectangle1, m_pLightSlateGrayBrush);
 
    // 绘制一个空心的矩形
    m_pRenderTarget->DrawRectangle(&rectangle2, m_pCornflowerBlueBrush);
 
    // 结束绘制
    hr = m_pRenderTarget->EndDraw();
}
 
if (hr == D2DERR_RECREATE_TARGET)
{
    hr = S_OK;
    DiscardDeviceResources();    // 释放资源
}

⑤ 释放资源

template<class Interface>
inline void SafeRelease(
    Interface **ppInterfaceToRelease
    )
{
    if (*ppInterfaceToRelease != NULL)
    {
        (*ppInterfaceToRelease)->Release();
 
        (*ppInterfaceToRelease) = NULL;
    }
}
 
// 上面是释放函数,下面是释放的对象!
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);

    这是执行的结果灯泡

OR9XOPMWGYJN7ID0TQ7OIRC

    弄了两天才写好,上面的有些东西也不是特别了解,请见谅!但是应该会随着时间的推移,了解更深的。如果大牛们看到其中的不足,请大牛们指正,本人不甚感激大笑

 

参考文献

1. msdn文档:http://msdn.microsoft.com/zh-cn/library/dd370990(v=vs.85).aspx

2.还是msdn文档。。。。因为本文是基于文档写成的。

这篇关于关于Direct2D的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1052491

相关文章

C++系列——Direct2D进行图片处理

C++系列——Direct2D图片处理 01 前言 图片处理工具多如牛毛了,自不必说。主要是应对需要批量处理的场景,所以不如手搓。已经试过直接用C#封装好的库System.Drawing,挺好的,就是过了一段时间感觉这速度有点受不了。于是转用C++,结合GDI+又手搓了一个。因为部分代码与C#版本类似(C#底层用的还是GDI),很快也搞好了。 嗯~~ 这下舒服了。随着效率的提高,我以为可以快乐

使用 devc++ 开发 easyx 实现 Direct2D 交互

代码为 codebus 另一先生的 文案 EasyX 的三种绘图抗锯齿方法 - CodeBus 这里移植到 devc++  移植操作如下:  调用dev++ 的链接库方式: project -> project option -> 如图所示 稍作修改的代码。  #include <graphics.h>#include <d2d1.h>#include <wincodec.h>#

7.Direct2D 捕鱼游戏开发-窗口对象DemoApp.h的说明

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 相关概念说明: 渲染循环(绘制各个精灵):周期的对游戏进行渲染 物理引擎循环(碰撞判断,向量计算的处理):周期的更新物理世界里面的刚体等对象的位置   假设我们使用的并不是一套框架(物理引擎采用的另一个人写的类库,渲染引擎又是一个人写的) 一

13.Direct2D 捕鱼游戏开发-编写场景2结构frame2.h

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 界面截图: 这是我们的frame2.h所控制的场景再看到这里的时候我们可以先看看场景的主要元素有些什么,首先精灵(sprite.h)是少不了的 然后是场景对象(action.h)再然后是我们的事件映射(createBefore.h)然后就是文字

10.Direct2D 捕鱼游戏开发-鱼类fish.h的封装

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 相关知识说明: 鱼的游动:可以是一个连续的帧动画(我们这里采用的就是一个数组来储存每一帧的动画) 鱼的曲线游动:我们让鱼一直像前移动然后在移动的时候修改鱼的面向角度这样鱼就会有一个非常完美的曲线游动了又因为我们的鱼在修改每一帧的显示位置(根据储存帧

3.Direct2D 捕鱼游戏开发-显示对象DisplayObject.h的封装

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 坐标系的概念: 全局坐标系(世界坐标系):这里我们将窗口的左上点作为世界坐标系的原点(0,0)向左表示x轴正方向,向下表示y轴正方向 局部坐标系(相对坐标系):相对于一个显示目标的坐标系由于变换涉及到复杂的向量知识;我们这里只说平移变换的坐标系(即

15.Direct2D 捕鱼游戏开发-金币对象gold.h的封装

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 金币对象: 主要是让鱼在死亡的时候有一个收取金币的动画 我们的动画是二阶一个贝塞尔曲线 二阶贝塞尔曲线: 这里我们需要三个点来确定这个曲线的流程 开始点,结束点,中间点。 开始点和结束点都非常容易确认 (鱼死亡的位置为结束点,金币显示数量的位

8.Direct2D 捕鱼游戏开发-消息映射和流程触发结构 createBefore.h

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 封装思路: 当代码在写好的时候我们又需要再窗口创建之前进行一些操作但是又不能修改demoapp那么这样的一个接口(api)就出来了 createBefore名字空间提供方法: createWindowBefore 窗口创建之前调用 create

12.Direct2D 捕鱼游戏开发-编写场景0结构frame0.h

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 再说代码之前我们先看看我们的界面截图: 我们先冷静分析这个界面的相关元素 首先这里应该有一个场景对象(action.h)来渲染各种精灵对象(sprite.h)然后当面点击开始游戏的时候我们的场景进行了切换所以这里还应该有一个消息映射(creat

16.Direct2D 捕鱼游戏开发-检查对象colVec.h的封装

环境: 编辑器:VS2015 系统:win10 专业版 碰撞:aabb obb盒模型(obb采用分离轴进行判断) 渲染:direct2d 检测对象说明: 我们这个检测对象只是提供一个对碰撞检测的方法和一些算法的方法并不提供实体什么的物理算法具体的物理算法我们是根据不同游戏进行不同的处理(但是碰撞检测是都是一样的) 相关概念: 向量:有方向的数量(向量A(x1,y1),原点B(0,0