美文网首页
IDirect3DDevice9::GetFrontBuffer

IDirect3DDevice9::GetFrontBuffer

作者: 叶迎宪 | 来源:发表于2020-12-08 22:41 被阅读0次

    一个使用Direct3D9接口实现抓屏的程序,今天在一台笔记本上面一直抓不到数据。报错的地方位于

        hr = d3dDev9_->CreateOffscreenPlainSurface(screenWidth, screenHeight, D3DFMT_A8R8G8B8,
            D3DPOOL_SCRATCH, &destTarget, NULL);
        if (FAILED(hr))
        {
            TRACE_LOG(TRACE_ERROR, "Failed to CreateOffscreenPlainSurface!\n");
            return hr;
        }
    
        hr = d3dDev9_->GetFrontBufferData(0, destTarget);
        if (FAILED(hr))
        {
            TRACE_LOG(TRACE_ERROR, "Failed to GetFrontBufferData!\n");
            goto CapEnd;
        }
    

    GetFrontBufferData返回了-2005530516,即D3DERR_INVALIDCALL。google查了好久,都没找到有用的信息。网上能找到的有用信息,就是要使用DirectX Control Panel来打卡调试信息,再根据信息一步步排查
    https://www.cnblogs.com/minggoddess/archive/2011/06/16/2082970.html

    但是DirectX 9毕竟已经时代久远,出问题的电脑是windows 10的,找了半天也没找到怎么把DirectX 9的调试信息弄出来。熬了一个晚上,最终决定放弃治疗,改为用GDI抓屏。

    可第二天调试的时候突然发现,使用GDI抓屏抓出来的画面,分辨率并不是1920*1080,而是1536*864。这是因为我的屏幕设置为125%字体大小了,这时候使用GetSystemMetrics获取到的值就不是屏幕分辨率了。果然把字体调回100%,Direct3D9又能正常工作了!这是一个巨大的发现

    研究了一下windows dpi工作机制。默认的win32程序是dpi unaware的,因此系统的窗口管理器会托管应用程序,在DPI发生改变的时候,直接对应用程序的界面进行比例缩放,通过windows api获取到的尺寸也会等比例缩放
    https://stackoverflow.com/questions/2630392/getsystemmetrics-returns-wrong-value-for-sm-cxscreen

    只要把应用程序声明为dpi aware的(方法参考上面的stackoverflow链接),GetSystemMetrics就可以获取到正确的分辨率值,从而direct3d的采集也恢复正常了

    相关文章

      网友评论

          本文标题:IDirect3DDevice9::GetFrontBuffer

          本文链接:https://www.haomeiwen.com/subject/dbnqgktx.html