前段时间稍微看了点Direct3D, 觉得挺有意思的,但是想着要有3D得先从2D开始。故开始了D2D旅行。

如标题所示,CreateHwndRenderTarget 是在用来创建一个渲染到窗口的渲染目标。

创建渲染目标并且可以使用硬件加速时,可以在计算机的GPU上分配资源。通过一次创建渲染目标并保留尽可能长的时间,您可以获得性能上的好处。您的应用程序应一次创建渲染目标,并在应用程序的生命周期内或在收到D2DERR_RECREATE_TARGET错误之前将其保留。收到此错误时,您需要重新创建渲染目标(及其创建的所有资源)。

它与CreateDCRenderTarget最大的区别,也就是GDI的绘图技巧与D2D的区别了。

我的个人理解是,前者是自己在GPU上创建渲染目标,并停留一段时间用来绘制,不用我们操心上下文的环境了。 而后者的作用是

创建一个绘制目标,以绘制到Windows图形设备接口(GDI)设备上下文。

很显然它是用来充当D2D与GDI的交互的。

这篇文档是介绍这个作用的, Direct2D and GDI Interoperability Overview

在代码上使用肯定也是有区别的。

前者的使用,可以先看D2D入门的代码,下面的代码是用来将图片绘制到窗口上,

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <d2d1.h>
#include <d2d1_1.h> #include <wincodec.h> #pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "Windowscodecs.lib") #define SAFE_RELEASE(P) if(P){P->Release() ; P = NULL ;} extern "C" ID2D1Bitmap * mybitmapcreate(ID2D1DCRenderTarget*);
float left = 5;
float top = 10;
float Bottom = 10;
float Right = 30;
ID2D1Bitmap* pBitmap = NULL;
IWICImagingFactory* pIWICFactory = NULL;
HWND hWnd;
ID2D1HwndRenderTarget* m_pRenderTarget; void initize();
void draw();
D2D1_RECT_F myrect = D2D1::RectF(left, top, Bottom, Right);
ID2D1Bitmap* mybitmap;
ID2D1Factory* l;
REFIID x = __uuidof(ID2D1Factory); HRESULT LoadBitmapFromFile(
ID2D1RenderTarget* pRenderTarget,
IWICImagingFactory* pIWICFactory,
PCWSTR uri,
UINT destinationWidth,
UINT destinationHeight
)
{
HRESULT hr = S_OK; IWICBitmapDecoder* pDecoder = NULL;
IWICBitmapFrameDecode* pSource = NULL;
IWICStream* pStream = NULL;
IWICFormatConverter* pConverter = NULL;
IWICBitmapScaler* pScaler = NULL; hr = pIWICFactory->CreateDecoderFromFilename(
uri,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{ // Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
hr = pIWICFactory->CreateFormatConverter(&pConverter);
}
// If a new width or height was specified, create an
// IWICBitmapScaler and use it to resize the image.
if (destinationWidth != 0 || destinationHeight != 0)
{
UINT originalWidth, originalHeight;
hr = pSource->GetSize(&originalWidth, &originalHeight);
if (SUCCEEDED(hr))
{
if (destinationWidth == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
}
else if (destinationHeight == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
} hr = pIWICFactory->CreateBitmapScaler(&pScaler);
if (SUCCEEDED(hr))
{
hr = pScaler->Initialize(
pSource,
destinationWidth,
destinationHeight,
WICBitmapInterpolationModeCubic
);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pScaler,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
}
}
if (SUCCEEDED(hr))
{
// Create a Direct2D bitmap from the WIC bitmap.
hr = pRenderTarget->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
} SAFE_RELEASE(pDecoder);
SAFE_RELEASE(pSource);
SAFE_RELEASE(pStream);
SAFE_RELEASE(pConverter);
SAFE_RELEASE(pScaler); return TRUE;
} LRESULT CALLBACK WndProcFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rc;
switch (message)
{
case WM_PAINT:
{
draw();
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int main(int argc, char* argv[])
{
WNDCLASS wc{};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProcFunc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = L"Class_Name";
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
RegisterClass(&wc); hWnd = CreateWindow(L"Class_Name", L"Test", WS_OVERLAPPEDWINDOW, 100, 100, 1000, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
initize(); ShowWindow(hWnd, 1);
UpdateWindow(hWnd); MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
} return 0;
} void initize()
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void**>(&pIWICFactory)); HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &l); RECT rc;
GetClientRect(hWnd, &rc); D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
); // Create a Direct2D render target.
hr = l->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hWnd, size),
&m_pRenderTarget
); } void draw()
{ LoadBitmapFromFile(m_pRenderTarget, pIWICFactory, L"timg.bmp", 650, 400); m_pRenderTarget->BeginDraw(); m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White)); D2D1_SIZE_F size = pBitmap->GetSize();
D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f); // Draw bitmap
m_pRenderTarget->DrawBitmap(
pBitmap,
D2D1::RectF(
upperLeftCorner.x,
upperLeftCorner.y,
upperLeftCorner.x + size.width,
upperLeftCorner.y + size.height)
);
m_pRenderTarget->EndDraw(); }

后者则是需要使用ID2D1DCRenderTarget::BindDC将渲染目标绑定到向其发出绘图命令的设备上下文。

需要更改的代码部分,

//创建DC的渲染目标
ID2D1DCRenderTarget* pow;
... void initize()
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void**>(&pIWICFactory)); HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &l); D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
l->CreateDCRenderTarget(&props, &pow); }
void draw()
{ LoadBitmapFromFile(m_pRenderTarget, pIWICFactory, L"timg.bmp", 650, 400); pow->BeginDraw(); pow->Clear(D2D1::ColorF(D2D1::ColorF::White)); D2D1_SIZE_F size = pBitmap->GetSize();
D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f); // Draw bitmap
pow->DrawBitmap(
pBitmap,
D2D1::RectF(
upperLeftCorner.x,
upperLeftCorner.y,
upperLeftCorner.x + size.width,
upperLeftCorner.y + size.height)
);
pow->EndDraw(); } case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
pow->BindDC(ps.hdc, &rc);
draw();
EndPaint(hwnd, &ps);
}
break;
...

Direct2D CreateHwndRenderTarget 和 CreateDCRenderTarget的更多相关文章

  1. Direct2D 几何图形绘制基础

    之前说过,D2D主要为了绘制有三种类型的数据:几何图形,图片,文字.这几种对象也叫做资源,资源就是要D2D流水线中要被加工的对象. 几何图形包括: 简单几何图形 直线,DrawLine,由起点和终点构 ...

  2. Direct2D教程I——简介及首个例子

    在博客园里,系统的Direct2D的教程比较少,只有“万一”写了一个关于Direct2D的系列(Delphi 2009).于是,仿照其系列,写一个在VS下的Direct2D系列教程. 博客园中的高手还 ...

  3. SharpDX之Direct2D教程I——简单示例和Color(颜色)

    研究Direct2D已经有一段时间了,也写了一个系列的文章 Direct2D ,是基于Windows API Code Pack 1.1.在前文 Direct2D教程VIII——几何(Geometry ...

  4. Direct2D教程V——位图(Bitmap)和位图笔刷(BitmapBrush)

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  5. Direct2D教程(二)来看D2D世界中的Hello,World

    引子 任何一门语言的第一个教程几乎都是Hello,world.我们也不例外,但是这里不是教大家打印Hello,world,而是编写一个简单的D2D绘制程序,让大家对Direct2D的程序结构及编程方法 ...

  6. Direct2D开发:Direct2D 和 GDI 互操作性概述

    本主题说明如何结合使用 Direct2D 和 GDI(可能为英文网页).有两种方法可以结合使用 Direct2D 和 GDI:您可以将 GDI 内容写入与 Direct2D GDI 兼容的呈现器目标, ...

  7. 关于 Direct2D

    http://msdn.microsoft.com/zh-cn/library/windows/desktop/dd370987(v=vs.85).aspx 本主题介绍 Direct2D,这是 Win ...

  8. UWP中的Direct2D

    介绍 DirectX一直是Windows平台中高性能图形的代名词,自Win7开始,微软又推出了Direct2D技术,包装于Direct3D,但专注于2D图形,并且准备取代GDI这样的传统2D图形技术. ...

  9. Direct2D教程(外篇)环境配置

    2014年世界杯首场淘汰赛马上开始了,闲着没事,整理以前的博客草稿打发时间,意外的发现这篇文章,本来是打算加入到Direct2D那个系列的,不知道为什么把它给遗漏了.环境配置,对于熟手来说,不是什么重 ...

  10. Direct2D开发:纹理混合

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 我们都知道Direct2D可以加载并显示图片,但是不知道你有没有想过,这个2D的图形引擎可以进行纹理混合吗?如果 ...

随机推荐

  1. [转帖]OpenSSL版本历史

    OpenSSL版本历史 新闻日志 这是所有 OpenSSL 公告的简洁日志.它们几乎是发布通知. 日期物品 2021 年 7 月 29 日OpenSSL 3.0 的 Beta 2 现已推出.这是一个候 ...

  2. [转帖]Module ngx_http_v2_module

    https://nginx.org/en/docs/http/ngx_http_v2_module.html#:~:text=Sets%20the%20maximum%20number%20of%20 ...

  3. [转帖]Steam内存测试工具【转】

      转自:https://www.cnblogs.com/iouwenbo/p/14377478.html Stream测试是内存测试中业界公认的内存带宽性能测试基准工具. Stream安装 官方源码 ...

  4. [转帖]019 Linux tcpdump 抓包案例入门可真简单啊?

    https://my.oschina.net/u/3113381/blog/5477908   1 tcpdump 是什么? tcpdump 可以将网络中传送的数据包完全截获下来提供分析.它支持针对网 ...

  5. AppCan 打包无限次下载解决方案

    1.下载AppCan 官网上打包好的文件apk文件 2.将apk文件放在指定的服务器文件内,谇文件发布到IIS,一般都会用已发布发的网站上面随便一个目录就可以了. 3.MIME类型中填写apk的MIM ...

  6. 开发QQ官方机器人

    QQ 频道机器人开发简明教程 1. 简介 QQ 频道机器人是一种可以在 QQ 频道中与用户进行互动的服务.这个教程旨在帮助新手学习如何使用 Python 的官方SDK,快速实现一些基本的机器人功能. ...

  7. P7036 [NWRRC2016] Folding

    题目简述 有两个矩形,大小分别是 \(W \times Y\) 和 $ w \times y$.现在我们要通过折叠将两个矩阵变成一样. 思路 part1 已知一条边折叠一次会变成 \(\frac{x} ...

  8. Milvus 2.3.功能全面升级,核心组件再升级,超低延迟、高准确度、MMap一触开启数据处理量翻倍、支持GPU使用!

    Milvus 2.3.功能全面升级,核心组件再升级,超低延迟.高准确度.MMap一触开启数据处理量翻倍.支持GPU使用! 1.Milvus 2.3版本全部升级简介 Milvus 2.3.0 不仅包含大 ...

  9. LeetCode刷题日记 2020/8/23

    题目描述 给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点). 示例 1: 输入: [5,7] ...

  10. Java多线程-JUC-1(八)

    前面把线程相关的生命周期.关键字.线程池(ThreadPool).ThreadLocal.CAS.锁和AQS都讲完了,现在就剩下怎么来用多线程了.而要想用好多线程,其实是可以取一些巧的,比如JUC(好 ...