设置 DXGI_SWAP_CHAIN_DESC1 的 AlphaMode 成员会使 CreateSwapChainForHwnd 失败并返回 0x887a0001
Setting AlphaMode member of DXGI_SWAP_CHAIN_DESC1 makes CreateSwapChainForHwnd fail with 0x887a0001
我想创建一个交换链,我可以更改我的 alpha 值,使其变得半透明。我的代码在这里:
#include <Windows.h>
#include <d3d11.h>
#include <d2d1_3.h>
#include <dxgi1_6.h>
#include <dwmapi.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dwmapi.lib")
#pragma comment(lib, "d2d1.lib")
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hwnd, msg, wparam, lparam);
}
return 0;
}
int WINAPI wWinMain(HINSTANCE hinstance, HINSTANCE, LPWSTR, int)
{
WNDCLASSEX wc{
sizeof WNDCLASSEX, CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hinstance, nullptr, LoadCursorW(nullptr, IDC_ARROW), nullptr, nullptr,
L"DxClass", nullptr
};
const auto hwnd{
CreateWindowExW(WS_EX_COMPOSITED, MAKEINTATOM(RegisterClassExW(&wc)), L"DirectX",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 650, HWND_DESKTOP, nullptr,
hinstance, nullptr)
};
const MARGINS marg{-1, -1, -1, -1};
DwmExtendFrameIntoClientArea(hwnd, &marg);
D3D_FEATURE_LEVEL levels[]{ D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0 };
ID3D11Device* device;
IDXGIDevice* dxdevice;
IDXGIAdapter* adapter;
IDXGIFactory7* dxFactory;
ID2D1Device* d2dDevice;
ID2D1DeviceContext* d2dContext;
IDXGISwapChain1* swapChain;
D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_BGRA_SUPPORT, levels, 2u, D3D11_SDK_VERSION, &device, 0, 0);
device->QueryInterface(IID_PPV_ARGS(&dxdevice));
dxdevice->GetAdapter(&adapter);
adapter->GetParent(IID_PPV_ARGS(&dxFactory));
D2D1CreateDevice(dxdevice, { D2D1_THREADING_MODE_SINGLE_THREADED, D2D1_DEBUG_LEVEL_INFORMATION, D2D1_DEVICE_CONTEXT_OPTIONS_NONE }, &d2dDevice);
d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2dContext);
DXGI_SWAP_CHAIN_DESC1 sc{ 0 };
sc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
sc.SampleDesc.Count = 1;
sc.Scaling = DXGI_SCALING_NONE;
sc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sc.BufferCount = 2;
sc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
sc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
sc.Flags = DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER;
HRESULT hr = dxFactory->CreateSwapChainForHwnd(dxdevice, hwnd, &sc, nullptr, 0, &swapChain);
if (FAILED(hr))
{
__debugbreak();
return -1;
}
MSG m;
while (GetMessageW(&m, nullptr, 0, 0))
{
TranslateMessage(&m);
DispatchMessageW(&m);
}
swapChain->Release();
d2dContext->Release();
device->Release();
d2dDevice->Release();
dxFactory->Release();
dxdevice->Release();
adapter->Release();
return 0;
}
我希望绘图表面是半透明的,这样背面就会透出来。我读过 WS_EX_COMPOSITED
和 DwmExtendFrameIntoClientArea
将创建一个 Direct3D 可以直接绘制的绘图表面,但是,由于这个问题,我还没有得到那么远。我的目标是在不使用分层 windows 的情况下做到这一点,正如我看到其他人这样做的那样:Vista D3D
当我注释掉交换链结构的 AlphaMode 成员时它起作用了,但我需要使用它。我怎样才能让它工作?谢谢。
如果您启用调试层,错误附带的消息会解释错误:
DXGI ERROR: IDXGIFactory::CreateSwapChain: Alpha blended swapchains must be created with CreateSwapChainForComposition, or CreateSwapChainForCoreWindow with the DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER flag.
我想创建一个交换链,我可以更改我的 alpha 值,使其变得半透明。我的代码在这里:
#include <Windows.h>
#include <d3d11.h>
#include <d2d1_3.h>
#include <dxgi1_6.h>
#include <dwmapi.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dwmapi.lib")
#pragma comment(lib, "d2d1.lib")
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hwnd, msg, wparam, lparam);
}
return 0;
}
int WINAPI wWinMain(HINSTANCE hinstance, HINSTANCE, LPWSTR, int)
{
WNDCLASSEX wc{
sizeof WNDCLASSEX, CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hinstance, nullptr, LoadCursorW(nullptr, IDC_ARROW), nullptr, nullptr,
L"DxClass", nullptr
};
const auto hwnd{
CreateWindowExW(WS_EX_COMPOSITED, MAKEINTATOM(RegisterClassExW(&wc)), L"DirectX",
WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 800, 650, HWND_DESKTOP, nullptr,
hinstance, nullptr)
};
const MARGINS marg{-1, -1, -1, -1};
DwmExtendFrameIntoClientArea(hwnd, &marg);
D3D_FEATURE_LEVEL levels[]{ D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0 };
ID3D11Device* device;
IDXGIDevice* dxdevice;
IDXGIAdapter* adapter;
IDXGIFactory7* dxFactory;
ID2D1Device* d2dDevice;
ID2D1DeviceContext* d2dContext;
IDXGISwapChain1* swapChain;
D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_BGRA_SUPPORT, levels, 2u, D3D11_SDK_VERSION, &device, 0, 0);
device->QueryInterface(IID_PPV_ARGS(&dxdevice));
dxdevice->GetAdapter(&adapter);
adapter->GetParent(IID_PPV_ARGS(&dxFactory));
D2D1CreateDevice(dxdevice, { D2D1_THREADING_MODE_SINGLE_THREADED, D2D1_DEBUG_LEVEL_INFORMATION, D2D1_DEVICE_CONTEXT_OPTIONS_NONE }, &d2dDevice);
d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &d2dContext);
DXGI_SWAP_CHAIN_DESC1 sc{ 0 };
sc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
sc.SampleDesc.Count = 1;
sc.Scaling = DXGI_SCALING_NONE;
sc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sc.BufferCount = 2;
sc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
sc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
sc.Flags = DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER;
HRESULT hr = dxFactory->CreateSwapChainForHwnd(dxdevice, hwnd, &sc, nullptr, 0, &swapChain);
if (FAILED(hr))
{
__debugbreak();
return -1;
}
MSG m;
while (GetMessageW(&m, nullptr, 0, 0))
{
TranslateMessage(&m);
DispatchMessageW(&m);
}
swapChain->Release();
d2dContext->Release();
device->Release();
d2dDevice->Release();
dxFactory->Release();
dxdevice->Release();
adapter->Release();
return 0;
}
我希望绘图表面是半透明的,这样背面就会透出来。我读过 WS_EX_COMPOSITED
和 DwmExtendFrameIntoClientArea
将创建一个 Direct3D 可以直接绘制的绘图表面,但是,由于这个问题,我还没有得到那么远。我的目标是在不使用分层 windows 的情况下做到这一点,正如我看到其他人这样做的那样:Vista D3D
当我注释掉交换链结构的 AlphaMode 成员时它起作用了,但我需要使用它。我怎样才能让它工作?谢谢。
如果您启用调试层,错误附带的消息会解释错误:
DXGI ERROR: IDXGIFactory::CreateSwapChain: Alpha blended swapchains must be created with CreateSwapChainForComposition, or CreateSwapChainForCoreWindow with the DXGI_SWAP_CHAIN_FLAG_FOREGROUND_LAYER flag.