zoukankan      html  css  js  c++  java
  • D3D-GetBackBuffer &GetFrontBufferData 抓屏&D3D抓取GPU数据

    HRESULT GetBackBuffer(
      [in]          UINT                iSwapChain,
      [in]          UINT               BackBuffer,
      [in]          D3DBACKBUFFER_TYPE Type,
      [out, retval] IDirect3DSurface9  **ppBackBuffer
    );
    
    

    Parameters

    iSwapChain [in]

    Type: UINT

    An unsigned integer specifying the swap chain.

    BackBuffer [in]

    Type: UINT

    Index of the back buffer object to return. Back buffers are numbered from 0 to the total number of back buffers minus one. A value of 0 returns the first back buffer, not the front buffer. The front buffer is not accessible through this method. Use IDirect3DDevice9::GetFrontBufferData to retrieve a copy of the front buffer.

    Type [in]

    Type: D3DBACKBUFFER_TYPE

    Stereo view is not supported in Direct3D 9, so the only valid value for this parameter is D3DBACKBUFFER_TYPE_MONO.

    ppBackBuffer [out, retval]

    Type: IDirect3DSurface9**

    Address of a pointer to an IDirect3DSurface9 interface, representing the returned back buffer surface.

    Return value

    Type: HRESULT

    If the method succeeds, the return value is D3D_OK. If BackBuffer equals or exceeds the total number of back buffers, then the function fails and returns D3DERR_INVALIDCALL.

    Remarks

    Calling this method will increase the internal reference count on the IDirect3DSurface9 interface. Failure to call IUnknown::Release when finished using this IDirect3DSurface9 interface results in a memory leak.

    https://msdn.microsoft.com/en-us/library/bb174379(VS.85).aspx

    利用 GetBackBuffer 截屏问题:

    截取windows桌面保存的画面是黑的问题。

    m_pd3dDevice->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, ddm.Format, D3DPOOL_SYSTEMMEM, &m_pSurface, NULL)
      
      
    IDirect3DSurface9*    pBlackSurface = NULL;
    m_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBlackSurface);
    m_pd3dDevice->GetRenderTargetData(pBlackSurface,m_pSurface);
    D3DXSaveSurfaceToFile("E:\test.bmp",D3DXIFF_BMP,m_pSurface,NULL, NULL);

    为什么截屏生成的图片全是黑的呀 (黑屏)??

    用GetFrontBufferData截屏是可以的,但测试了一下在我的机器上最多一秒截23帧图像,网上说用GetBackBuffer和 GetRenderTargetData 会快一些,但是为什么我的截出来的是黑屏呢?
    还有个问题 GetFrontBufferData 和 GetRenderTargetData 好像都是从显存里把数据考到内存里(是吗??) 为什么GetBackBuffer加 GetRenderTargetData的截屏组合会比GetFrontBufferData截屏快一些呢?

    --------------------------------

    IDirect3DDevice9 :: GetFrontBufferData方法
    生成设备前端缓冲区的副本,并将该副本放置在应用程序提供的系统内存缓冲区中。


    备注:
    由pDestSurface指向的缓冲区将填充前缓冲区的表示,转换为每像素格式的标准32位D3DFMT_A8R8G8B8。

    此方法是捕获反锯齿屏幕快照的唯一方法。

    这个功能在设计上非常慢,不应该用在任何性能关键的路径上。

    ----------------------------------

    GetFrontBufferData  是返回一个Copy, 有复制的过程,在复制的时候可能还要考虑到显卡当前是否正在使用其内容做处理

    GetBackBuffer,Retrieves a back buffer from the swap chain of the device.
       这个是不需要转换的

    看GetFrontBufferData的说明,  这个办法是唯一的可以把反混淆的效果也带回来的
    反混淆本身就是一个很浪费时间的操作,它也只发生在frontbuffer上

    -----------------------------------

    windows桌面不用后缓冲,所以后缓冲是黑的

    ------------------------------

    最新的WIN8上的API,DWM截屏。通过D3D9的话只有这个方法了。

    http://bbs.csdn.net/topics/390430991

    ===========================================================================

    利用D3D抓取GPU数据

    microsoft 提供的D3D SDK是用来进行3D建模和利用GPU运算的一组接口的集合,

    D3D SDK至少有两个优点:

    1、提供了一种3D建模的构架,程序员可以很容易的用这种构架来建模自己的3D模型

    2、提供了一种GPU和CPU并行运算的解决方案,,为提供应用程序的性能提供了一种思路

    这些对于D3D 程序员应该并不陌生,具体可以参见Direct 3D SDK文档。

    这篇文章主要想讲一个在D3D编程中经常遇到的一个问题,从GPU中把数据取出,存入本地磁盘中。这个功能的应用也应该比较常见,例如保存游戏录像视频等。实现GPU to CPU拷贝的D3D 方法还是比较多的,但对于视频转存来说,能达到实时转存效果才有真正的利用价值。

    这里首先简要介绍一下D3D 渲染的基本流程:

          1. D3D setting states//设置渲染环境

          2. g_pd3dDevice->beginscene();

          3. D3D 管线渲染

          4. g_pd3dDevice->EndScene();

    至此,D3D的渲染过程已经结束,渲染处理的最终数据被存于D3D surface(这是在GPU中开辟的存储区域), 下面可以根据具体的需求来对该surface进行后处理:

    1 直接显示:g_pd3dDevice->present();

    2 转存到本地磁盘,即GPU to CPU的copy.

    这里给出比较常见的一种处理方法:

    g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackbuffer);

            pBackbuffer->LockRect(&Source,NULL,0);

    copy(Dest,Source);

    pBackbuffer->UnLock();

    这种方法缺点很严重,就是由于IPtrD3dsurface lock的内存是位于显卡中,这样在做copy(Dest,Source)的时候,非常缓慢,基本无法实现实时转存的要求。

    那microsoft有没有提供更好的解决方案呢?哈哈,答案是肯定的,直接上代码:

    g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&pBackbuffer);

    g_pd3dDevice->CreateOffscreenPlainSurface(d3dpp.BackBufferWidth,

    d3dpp.BackBufferHeight,d3dpp.BackBufferFormat,D3DPOOL_SYSMEM,&g_p2DSurface,NULL);

    g_pd3dDevice->GetRenderTargetData(pBackbuffer, g_p2DSurface);

    g_p2DSurface->LockRect(&Source,NULL,0);

            copy(Dest,Source);

            g_p2DSurface->UnLock();

     
    这段代码的处理速度是很赞的,对于正在急于寻找处理方法而又看到我这篇文章的朋友将是很幸运的。
    至于其深层的原因,关键还是取决去CreateOffscreenPlainSurface函数,这个函数在内存中开辟了一块区域g_p2DSurface,microsoft可能采取了某种策略使得这块内存区域是最利于GPU拷贝的。真正的本质原因由于没有看过源代码,也不是很清楚。
    http://blog.csdn.net/seamanj/article/details/8878421
  • 相关阅读:
    1.4 Arduino IDE
    1.3 选择适合的Arduino
    1.2为什么选择Arduino
    1.1什么是Arduino
    博文《arduino入门》预告
    Delphi实现HTMLWebBrowser实现HTML界面
    Delphi判断MDI子窗体是否被创建
    Delphi给窗体镶边-为控件加边框,描边,改变边框颜色
    Delphi 查找标题已知的窗口句柄,遍历窗口控件句柄
    DELPHI实现类似仿360桌面的程序界面
  • 原文地址:https://www.cnblogs.com/wainiwann/p/8080681.html
Copyright © 2011-2022 走看看