【问题标题】:c++ direct3d 2d renderingc++ direct3d 2d 渲染
【发布时间】:2021-04-12 09:09:49
【问题描述】:

我想知道您对以下问题的建议:

我所需要的只是在一个 win32 窗口中显示一个表面。说 256 * 256 xRGB,我需要访问内存以将像素放入其中。 我对 Direct3d9 是完全正确的,但 API 是旧的。 我知道在 Dirct3D 10 和 11 中有不同的方法可以做到这一点,但它是否涉及玩 3d 的东西?我认为在 Direct3D10 或 11 中无法做到这一点。 我在 direct3D9 中使用了 surface->Lock(),但在较新的版本中不可用。

所以,如果我必须使用我无法直接调用的库(如 SDL)来锁定表面并在 win32 窗口中显示。是否有一些 api 可以在 d3d 中进行 2d 渲染,还是我必须进入 direct3d 10 或 11 并以困难的方式在 3d 中进行?

我用谷歌搜索了一下,我有点迷路了。 欢迎提出任何建议。

【问题讨论】:

  • 你在使用 cuda 来修改你的像素吗?

标签: c++ direct3d


【解决方案1】:

我所需要的只是在一个 win32 窗口中显示一个表面。比如说 256 * 256 xRGB,我需要访问内存才能将像素放入其中。

如果您只需要这些,我建议您坚持使用 GDI/GDI+。它的性能较低,因为它是完全软件实现的,但它非常易于使用。

我知道在 Dirct3D 10 和 11 中有不同的方法可以做到这一点,但它是否涉及玩 3d 事物?

仅限设置 2D 投影(默认设置)。

我在 direct3D9 中使用了 surface->Lock(),但在较新的版本中不可用。

上传资源数据的现代方式是使用ID3D12Resource::Map

所以,如果我必须使用我无法直接调用的库(如 SDL)来锁定表面并在 win32 窗口中显示

您的意思是,SDL 是基本 3D API(OGL/D3D)之上的一层。它支持他们支持的一切。具体来说,锁定 SDL 纹理是使用 SDL_LockTexture 完成的。

【讨论】:

  • 他们也可以使用Direct2D,这是为此目的而设计的。
  • D2D 是 D3D9 之上的(死)层,并且是一个薄层。在 D3D12 中重新实现所需的部分并不难。
  • Drect2D 不是 D3D9 之上的死层。它可以与 D3D11 一起使用,D3D12 使用 D3D11on12 docs.microsoft.com/en-us/windows/win32/direct3d12/…
  • @Blindy D2D 并没有死,它得到了很好的支持并被用作 XAML UI 的底层技术
【解决方案2】:

使用 DirectX,您可以将图像显示为带有纹理的四边形(矩形),并根据需要修改纹理(作为图像)。

您可以使用任何 DX (9,10,11,12) 来执行此操作,但仅显示 256x256 像素的图像需要大量工作。

这里有实现此目的的示例:https://github.com/microsoft/DirectXTK/wiki/Getting-Started, 特别是精灵和纹理https://github.com/microsoft/DirectXTK/wiki/Sprites-and-textures

您可以在这里获得帮助:https://github.com/microsoft/DirectXTK/wiki/DeviceResources

然而,我发现该示例并不能直接显示经过计算的图像。

如果您正在寻找可能的最低延迟(亚毫秒),或者能够以 10 位显示(您只能使用 DX),拥有支持 cuda 的 GPU,您可以在使用 DX12 的 GPU:https://github.com/mprevot/CudaD3D12Update

这是一个 cuda-DX12 互操作的案例。在这种情况下,您可以最大限度地减少 CPU 和 GPU 之间的来回,因为纹理是在 GPU 中计算和显示的。 CPU 仅用于编排事件。

四边形定义为as such:

    TexVertex quadVertices[] =
    {
        { {-x,-y, 0.0f }, { 0.0f, 0.0f } },
        { {-x, y, 0.0f }, { 0.0f, 1.0f } },
        { {x, -y, 0.0f }, { 1.0f, 0.0f } },
        { {x,  y, 0.0f }, { 1.0f, 1.0f } },
    };

然后是uploaded。纹理是这样定义的:

    TextureChannels = 4;
    TextureWidth = m_width;
    TextureHeight = m_height;
    const auto textureSurface = TextureWidth * TextureHeight;
    const auto texturePixels = textureSurface * TextureChannels;
    const auto textureSizeBytes = sizeof(float)* texturePixels;

    const auto texFormat = TextureChannels == 4 ? DXGI_FORMAT_R32G32B32A32_FLOAT : DXGI_FORMAT_R32G32B32_FLOAT;
    const auto texDesc = CD3DX12_RESOURCE_DESC::Tex2D(texFormat, TextureWidth, TextureHeight, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS);
    ThrowIfFailed(m_device->CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT), D3D12_HEAP_FLAG_SHARED,
        &texDesc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, nullptr, IID_PPV_ARGS(&TextureArray)));
    NAME_D3D12_OBJECT(TextureArray);

那么DX12贴图是imported into cuda as a surface,然后你run a kernel(或者DX语言的shader)来修改。好处是您不必以预定义的频率更新它,表面可以随意更新和显示,只有这样。

如果您没有 cuda GPU,您可以从 CPU 更改纹理(参见 DX 示例)。

但是,即使您没有要求这样做,我相信使用诸如 WPF 框架之类的东西来显示(和计算)此类图像会更容易,延迟会更大但非常可接受,并且您只能显示 8 位图像。在后面的 WPF 依赖于 DX,但据我所知,无法修改其配置。这是获得结果并尽快处理的方法。

【讨论】:

    猜你喜欢
    • 2017-08-29
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多