Qt中嵌入Directx11(有句柄就可以)

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)  

猜你喜欢

转载自blog.csdn.net/lengyuezuixue/article/details/80894315
今日推荐