我是一位经验丰富的计算机图形程序员,主要使用Direct3D 9.0c,OpenGL和通用算法。目前,我正在评估Direct2D作为处理医学图像数据的专业应用程序的渲染技术。至于渲染,它是一个处于窗口模式的x64桌面应用程序(不是全屏)。
在我最初的步骤中,我一直在努力完成一项任务,我认为这将是一个明智的选择:在屏幕上渲染单通道位图。
在Windows 8.1计算机上运行时,我创建了一个{3},其中Direct3D交换链缓冲区表面作为渲染目标。交换链是从HWND和缓冲区格式ID2D1DeviceContext
创建的。注意:另请参阅最后的代码段。
之后,我创建了一个像素格式DXGI_FORMAT_B8G8R8A8_UNORM
和alpha模式DXGI_FORMAT_R8_UNORM
的位图。在设备上下文中调用D2d1_ALPHA_MODE_IGNORE
时,将使用调试消息触发调试断点" D2d DEBUG ERROR - 此操作与位图的像素格式不兼容"。
我知道这个输出很清楚。此外,当使用DrawBitmap(...)
将像素格式更改为DXGI_FORMAT_R8G8B8A8_UNORM
时,一切运行正常,我会看到渲染的位图。但是,我根本无法相信!从那时起,显卡就支持单通道纹理 - 每个3D图形应用程序都可以使用它们而无需考虑两次。这不用说了。
我试图在Google和Google上找到任何内容,但没有成功。我能找到的唯一提示是带有(supported pixel formats)的MSDN Direct2D页面。文档建议 - 不提及它 - DXGI_ALPHA_MODE_IGNORE
确实不支持位图格式。我也找到了关于alpha蒙版的帖子(使用DXGI_FORMAT_R8_UNORM
),但这不是我之后的事。
我错过了什么,我无法说服Direct2D创建和绘制灰度位图?或者,Direct2D是否支持绘制R8或R16位图是真的吗?
任何帮助都非常感谢,因为我不知道如何解决这个问题。如果我不能让这些琐碎的基础工作,我想我不得不停止深入研究Direct2D: - (。
以下是相关的代码段。请注意,自从我将C ++ / CLI代码移植到普通C ++后,它们可能无法编译。此外,我扔掉了所有错误检查和其他噪音:
设备,设备上下文和交换链创建(D3D和Direct2D):
DXGI_FORMAT_A8_UNORM
D2D单通道位图创建:
// Direct2D factory creation
D2D1_FACTORY_OPTIONS options = {};
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
ID2D1Factory1* d2dFactory;
D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, options, &d2dFactory);
// Direct3D device creation
const auto type = D3D_DRIVER_TYPE_HARDWARE;
const auto flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
ID3D11Device* d3dDevice;
D3D11CreateDevice(nullptr, type, nullptr, flags, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, nullptr);
// Direct2D device creation
IDXGIDevice* dxgiDevice;
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));
ID2D1Device* d2dDevice;
d2dFactory->CreateDevice(dxgiDevice, &d2dDevice);
// Swap chain creation
DXGI_SWAP_CHAIN_DESC1 desc = {};
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = 2;
IDXGIAdapter* dxgiAdapter;
dxgiDevice->GetAdapter(&dxgiAdapter);
IDXGIFactory2* dxgiFactory;
dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void **>(&dxgiFactory));
IDXGISwapChain1* swapChain;
dxgiFactory->CreateSwapChainForHwnd(d3dDevice, hwnd, &swapChainDesc, nullptr, nullptr, &swapChain);
// Direct2D device context creation
const auto options = D2D1_DEVICE_CONTEXT_OPTIONS_NONE;
ID2D1DeviceContext* deviceContext;
d2dDevice->CreateDeviceContext(options, &deviceContext);
// create render target bitmap from swap chain
IDXGISurface* swapChainSurface;
swapChain->GetBuffer(0, __uuidof(swapChainSurface), reinterpret_cast<void **>(&swapChainSurface));
D2D1_BITMAP_PROPERTIES1 bitmapProperties;
bitmapProperties.dpiX = 0.0f;
bitmapProperties.dpiY = 0.0f;
bitmapProperties.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
bitmapProperties.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
bitmapProperties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
bitmapProperties.colorContext = nullptr;
ID2D1Bitmap1* swapChainBitmap = nullptr;
deviceContext->CreateBitmapFromDxgiSurface(swapChainSurface, &bitmapProperties, &swapChainBitmap);
// set swap chain bitmap as render target of D2D device context
deviceContext->SetTarget(swapChainBitmap);
位图绘制(FAILING):
const D2D1_SIZE_U size = { 512, 512 };
const UINT32 pitch = 512;
D2D1_BITMAP_PROPERTIES1 d2dProperties;
ZeroMemory(&d2dProperties, sizeof(D2D1_BITMAP_PROPERTIES1));
d2dProperties.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
d2dProperties.pixelFormat.format = DXGI_FORMAT_R8_UNORM;
char* sourceData = new char[512*512];
ID2D1Bitmap1* d2dBitmap;
deviceContext->DeviceContextPointer->CreateBitmap(size, sourceData, pitch, d2dProperties, &d2dBitmap);
答案 0 :(得分:0)
从我的经验来看,Direct2D确实非常有限。
您是否尝试过Direct2D effects(ID2D1Effect
)?你可以编写自己的[似乎比较复杂],或者使用built-in effects之一[这很简单]。
有一个叫Color matrix effect (CLSID_D2D1ColorMatrix
)。 可能可以让您的DXGI_FORMAT_R8_UNORM
(或DXGI_FORMAT_A8_UNORM
,任何单个频道都可以)作为输入(效果输入为ID2D1Image
,{{1继承自ID2D1Bitmap
)。然后设置ID2D1Image
以将输入通道复制到所有输出通道。但是没试过。