最近要做個游戲場景編輯器,需要directx11配合gui框架使用,所以簡單地弄了一個directx11嵌入到Qt窗體中的程序。
1 建立工程
建一個Qt的工程,配置好directx的包含目錄和庫目錄(以及附加依賴項),Qt vs2013 add-in的話很方便,直接在vs2013里面加,Qt creator的話寫到pro文件里,可以選擇生成對應的ui文件,或者不生成。
2 代碼結構
工程的結構
- D3d11RenderWidget類繼承自QWidegt,用於directx11渲染
- MainWidget繼承自QMainWindow,是包含dx11渲染窗體的父窗體
- Effects.fx是shader文件,VS和PS寫到一起,注意要在工程中設置排除編譯
- main函數是程序入口
3 關鍵代碼
(1)dx11嵌入到Qt中就需要獲得某個widgt的句柄hwnd,所以在D3D初始化時要改一個參數,swapChainDesc.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;
- setAttribute(Qt::WA_PaintOnScreen,true);
- setAttribute(Qt::WA_NativeWindow,true);
(3)渲染更新借助的就是Qt的paintEvent函數,在里面再調用update()就可以實現渲染循環。(也可以設置定時器隔一定時間強制刷新,不過這樣效果不好)
- void D3d11RenderWidget::paintEvent(QPaintEvent *event)
- {
- //計算fps
- frameCount++;
- if(getTime() > 1.0f)
- {
- fps=frameCount;
- frameCount=0;
- startFPStimer();
- //設置父窗口標題顯示fps值
- parentWidget()->setWindowTitle("FPS: "+QString::number(fps));
- }
- frameTime=getFrameTime();
- //更新場景和渲染場景
- UpdateScene(frameTime);
- RenderScene();
- //保證此函數體每一幀都調用
- update();
- }
- void D3d11RenderWidget::resizeEvent(QResizeEvent *event)
源代碼:
csdn:
demo
github:
demo
http://blog.csdn.net/u012234115/article/details/47402277
