2012-02-23 7 views
2

나는 내 directx 11 응용 프로그램에 통합하려고하는 다음과 같은 기능을 가지고 있습니다. directx9를 사용할 때 모든 것이 잘 작동하지만 directx 11로 변환 할 때 Bitblt 라인에서 파란 화면이 나옵니다 (HDC의 문제가있을 것입니다). 이 코드를 HDC 대신 directx 11 호환 표면으로 변환하는 최선의 방법이 무엇인지 궁금합니다. 여기 Directx 11 Bitblt 대체

는 기능입니다 : 내가 잘못 뭐하는 거지의

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

모든 아이디어 :이 함수에 전달 오전 HDC는 다음과 같은 방식으로 생성된다

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

? 나는 무슨 일이 일어나고 있는지, 왜 내가 DirectX 9를 사용하는지 블루 스크린을 사용 하는지를 파악할 수 없다. 이 작업을 수행하는 더 좋은 방법이 있습니까?

(또한 드라이버를 업데이트하려고 시도했지만 모두 최신 상태입니다.)

도움 주셔서 감사합니다.

+3

컴퓨터를 BSOD로 설정 했습니까? 끔찍한 (나쁜 방식으로). –

답변

2

이것이 실제로 드라이버 문제였습니다. 그것은 내 latop에 radeon으로 설정된 내 그래픽 카드로 실행할 때 문제없이 작동하지만, 내 radeon을 선택해야하더라도 어떤 이유로 든 전환 할 수있을 때 여전히 충돌합니다. 그래픽 모드를 고정시켜야합니다. 이상한,하지만 atleast 내 프로그램 같아.

1

코드 검사로는 실제로 알 수 없습니다. 나는 노골적으로 잘못된 것을 눈치 채지 못했다. 확실히 BSOD가 없어야합니다. 그 부분은 드라이버 버그입니다. 어떤 하드웨어/드라이버를 실행하고 있습니까?

DC 메모리 외부로 블리 싱하는 경우 종종 메모리 공간에 불법적으로 쓰지만 드라이버가 충돌하는 일반적인 이유가 있습니다. 귀하의 지역이 범위를 벗어나지 않고 m_alphaBlackDC가 dc와 동일한 크기인지 확인하기 위해 두 번 확인해 보겠습니다.

다른 비 관련 GPU (동일한 하드웨어 아키텍처를 공유하지 않음)에서 테스트하는 것이 좋습니다.