标签: direct2d

如何从TDirect2DCanvas(Direct2D Rendertarget)复制数据?

我正在尝试使用C++ Builder的TDirect2DCanvas的Direct2D RenderTarget属性来使用GPU对位图操作进行基准测试.与GDI相比,这是最令人印象深刻的.但是,我无法弄清楚如何将结果返回到CPU内存中,因此我可以将其用于进一步的CPU处理.读过关于使用WIC的内容,但显然你放弃了大部分的硬件加速.Windows 8似乎提供了一个带有地图功能的新位图,但我想使用(标准)Windows 7.此外,C++ Builder不提供这些新功能的头文件.

给定一个TDirect2DCanvas,或者您希望使用Direct2D RenderTarget或ID2D1Bitmap,如何将位图复制回CPU内存?

c++ windows delphi direct2d

8
推荐指数
1
解决办法
658
查看次数

如何清除Direct2D渲染目标以使其完全透明

我试图在一个看不见的HWND上绘制半透明的矩形.但是,使用ID2D1HwndRenderTarget :: Clear清除窗口只会使整个窗口变黑,所以当我在顶部绘制矩形时,它们看起来是半黑色的.

如果我没有Clear()并且没有绘制,那么窗口是不可见的,因为它应该是.Clear()是罪魁祸首; 但是,如果我不使用它,那么绘画就会非常糟糕.

这是我在WindowProc中使用的代码:

case WM_PAINT:
    // Begin drawing
    pRenderTarget->BeginDraw();
    pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());

    // Clear the window
    pRenderTarget->Clear();

    // Paint the panel and its children
    D2DSurface()->StartPainting();
    {
        D2DSurface()->PaintTraverse(panel);
    }
    D2DSurface()->FinishPainting();

    // Finish drawing
    HRESULT hr = plat->pRenderTarget->EndDraw();
Run Code Online (Sandbox Code Playgroud)

提前致谢!

c c++ transparency hwnd direct2d

7
推荐指数
3
解决办法
8518
查看次数

Win32:是否有使用硬件加速的替代GDI32.dll?

有没有人创建了一个GDI32.dll利用机器上可用硬件加速的版本?gdiplus.dll

从Windows Vista开始,GDI不再是硬件加速.(GDI +从未加速硬件).如果没有Microsoft修复GDI(和GDI +)以便能够在计算机上运行良好:本机应用程序(C++ MFC,Delphi等)和托管的WinForms应用程序将继续运行得很糟糕.

虽然我可以将Direct2D用于业务应用程序,但我无法控制开发环境仍然创建控件的事实,数十年的库支持代码假定存在GDI.


应用程序兼容性:图形设备接口(GDI):

现在,诸如LineTo和Rectangle之类的GDI原语在软件而不是视频硬件中呈现,这极大地简化了显示驱动程序.

Windows和视频内存

在XP中,GDI是GPU加速到不同程度,具体取决于操作系统的配置方式或设备驱动程序(有关详细信息,请参阅挂钩与撑开).在Vista中,GDI不是GPU加速的

比较Direct2D和GDI

因此,在Windows Vista中,GDI DDI显示驱动程序已更改为仅由Microsoft提供的驱动程序Canonical Display Driver(CDD)实现.GDI呈现给系统内存位图.脏区域用于更新窗口管理器用于合成桌面的视频内存纹理.

user-interface winapi gdi+ gdi direct2d

7
推荐指数
1
解决办法
3950
查看次数

直接写:获得字体的高度

我的目标: 我想获得IDWriteTextFormat字体的高度,这样我就可以计算出在一定高度的IDWriteTextLayout中可以容纳多少行文本.

我的问题: 现在我正在使用此代码来计算可见的行数:

inline int kmTextCtrl::GetVisLines() const
{

    /* pTextFormat is an IDWriteTextFormat pointer, dpi_y is the desktop's vertical dpi,
       and GetHeight() returns the height (in pixels) of the render target. */
    float size = (pTextFormat->GetFontSize()/72.0f)*dpi_y;
    return (int)(GetHeight()/size);
}
Run Code Online (Sandbox Code Playgroud)

对于某些字体,计算似乎是准确的,但对于任何TrueType字体都不准确(例如:Courier New,Arial,Times New Roman).对于这些字体,显示的文本剪裁得远远低于渲染目标的下垂直边界.

一些上下文: 我正在制作一个文本回滚缓冲区控件,它使用IDWriteTextLayout将文本放到控件的渲染目标中.我使用GetVisLines()的结果来确定循环缓冲区(由行存储std :: strings中的文本)中的文本行数以拉入布局,并在每次滚动或调整窗口大小时重新创建它.

这是使用"本机"Win32 API C++完成的.

c++ winapi native direct2d directwrite

7
推荐指数
2
解决办法
5679
查看次数

Direct2D/C++ - 使用位图进行屏幕外渲染

我已经使用C++为Windows桌面应用程序实现了Direct2D应用程序,在模拟过程中我显示了图形结果(包括点,线和椭圆).只要模拟仍在运行,我就会保留一个缓冲区来存储模拟值,每个时间间隔我只是绘制值.现在,情况是,我直接画上Hwnd(ID2D1HwndRenderTarget)就像

pRenderTarget->BeginDraw() 

for(values of simulation results)
pRenderTarget->DrawLine(....)

pRenderTarget->EndDraw()
Run Code Online (Sandbox Code Playgroud)

现在我想使用Bitmap进行屏幕外渲染/绘图,因为我需要将位图作为图像存储在计算机上(相当于拍摄/捕获截图以存储模拟结果).在这种情况下我应该如何处理(有/没有Direct2D IWICBitmapFactory- 用于以后的屏幕捕获)?

  1. 创造ID2D1HwndRenderTarget pHwndRenderTarget- 使用pD2DFactory->CreateHwndRenderTarget()

  2. 创造ID2D1BitmapFactory pBitmapFactory- 使用pHwndRenderTarget->CreateCompatibleRenderTarget()

  3. 创建一个空位图ID2D1Bitmap ID2D1Bitmap pBmp- 使用pBitmapFactory->CreateBitmap()

  4. ?? 在这个位图上我应该画线吗?如果没有,我应该在哪里画线

  5. 最后,在哪个BeginDraw()和之间EndDraw(),我应该放置位图?

  6. 后来在某些时候,我会捕获这个位图的截图.没有IWICBitmapFactory我可以做到这一点?任何代码示例将不胜感激.

c++ windows off-screen direct2d

7
推荐指数
0
解决办法
958
查看次数

高效的Direct2D多线程

我正在为Windows Store编写电子书阅读器应用程序.我正在使用Direct2D + DXGI交换链在屏幕上呈现书页.

我的书内容有时非常复杂(几何,位图,蒙版等),因此渲染它可能需要100毫秒.所以我试图在单独的线程中对位图进行离屏渲染,然后在主线程中显示这个位图.

但是,我无法想象如何有效地做到这一点.

到目前为止,我尝试了两种方法:

  1. 使用ID2D1Factory带有D2D1_FACTORY_TYPE_MULTI_THREADED标志的单个标志,ID2D1BitmapRenderTarget在后台线程中创建并使用它以进行屏幕外渲染.(这另外需要ID2D1Multithread::Enter/LeaveIDXGISwapChain::Present操作).问题是,ID2D1RenderTarget::EndDraw后台线程中的操作有时需要长达100毫秒,并且由于内部Direct2D锁定,主线程渲染在此期间被阻止.

  2. ID2D1Factory在后台线程中使用单独的(如http://www.sdknews.com/ios/using-direct2d-for-server-side-rendering中所述)并关闭内部Direct2D同步.在这种情况下,两个线程之间没有交叉锁定.不幸的是,在这种情况下,我不能ID2D1Factory直接在main中使用结果位图,因为它属于不同的工厂.我必须将位图数据移动到CPU内存,然后将其复制到主内存的GPU内存中ID2D1Factory.这个操作也引入了显着的滞后(我认为这是由于大量的内存访问,但我不确定).

有没有办法有效地做到这一点?

PS此处的所有时间均为Acer Switch 10平板电脑.在常规的Core i7 PC上,两种方法都可以在没有任何明显滞后的情

multithreading direct2d

7
推荐指数
1
解决办法
1205
查看次数

什么是“轻量级 COM”?

在研究 Direct2D 支持哪些 COM 单元线程模型时,我发现尽管外观和事实可以使用来自 .NET 的 API 使用 COM 互操作性,但Direct2D(与其他 DirectX API 一样)实际上根本不是 COM API(1)无论是维基百科上的Direct2D文章(2) ,以及一个由托马斯·奥尔森MSDN博客文章(3)指的是使用一个“轻量级COM”的方式这些API。

但是,我还没有找到关于这个“轻量级 COM”究竟是什么的任何官方定义。有没有这样的定义(可能是微软)?

脚注:

  1. Mike Danes 对 MSDN 论坛问题“CoInitialize/CoUninitialize,Direct2D 和 DirectWrite 真的需要它们吗?”的回答 . 这是有趣的一点:

    “DirectWrite/Direct2D/Direct3D 是 COM 之类的 API,但它们不使用 COM。它们不像普通的 COM 组件那样在注册表中注册,它们不遵循 COM 线程模型,它们不支持任何类型的编组等。它们”不是 COM。”

  2. 维基百科关于 Direct2D 的文章(概述部分)

    “Direct2D 是一种基于 C++ 的本机代码 API,可由托管代码调用,并使用类似于 Direct3D 的“轻量级 COM”方法,具有最少的抽象。”

  3. Thomas Olsen 的 MSDN 博客文章提到以下作为 Direct2D 的设计目标:

    “轻量级 COM——应该使用 C++ 风格的接口来模拟 Direct3D 的使用。不支持代理、跨进程远程处理、BSTR、VARIANT、COM 注册(例如重量级的东西)。”

.net com direct3d com-interop direct2d

7
推荐指数
2
解决办法
607
查看次数

调整绑定到 Direct2D 渲染目标的 DXGI 交换链的大小

我有一个使用 ID2D1Factory::CreateDxgiSurfaceRenderTarget 创建的 Direct2D 渲染目标。当我收到 WM_SIZE 消息时,我尝试通过调用 IDXGISwapChain::ResizeBuffers 来调整相应交换链的大小,但失败并显示 DXGI_ERROR_INVALID_CALL (0x887a0001)。我相信这是因为ResizeBuffers 文档中指出的以下内容:

除非释放对其后台缓冲区的所有未完成引用,否则无法调整交换链的大小。为了使 ResizeBuffers 成功,您必须释放其对后台缓冲区的所有直接和间接引用。

在对资源调用 AddRef 后,应用程序将保留直接引用。

间接引用由对资源的视图持有,将资源的视图绑定到设备上下文、使用该资源的命令列表、使用该资源的视图的命令列表、执行使用过的另一个命令列表的命令列表。资源等等。

我假设由 ID2D1RenderTarget::CreateDxgiSurfaceRenderTarget 创建的 Direct2D 渲染目标就是这样一种间接引用。但我无法想象每次调整窗口大小时都应该重新创建渲染目标,那么我该怎么办?

c++ direct3d direct2d dxgi

6
推荐指数
1
解决办法
2015
查看次数

每个监视器DPI-Aware:使用NVIDIA Optimus的黑色窗口故障

我想制作一个Per-Monitor DPI-Aware Direct2D应用程序.我已按照Kenny Kerr的MSDN文章中的解释,扩展了Microsoft的"First Direct2D Program"示例.当两台显示器都使用一块显卡时,这种方法很有效,但在使用我的笔记本电脑的NVIDIA Optimus设置时会出现故障.WM_DPICHANGED

我可以通过以下步骤运行Per-Monitor Aware WPF示例来重现相同的故障:

  • 每台显示器上的DPI比例因子不同.
  • 支持Optimus(集成显卡上的笔记本电脑显示,Quadro显卡上的外接显示器)
  • 应用程序在主显示屏上启动 - 右侧的外部显示器.
  • 将其拖到左侧,它可以正确处理DPI更改.
  • 将其拖回右侧.当它处理DPI更改时,右侧监视器上的窗口部分变为黑色.左侧部分仍然正确绘制.

(见这个bug的视频)

我只是在上面的示例应用程序中看到了这个错误,当我尝试将Kerr的WM_DPICHANGED处理程序添加到一个更简单的示例时.可疑的是,我已经看到其他应用程序(Chrome,Visual Studio本身)显示类似的黑色窗口,但只是暂时的,如果我在显示器之间拖动并且非常快速地最大化它们.

那么 - 是否有人熟悉这个故障?是我的显示驱动程序中的一些错误?或者是否有其他应用程序要做的事情来纠正它,示例代码没有?

c++ winapi multiple-monitors direct2d optimus

6
推荐指数
1
解决办法
397
查看次数

Skia 或 Direct2D 如何使用 GPU 渲染线条或多边形?

这是一道了解2d矢量图形GPU加速渲染原理的题。

使用 Skia 或 Direct2D,您可以绘制圆角矩形、贝塞尔曲线、多边形等,并且还可以产生模糊等效果。

Skia / Direct2D 提供基于 CPU 和 GPU 的渲染。

对于CPU渲染,我或多或少可以想象如何渲染圆角矩形。我已经见过很多不同的线条渲染算法。

但对于GPU,我没有太多线索。

  • 圆角矩形是由三角形组成的吗?
  • 圆角矩形是否完全由野生像素着色器绘制?

是否有一些基本示例可以向我展示此类事物如何工作的基本原理?

(也许,解决方案也可以在 Skia 的源代码中找到,但我担心它会如此复杂/通用,以至于像我这样的菜鸟什么都看不懂。)

graphics rendering gpu direct2d skia

6
推荐指数
1
解决办法
947
查看次数