问题描述
-
我使用了DrawIconEx(GDI / D3D11互操作性和CopyResource)来生成ID3D11Texture2D,该像素具有许多alpha通道值为0的像素。D3D11_USAGE_STAGING/ Map已验证了此纹理,可以查看像素值和{ 3}}保存png(需要修改相关代码:DXGI_FORMAT_B8G8R8A8_UNORM->使用GUID_WICPixelFormat32bppBGRA而不是GUID_WICPixelFormat24bppBGR)。
-
当我使用ScreenGrab的渲染纹理方法时,0像素的alpha值将被渲染为黑色,这不是我想要的,我希望这些像素能够透明。将如何实现目标?这是我的相关代码:
HRESULT CGraphRender::Init() { ... // Create an alpha enabled blend state description. _blend_state = nullptr; D3D11_BLEND_DESC blendDesc; ZeroMemory(&blendDesc,sizeof(D3D11_BLEND_DESC)); blendDesc.RenderTarget[0].BlendEnable = TRUE; blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = _d3d_device->CreateBlendState(&blendDesc,&_blend_state); RETURN_ON_FAIL(hr); .... } HRESULT CGraphRender::Clear_3D(float color[]) { ID3D11RenderTargetView* rtv[] = { _back_rendertarget_view }; _immediate_context->OMSetRenderTargets(_countof(rtv),rtv,nullptr); _immediate_context->ClearRenderTargetView(_back_rendertarget_view,color); float blendFactor[4] = { 1.f,1.f,1.f }; _immediate_context->OMSetBlendState(_blend_state,blendFactor,0xffffffff); return S_OK; }
解决方法
问题已解决:在渲染“ alpha”纹理之前执行OMGetBlendState(_blend_state ...设置,并在渲染后恢复默认的blendstate
HRESULT CGraphRender::DrawTexture(const std::shared_ptr<CDrawTextureShader>& texture,const RECT& dst_rect,const BOOL& is_blend_alpha)
{
CComPtr<ID3D11DeviceContext> immediate_context;
_d3d_device->GetImmediateContext(&immediate_context);
if (!immediate_context)
{
return E_UNEXPECTED;
}
if (is_blend_alpha)
{
CComPtr<ID3D11BlendState> old_blend_state;
FLOAT old_blend_factor[4] = { 0.f };
UINT old_sample_mask = 0;
immediate_context->OMGetBlendState(&old_blend_state,old_blend_factor,&old_sample_mask);
float blend_factor[4] = { 1.f,1.f,1.f };
immediate_context->OMSetBlendState(_blend_state,blend_factor,0xffffffff);
HRESULT hr = texture->Render(immediate_context,dst_rect);
immediate_context->OMSetBlendState(old_blend_state,old_sample_mask);
return hr;
}
else
{
return texture->Render(immediate_context,dst_rect);
}
}