October 4, 2011

Hornsj2 Hornsj2
Lab Rat
80 posts

[Solved] Direct3d and Qt Not Working

 

I am trying to render D3D11 to a QWidget derived class. The class is below, can anyone see what I’m doing wrong? Right now what I see is the D3D result flickers on the screen once in a while but doesn’t show up consistently.
H

  1. #ifndef D3DWIDGET_H
  2. #define D3DWIDGET_H
  3.  
  4. #include <QWidget>
  5. #include <dxgi.h>
  6. #include <d3d11.h>
  7.  
  8. class D3DWidget : public QWidget
  9. {
  10.  Q_OBJECT
  11.   Q_DISABLE_COPY(D3DWidget)
  12.  
  13.  public:
  14.   D3DWidget(QWidget* aParent = NULL, Qt::WindowFlags flags = 0);
  15.   ~D3DWidget(void);
  16.   inline QPaintEngine* paintEngine(void) { return NULL; }
  17.  
  18.  protected:
  19.   bool createD3D11();
  20.   void paintEvent(QPaintEvent*);
  21.   void resizeEvent(QResizeEvent*);
  22.  
  23.  private:
  24.   ID3D11Device* m_pD3D11Dev;
  25.   ID3D11DeviceContext* m_pD3D11DevContext;
  26.   IDXGISwapChain* m_pD3DSwapChain;
  27.   ID3D11RenderTargetView* m_pRenderView;
  28.   DXGI_SWAP_CHAIN_DESC m_pSwapChainDesc;
  29.   ID3D11Texture2D* m_pBackBuffer;
  30.   D3D11_VIEWPORT m_pViewPort;
  31.   IDXGIAdapter* m_pAdapter;
  32. };
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39. #endif

CPP

  1. D3DWidget::D3DWidget(QWidget* aParent, Qt::WindowFlags flags)
  2.  : QWidget(aParent)
  3. {
  4.  
  5.  createD3D11();
  6.  setAttribute(Qt::WA_PaintOnScreen, true);
  7.  
  8. }
  9.  
  10. D3DWidget::~D3DWidget(void)
  11. {
  12.  m_pD3D11Dev->Release();
  13.  m_pD3DSwapChain->Release();
  14. }
  15.  
  16. bool D3DWidget::createD3D11(void)
  17. {
  18.  ZeroMemory(&this->m_pSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
  19.  m_pSwapChainDesc.BufferCount = 1;
  20.  m_pSwapChainDesc.BufferDesc.Width = width();
  21.  m_pSwapChainDesc.BufferDesc.Height = height();
  22.  m_pSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  23.  m_pSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  24.  m_pSwapChainDesc.SampleDesc.Count = 1;
  25.  m_pSwapChainDesc.SampleDesc.Quality = 0;
  26.  m_pSwapChainDesc.Windowed = true;
  27.  m_pSwapChainDesc.OutputWindow = winId();
  28.  m_pSwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
  29.  m_pSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
  30.  
  31.  HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL,
  32.   D3D_DRIVER_TYPE_HARDWARE,
  33.   NULL,
  34.   0, NULL , NULL , D3D11_SDK_VERSION,
  35.   &m_pSwapChainDesc,
  36.   &m_pD3DSwapChain,
  37.   &m_pD3D11Dev,
  38.   NULL,
  39.   &m_pD3D11DevContext
  40.   );
  41.  
  42.  if(FAILED(hr))
  43.  {
  44.   MessageBoxA(NULL, "Blah, Blah", "", MB_OK);
  45.   return false;
  46.  }
  47.  
  48.  ID3D11Texture2D* pBackBuffer;
  49.  if( FAILED( m_pD3DSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*)&pBackBuffer ) ) )
  50.   return false;
  51.  hr = m_pD3D11Dev->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderView );
  52.  pBackBuffer->Release();
  53.  if(FAILED(hr))
  54.   return false;
  55.  m_pD3D11DevContext->OMSetRenderTargets( 1, &m_pRenderView, NULL);
  56.  ZeroMemory(&m_pViewPort, sizeof(D3D11_VIEWPORT));
  57.  m_pViewPort.MinDepth = 0.0f;
  58.  m_pViewPort.MaxDepth = 1.0f;
  59.  m_pViewPort.TopLeftX = 0;
  60.  m_pViewPort.TopLeftY = 0;
  61.  m_pViewPort.Width = width();
  62.  m_pViewPort.Height = height();
  63.  m_pD3D11DevContext->RSSetViewports(1, &m_pViewPort);
  64.     return true;
  65. }
  66.  
  67. void D3DWidget::paintEvent(QPaintEvent* paint)
  68. {
  69.  float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
  70.  m_pD3D11DevContext->ClearRenderTargetView(this->m_pRenderView,ClearColor);
  71.  
  72.  m_pD3DSwapChain->Present(0,0);
  73. }
  74.  
  75. void D3DWidget::resizeEvent(QResizeEvent* event)
  76. {
  77.  
  78. }

2 replies

October 4, 2011

Andrew den Exter Andrew den Exter
Lab Rat
6 posts

The flickering is Qt presenting it’s back buffer over the direct 3d content. The way to fix is to disable paint updates on the widget with setUpdatesEnabled(false) and reimplementing winEvent() to handle WM_PAINT messages as you wont get paintEvents with updates disabled.

October 5, 2011

Hornsj2 Hornsj2
Lab Rat
80 posts

Solved – thank you, that worked perfectly

-H

  1. #ifndef D3DWIDGET_H
  2. #define D3DWIDGET_H
  3.  
  4. #include <QWidget>
  5. #include <dxgi.h>
  6. #include <d3d11.h>
  7.  
  8. class D3DWidget : public QWidget
  9. {
  10.  Q_OBJECT
  11.   Q_DISABLE_COPY(D3DWidget)
  12.  
  13.  public:
  14.   D3DWidget(QWidget* aParent = NULL, Qt::WindowFlags flags = 0);
  15.   ~D3DWidget(void);
  16.   inline QPaintEngine* paintEngine(void) { return NULL; }
  17.  
  18.  protected:
  19.   bool createD3D11();
  20.   void paintEvent(QPaintEvent*);
  21.   void resizeEvent(QResizeEvent*);
  22.   virtual bool winEvent(MSG * message, long * result );
  23.   void render(void);
  24.  private:
  25.   ID3D11Device* m_pD3D11Dev;
  26.   ID3D11DeviceContext* m_pD3D11DevContext;
  27.   IDXGISwapChain* m_pD3DSwapChain;
  28.   ID3D11RenderTargetView* m_pRenderView;
  29.   DXGI_SWAP_CHAIN_DESC m_pSwapChainDesc;
  30.   ID3D11Texture2D* m_pBackBuffer;
  31.   D3D11_VIEWPORT m_pViewPort;
  32.   IDXGIAdapter* m_pAdapter;
  33. };
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40. #endif

-CPP

  1. #include "d3dwidget.h"
  2.  
  3. D3DWidget::D3DWidget(QWidget* aParent, Qt::WindowFlags flags)
  4.  : QWidget(aParent)
  5. {
  6.  
  7.  createD3D11();
  8.  setAttribute(Qt::WA_PaintOnScreen, true);
  9.  setUpdatesEnabled(false);
  10. }
  11.  
  12. D3DWidget::~D3DWidget(void)
  13. {
  14.  m_pD3D11Dev->Release();
  15.  m_pD3DSwapChain->Release();
  16. }
  17.  
  18. bool D3DWidget::createD3D11(void)
  19. {
  20.  ZeroMemory(&this->m_pSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
  21.  m_pSwapChainDesc.BufferCount = 1;
  22.  m_pSwapChainDesc.BufferDesc.Width = width();
  23.  m_pSwapChainDesc.BufferDesc.Height = height();
  24.  m_pSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  25.  m_pSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  26.  m_pSwapChainDesc.SampleDesc.Count = 1;
  27.  m_pSwapChainDesc.SampleDesc.Quality = 0;
  28.  m_pSwapChainDesc.Windowed = true;
  29.  m_pSwapChainDesc.OutputWindow = winId();
  30.  m_pSwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
  31.  m_pSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
  32.  
  33.  HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL,
  34.   D3D_DRIVER_TYPE_HARDWARE,
  35.   NULL,
  36.   0, NULL , NULL , D3D11_SDK_VERSION,
  37.   &m_pSwapChainDesc,
  38.   &m_pD3DSwapChain,
  39.   &m_pD3D11Dev,
  40.   NULL,
  41.   &m_pD3D11DevContext
  42.   );
  43.  
  44.  if(FAILED(hr))
  45.  {
  46.   MessageBoxA(NULL, "Blah, Blah", "", MB_OK);
  47.   return false;
  48.  }
  49.  
  50.  ID3D11Texture2D* pBackBuffer;
  51.  if( FAILED( m_pD3DSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*)&pBackBuffer ) ) )
  52.   return false;
  53.  hr = m_pD3D11Dev->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderView );
  54.  pBackBuffer->Release();
  55.  if(FAILED(hr))
  56.   return false;
  57.  m_pD3D11DevContext->OMSetRenderTargets( 1, &m_pRenderView, NULL);
  58.  ZeroMemory(&m_pViewPort, sizeof(D3D11_VIEWPORT));
  59.  m_pViewPort.MinDepth = 0.0f;
  60.  m_pViewPort.MaxDepth = 1.0f;
  61.  m_pViewPort.TopLeftX = 0;
  62.  m_pViewPort.TopLeftY = 0;
  63.  m_pViewPort.Width = width();
  64.  m_pViewPort.Height = height();
  65.  m_pD3D11DevContext->RSSetViewports(1, &m_pViewPort);
  66.     return true;
  67. }
  68.  
  69. void D3DWidget::paintEvent(QPaintEvent* paint)
  70. {
  71.  
  72. }
  73.  
  74. void D3DWidget::resizeEvent(QResizeEvent* event)
  75. {
  76.  
  77. }
  78.  
  79. bool D3DWidget::winEvent(MSG * message, long * result )
  80. {
  81.  bool returnValue = false;
  82.  switch(message->message)
  83.  {
  84.   case WM_PAINT:
  85.   // PreRender();
  86.    render();
  87.    //PostRender();
  88.    returnValue = true;
  89.    break;
  90.  
  91.   default:
  92.    returnValue = false;
  93.  }
  94.  return returnValue;
  95. }
  96.  
  97. void D3DWidget::render()
  98. {
  99.  float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
  100.  m_pD3D11DevContext->ClearRenderTargetView(this->m_pRenderView,ClearColor);
  101.  
  102.  m_pD3DSwapChain->Present(0,0);
  103. }

 
  ‹‹ No such slot error      undostack decrement problem ››

You must log in to post a reply. Not a member yet? Register here!