您的位置:首页 > 其它

Direct2D学习教程(一)

2012-12-26 12:41 525 查看
转自http://www.cnblogs.com/ComputerG/archive/2012/03/14/2396550.html
㈠关于Direct2D

Direct2D是一个硬件加速的,提供立即模式的二维图形API。它提供了二维的几何体,位图,文本的高性能,高质量的渲染

。十分方便的是,Direct2D与GDI,GDI+和D3D都是可以交互的。一项技术总是有其受众面,看看微软本身怎么说的



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

㈡Direct2D的架构
Direct2D是基于使用Direct3D10.1的API

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




在Direct2D的右下方,有一个软件光栅化(softwarerasterizer),假如显卡不支持硬件加速,那么Direct2D可以使用软件方式渲染,即便是这样,其效果还是要优于GDI的

。在Direct
3D下面还有一层叫DXGI(DirectXGraphicsInfrastructure(DXGI)),对于DXGI,现在我还不是很了解,这里就不敢乱说了

。抱歉抱歉。。

㈢视觉效果

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





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

㈢交互性

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







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



㈣Direct2D的HelloWorld

⑴Direct2D的头文件

Direct2DAPI定义于以下头文件中:

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

d2d1.lib这个库。你可以在Windows
SoftwareDevelopmentKit(SDK)forWindows7中可以找到以上这些东西。

⑵基本术语解释

①Direct2DResources(资源)

所谓的资源,指的是视频内存或系统内存的某种分配。举例来说,位图和画笔就是资源。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用位图绘制区域





④ID2D1Geometry(几何对象)

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

⑤Bitmap(位图)

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

⑶HelloWorld来了

,创建一个矩形!

①包含Direct2D头文件

//windows的头文件

#include<windows.h>


//Direct2D的头文件

#include<d2d1.h>


②创建一个ID2D1Factory

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

ID2D1Factory*pd2dfactory=null;

HRESULThr=D2D1CreateFactory(

D2D1_FACTORY_TYPE_SINGLE_THREADED,

&pd2dfactory

);


③创建ID2D1HwndRenderTarget

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

HRESULThr=S_OK;


if(!m_pRenderTarget)

{

RECTrc;

GetClientRect(m_hwnd,&rc);


D2D1_SIZE_Usize=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

);

}

}


④绘制矩形

HRESULThr=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_FrtSize=m_pRenderTarget->GetSize();


//绘制一个网格背景

intwidth=static_cast<int>(rtSize.width);

intheight=static_cast<int>(rtSize.height);


for(intx=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(inty=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_Frectangle1=D2D1::RectF(

rtSize.width/2-50.0f,

rtSize.height/2-50.0f,

rtSize.width/2+50.0f,

rtSize.height/2+50.0f

);


D2D1_RECT_Frectangle2=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<classInterface>

inlinevoidSafeRelease(

Interface**ppInterfaceToRelease

)

{

if(*ppInterfaceToRelease!=NULL)

{

(*ppInterfaceToRelease)->Release();


(*ppInterfaceToRelease)=NULL;

}

}


//上面是释放函数,下面是释放的对象!

SafeRelease(&m_pRenderTarget);

SafeRelease(&m_pLightSlateGrayBrush);

SafeRelease(&m_pCornflowerBlueBrush);


这是执行的结果







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



(转载,没发现后续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: