我查看了这个网站示例:http://www.codesampler.com/dx9src/dx9src_6.htm
但代码相当奇怪:它释放了每个纹理,顶点缓冲区,一切!然后再次构建它们:从磁盘加载模型......我不认为这是非常有效的! OpenGL可以在没有这些限制的情况下进行窗口大小调整。我怎么能像OpenGL一样做:高效的窗口调整大小而不需要释放程序中的每个资源?
我在上面的链接示例中尝试了代码,没有那些invalidateDeviceObjects / restoreDeviceObjects函数调用,但它没有工作..所以我想它必须完成?我希望不会,或者窗口大小调整对于在纹理,模型等中分配数百兆字节数据的大型应用程序来说会很痛苦。
答案 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设备。