您的位置:首页 > 编程语言 > Qt开发

Qt中嵌入Directx11

2015-08-10 18:18 831 查看
最近要做个游戏场景编辑器,需要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;
(2)用于渲染的子widget必须设置属性为
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();
}
(4)必须重写resizeEvent函数,重新设置帧缓存、深度和模板缓存以及视口,防止窗口缩放时场景被拉伸或者视口不对应
void D3d11RenderWidget::resizeEvent(QResizeEvent *event)


4 截图





源代码:
csdn:demo
github:demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: