Qt中嵌入Directx11

最近要做个游戏场景编辑器,需要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

 

 

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值