如何有效地调整DirectX窗口的大小?

时间:2012-01-06 20:25:12

标签: c++ windows visual-c++ directx

我查看了这个网站示例:http://www.codesampler.com/dx9src/dx9src_6.htm

但代码相当奇怪:它释放了每个纹理,顶点缓冲区,一切!然后再次构建它们:从磁盘加载模型......我不认为这是非常有效的! OpenGL可以在没有这些限制的情况下进行窗口大小调整。我怎么能像OpenGL一样做:高效的窗口调整大小而不需要释放程序中的每个资源?

我在上面的链接示例中尝试了代码,没有那些invalidateDeviceObjects / restoreDeviceObjects函数调用,但它没有工作..所以我想它必须完成?我希望不会,或者窗口大小调整对于在纹理,模型等中分配数百兆字节数据的大型应用程序来说会很痛苦。

3 个答案:

答案 0 :(得分:7)

这是d3d9设计的结果。调整d3d9窗口大小需要调用IDirect3DDevice9::Reset,并且需要调用文档:

调用IDirect3DDevice9 :: Reset会导致所有纹理内存表面丢失,托管纹理将从视频内存中刷新,并且所有状态信息都将丢失。

它就是这样。实际上,从游戏开始到游戏结束,你根本不会更改显示器的分辨率。通常你在游戏开始时设置分辨率,允许在某些特殊设置屏幕中重置。

现在我应该补充一点,如果你使用D3D9,你可以使用一个特殊的资源分配标志(D3DPOOL_MANAGED)来实际负责为你重新加载资源 。因此,所有纹理,顶点缓冲区等的本地(系统内存)副本在系统内存中自动维护,当GPU重置时,这些纹理等会自动复制回GPU。 / p>

如果您使用较新的D3DPOOL_MANAGED,请注意不要IDirect3DDevice9Ex

答案 1 :(得分:3)

在非游戏业务应用程序中,频繁调整窗口大小是UI的重要组成部分,我通过在检测到的全屏分辨率下将D3D设备创建为内存设备来解决此问题,然后在CWnd中使用StretchBlt :: OnDraw(...)在从后备缓冲区写入屏幕时调整内存位图的大小。这对于高帧率动画来说不是一个好的解决方案,但是在相对静态的视图情况下,用户的动作控制对象/视图运动,它比拆卸和重新创建方法更好。

答案 2 :(得分:0)

将后备缓冲区创建为显示器的最大分辨率,并使用SWAPEFFECT_COPY

绘制时,将代码绘制为当前窗口大小。

调用Present时,请提供源矩形和目标矩形的窗口大小。

然后您有了一个可调整大小的窗口,当窗口大小更改时,它不需要重新创建D3D设备。