[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
@#ifndef D3DWIDGET_H
#define D3DWIDGET_H#include <QWidget>
#include <dxgi.h>
#include <d3d11.h>class D3DWidget : public QWidget
{
Q_OBJECT
Q_DISABLE_COPY(D3DWidget)public:
D3DWidget(QWidget* aParent = NULL, Qt::WindowFlags flags = 0);
~D3DWidget(void);
inline QPaintEngine* paintEngine(void) { return NULL; }protected:
bool createD3D11();
void paintEvent(QPaintEvent*);
void resizeEvent(QResizeEvent*);private:
ID3D11Device* m_pD3D11Dev;
ID3D11DeviceContext* m_pD3D11DevContext;
IDXGISwapChain* m_pD3DSwapChain;
ID3D11RenderTargetView* m_pRenderView;
DXGI_SWAP_CHAIN_DESC m_pSwapChainDesc;
ID3D11Texture2D* m_pBackBuffer;
D3D11_VIEWPORT m_pViewPort;
IDXGIAdapter* m_pAdapter;
};#endif
@CPP
@D3DWidget::D3DWidget(QWidget* aParent, Qt::WindowFlags flags)
: QWidget(aParent)
{createD3D11();
setAttribute(Qt::WA_PaintOnScreen, true);}
D3DWidget::~D3DWidget(void)
{
m_pD3D11Dev->Release();
m_pD3DSwapChain->Release();
}bool D3DWidget::createD3D11(void)
{
ZeroMemory(&this->m_pSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
m_pSwapChainDesc.BufferCount = 1;
m_pSwapChainDesc.BufferDesc.Width = width();
m_pSwapChainDesc.BufferDesc.Height = height();
m_pSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_pSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
m_pSwapChainDesc.SampleDesc.Count = 1;
m_pSwapChainDesc.SampleDesc.Quality = 0;
m_pSwapChainDesc.Windowed = true;
m_pSwapChainDesc.OutputWindow = winId();
m_pSwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
m_pSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
0, NULL , NULL , D3D11_SDK_VERSION,
&m_pSwapChainDesc,
&m_pD3DSwapChain,
&m_pD3D11Dev,
NULL,
&m_pD3D11DevContext
);if(FAILED(hr))
{
MessageBoxA(NULL, "Blah, Blah", "", MB_OK);
return false;
}ID3D11Texture2D* pBackBuffer;
if( FAILED( m_pD3DSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*)&pBackBuffer ) ) )
return false;
hr = m_pD3D11Dev->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderView );
pBackBuffer->Release();
if(FAILED(hr))
return false;
m_pD3D11DevContext->OMSetRenderTargets( 1, &m_pRenderView, NULL);
ZeroMemory(&m_pViewPort, sizeof(D3D11_VIEWPORT));
m_pViewPort.MinDepth = 0.0f;
m_pViewPort.MaxDepth = 1.0f;
m_pViewPort.TopLeftX = 0;
m_pViewPort.TopLeftY = 0;
m_pViewPort.Width = width();
m_pViewPort.Height = height();
m_pD3D11DevContext->RSSetViewports(1, &m_pViewPort);
return true;
}void D3DWidget::paintEvent(QPaintEvent* paint)
{
float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
m_pD3D11DevContext->ClearRenderTargetView(this->m_pRenderView,ClearColor);m_pD3DSwapChain->Present(0,0);
}void D3DWidget::resizeEvent(QResizeEvent* event)
{}@
-
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.
-
Solved - thank you, that worked perfectly
-H
@#ifndef D3DWIDGET_H
#define D3DWIDGET_H#include <QWidget>
#include <dxgi.h>
#include <d3d11.h>class D3DWidget : public QWidget
{
Q_OBJECT
Q_DISABLE_COPY(D3DWidget)public:
D3DWidget(QWidget* aParent = NULL, Qt::WindowFlags flags = 0);
~D3DWidget(void);
inline QPaintEngine* paintEngine(void) { return NULL; }protected:
bool createD3D11();
void paintEvent(QPaintEvent*);
void resizeEvent(QResizeEvent*);
virtual bool winEvent(MSG * message, long * result );
void render(void);
private:
ID3D11Device* m_pD3D11Dev;
ID3D11DeviceContext* m_pD3D11DevContext;
IDXGISwapChain* m_pD3DSwapChain;
ID3D11RenderTargetView* m_pRenderView;
DXGI_SWAP_CHAIN_DESC m_pSwapChainDesc;
ID3D11Texture2D* m_pBackBuffer;
D3D11_VIEWPORT m_pViewPort;
IDXGIAdapter* m_pAdapter;
};#endif
@-CPP
@#include "d3dwidget.h"D3DWidget::D3DWidget(QWidget* aParent, Qt::WindowFlags flags)
: QWidget(aParent)
{createD3D11();
setAttribute(Qt::WA_PaintOnScreen, true);
setUpdatesEnabled(false);
}D3DWidget::~D3DWidget(void)
{
m_pD3D11Dev->Release();
m_pD3DSwapChain->Release();
}bool D3DWidget::createD3D11(void)
{
ZeroMemory(&this->m_pSwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
m_pSwapChainDesc.BufferCount = 1;
m_pSwapChainDesc.BufferDesc.Width = width();
m_pSwapChainDesc.BufferDesc.Height = height();
m_pSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
m_pSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
m_pSwapChainDesc.SampleDesc.Count = 1;
m_pSwapChainDesc.SampleDesc.Quality = 0;
m_pSwapChainDesc.Windowed = true;
m_pSwapChainDesc.OutputWindow = winId();
m_pSwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
m_pSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
0, NULL , NULL , D3D11_SDK_VERSION,
&m_pSwapChainDesc,
&m_pD3DSwapChain,
&m_pD3D11Dev,
NULL,
&m_pD3D11DevContext
);if(FAILED(hr))
{
MessageBoxA(NULL, "Blah, Blah", "", MB_OK);
return false;
}ID3D11Texture2D* pBackBuffer;
if( FAILED( m_pD3DSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*)&pBackBuffer ) ) )
return false;
hr = m_pD3D11Dev->CreateRenderTargetView( pBackBuffer, NULL, &m_pRenderView );
pBackBuffer->Release();
if(FAILED(hr))
return false;
m_pD3D11DevContext->OMSetRenderTargets( 1, &m_pRenderView, NULL);
ZeroMemory(&m_pViewPort, sizeof(D3D11_VIEWPORT));
m_pViewPort.MinDepth = 0.0f;
m_pViewPort.MaxDepth = 1.0f;
m_pViewPort.TopLeftX = 0;
m_pViewPort.TopLeftY = 0;
m_pViewPort.Width = width();
m_pViewPort.Height = height();
m_pD3D11DevContext->RSSetViewports(1, &m_pViewPort);
return true;
}void D3DWidget::paintEvent(QPaintEvent* paint)
{}
void D3DWidget::resizeEvent(QResizeEvent* event)
{}
bool D3DWidget::winEvent(MSG * message, long * result )
{
bool returnValue = false;
switch(message->message)
{
case WM_PAINT:
// PreRender();
render();
//PostRender();
returnValue = true;
break;default:
returnValue = false;
}
return returnValue;
}void D3DWidget::render()
{
float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
m_pD3D11DevContext->ClearRenderTargetView(this->m_pRenderView,ClearColor);m_pD3DSwapChain->Present(0,0);
}@