I am going to create a game scene editor recently, which requires Directx11 to be used in conjunction with the GUI framework. Therefore, I simply created a program that embeds Directx11 into the Qt form.
1. Establish the project .
Build a Qt project and configure the directory and library directory (as well as additional dependencies) for Directx. It is convenient to add Qt vs2013 add in directly in vs2013, and write Qt creator to the Pro file. You can choose to generate the corresponding UI file or not generate it.
2 Code structure .
The structure of the project.
- The D3d11RenderWidget class inherits from QWidegt and is used for directx11 rendering
- MainWidget inherits from QMainWindow and is the parent form that contains the dx11 rendering form
- Effects.fx is a shader file, written together with VS and PS. Please note to set exclusion compilation in the project
- The main function is the program entry point
3 Key codes .
(1) Embedding dx11 into Qt requires obtaining a handle hwnd for a certain widgt, so a parameter, swapChainDesc, needs to be changed during D3D initialization OutputWindow= (HWND) winId().
swapChainDesc.BufferDesc=bufferDesc;
swapChainDesc.SampleDesc.Count=1;
swapChainDesc.SampleDesc.Quality=0;
swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount=1;
swapChainDesc.OutputWindow=(HWND)winId();
swapChainDesc.Windowed=TRUE;
swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD;
(2) The sub widgets used for rendering must have their properties set to.
setAttribute(Qt::WA_PaintOnScreen,true);
setAttribute(Qt::WA_NativeWindow,true);
Otherwise, rendering will be messy
(3) The rendering update relies on Qt's paintEvent function, where you can call update() to implement a rendering loop. (You can also set a timer to force a refresh at certain intervals, but this may not be effective.).
void D3d11RenderWidget::paintEvent(QPaintEvent *event)
{
//calculate fps
frameCount++;
if(getTime() > 1.0f)
{
fps=frameCount;
frameCount=0;
startFPStimer();
//set parent window title display fps value
parentWidget()->setWindowTitle("FPS: "+QString::number(fps));
}
frameTime=getFrameTime();
//updating and rendering scenes
UpdateScene(frameTime);
RenderScene();
//ensure that this function body is called every frame
update();
}
(4) The resizeEvent function must be rewritten to reset the frame cache, depth, and template cache, as well as the viewport, to prevent the scene from being stretched or the viewport from not corresponding during window scaling.
void D3d11RenderWidget::resizeEvent(QResizeEvent *event)
4 Screenshots
.
.
Source code:
Csdn: demo.
Github: demo