DirectX 11 BitBlt Alternative
Pregunta
Tengo la siguiente función que estoy tratando de integrar en mi aplicación DirectX 11. Cuando estoy usando DirectX9, todo funciona bien, pero al convertir a DirectX 11, recibo una pantalla azul de error de muerte en la línea BitBlt (debo estar haciendo algo mal con los HDC?). Me preguntaba cuál sería la mejor manera de convertir este código en superficies compatibles con DirectX 11 en lugar de HDC.
Aquí está la función:
void CFlashDXPlayer::DrawFrame(HDC dc)
{
if (m_dirtyFlag)
{
IViewObject* pViewObject = NULL;
m_flashInterface->QueryInterface(IID_IViewObject, (LPVOID*) &pViewObject);
if (pViewObject != NULL)
{
// Combine regions
HRGN unionRgn, first, second = NULL;
unionRgn = CreateRectRgnIndirect(&m_dirtyRects[0]);
if (m_dirtyRects.size() >= 2)
second = CreateRectRgn(0, 0, 1, 1);
for (std::vector<RECT>::iterator it = m_dirtyRects.begin() + 1; it != m_dirtyRects.end(); ++it)
{
// Fill combined region
first = unionRgn;
SetRectRgn(second, it->left, it->top, it->right, it->bottom);
unionRgn = CreateRectRgn(0, 0, 1, 1);
CombineRgn(unionRgn, first, second, RGN_OR);
DeleteObject(first);
}
if (second)
DeleteObject(second);
RECT clipRgnRect; GetRgnBox(unionRgn, &clipRgnRect);
RECTL clipRect = { 0, 0, m_width, m_height };
// Fill background
if (m_transpMode != TMODE_FULL_ALPHA)
{
// Set clip region
SelectClipRgn(dc, unionRgn);
COLORREF fillColor = GetBackgroundColor();
HBRUSH fillColorBrush = CreateSolidBrush(fillColor);
FillRgn(dc, unionRgn, fillColorBrush);
DeleteObject(fillColorBrush);
// Draw to main buffer
HRESULT hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, dc, &clipRect, &clipRect, NULL, 0);
assert(SUCCEEDED(hr));
}
else
{
if (m_alphaBlackDC == NULL)
{
// Create memory buffers
BITMAPINFOHEADER bih = {0};
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biBitCount = 32;
bih.biCompression = BI_RGB;
bih.biPlanes = 1;
bih.biWidth = LONG(m_width);
bih.biHeight = -LONG(m_height);
m_alphaBlackDC = CreateCompatibleDC(dc);
m_alphaBlackBitmap = CreateDIBSection(m_alphaBlackDC, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&m_alphaBlackBuffer, 0, 0);
SelectObject(m_alphaBlackDC, m_alphaBlackBitmap);
m_alphaWhiteDC = CreateCompatibleDC(dc);
m_alphaWhiteBitmap = CreateDIBSection(m_alphaWhiteDC, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&m_alphaWhiteBuffer, 0, 0);
SelectObject(m_alphaWhiteDC, m_alphaWhiteBitmap);
}
HRESULT hr;
HBRUSH fillColorBrush;
// Render frame twice - against white and against black background to calculate alpha
SelectClipRgn(m_alphaBlackDC, unionRgn);
COLORREF blackColor = 0x00000000;
fillColorBrush = CreateSolidBrush(blackColor);
FillRgn(m_alphaBlackDC, unionRgn, fillColorBrush);
DeleteObject(fillColorBrush);
hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, m_alphaBlackDC, &clipRect, &clipRect, NULL, 0);
assert(SUCCEEDED(hr));
// White background
SelectClipRgn(m_alphaWhiteDC, unionRgn);
COLORREF whiteColor = 0x00FFFFFF;
fillColorBrush = CreateSolidBrush(whiteColor);
FillRgn(m_alphaWhiteDC, unionRgn, fillColorBrush);
DeleteObject(fillColorBrush);
hr = pViewObject->Draw(DVASPECT_TRANSPARENT, 1, NULL, NULL, NULL, m_alphaWhiteDC, &clipRect, &clipRect, NULL, 0);
assert(SUCCEEDED(hr));
// Combine alpha
for (LONG y = clipRgnRect.top; y < clipRgnRect.bottom; ++y)
{
int offset = y * m_width * 4 + clipRgnRect.left * 4;
for (LONG x = clipRgnRect.left; x < clipRgnRect.right; ++x)
{
BYTE blackRed = m_alphaBlackBuffer[offset];
BYTE whiteRed = m_alphaWhiteBuffer[offset];
m_alphaBlackBuffer[offset + 3] = 255 - (whiteRed - blackRed);
offset += 4;
}
}
// Blit result to target DC
BitBlt(dc, clipRgnRect.left, clipRgnRect.top,
clipRgnRect.right - clipRgnRect.left,
clipRgnRect.bottom - clipRgnRect.top,
m_alphaBlackDC, clipRgnRect.left, clipRgnRect.top, SRCCOPY);
}
DeleteObject(unionRgn);
pViewObject->Release();
}
m_dirtyFlag = false;
m_dirtyRects.clear();
m_dirtyUnionRect.left = m_dirtyUnionRect.top = LONG_MAX;
m_dirtyUnionRect.right = m_dirtyUnionRect.bottom = -LONG_MAX;
}
}
El HDC que estoy pasando a esta función se crea de la siguiente manera:
D3D11_TEXTURE2D_DESC textureDesc;
ZeroMemory(&textureDesc, sizeof(textureDesc));
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
HRESULT hr = device->CreateTexture2D(&textureDesc, NULL, &m_flashTexture);
HRESULT hResult;
HDC hDC;
IDXGISurface1 *pSurface = NULL;
hResult = m_flashTexture->QueryInterface(__uuidof(IDXGISurface1), (void**)&pSurface);
hResult = pSurface->GetDC(TRUE, &hDC);
assert(SUCCEEDED(hResult));
m_flashPlayer->DrawFrame(hDC);
¿Alguna idea de lo que estoy haciendo mal? Parece que no puedo averiguar qué está pasando y por qué esto está transmitiendo una pantalla azul cuando si uso DirectX 9 Obejcts no lo hace. ¿Hay una mejor manera de hacer esto?
(También he intentado actualizar mis controladores y todos están actualizados).
Gracias por la ayuda.
No hay solución correcta