Question

J'ai la fonction suivante que j'essaie d'intégrer dans mon application DirectX 11. Lorsque j'utilise DirectX9, tout fonctionne bien, mais lors de la conversion à DirectX 11, je reçois un écran bleu d'erreur de mort à la ligne Bitblt (je dois faire quelque chose de mal avec les HDC?). Je me demandais quelle serait la meilleure façon de convertir ce code en surfaces compatibles DirectX 11 au lieu des HDC.

Voici la fonction:

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;
}
}

Le HDC que je passe à cette fonction est créé de la manière suivante:

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);

Des idées de ce que je fais mal? Je n'arrive pas à comprendre ce qui se passe et pourquoi cela mène un écran bleu alors que si j'utilise DirectX 9 obejcts, ce n'est pas le cas. Y a-t-il une meilleure manière de faire cela?

(J'ai également essayé de mettre à jour mes pilotes et ils sont tous à jour).

Merci pour l'aide.

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top