我一直在2009年3月DirectX SDK中为Direct3D应用程序测试DXUT功能。它们似乎具有许多有用的功能,包括自动检测DirecX10或DirectX9以及窗口管理功能,这些功能绕过了Direct3D通常要求的许多繁琐的窗口管理任务。但是,当我使用DXUTSetWindow函数让Direct3D绘制到已经创建的窗口时,我遇到了问题。在这种情况下,CFrameWndEx
的查看子窗口是应用程序的主窗口。
如果将bHandleMessages
参数设置为true,则一切都会调整大小并重置,而无需我进行任何干预。但是,当我尝试关闭程序时,应用程序崩溃了(并立即退出,因此我什至无法中断导致崩溃的原因),并且发生了一系列内存泄漏。如果将bHandleMessages
设置为false,则无法进行任何大小调整,但是退出时不会崩溃,也不会导致内存泄漏。
看来DXUTMainLoop正在寻找WM_QUIT
消息以退出,然后清除所有Direct3D对象,子窗口从未接收到该对象。我已经尝试了以下方法,但均未成功:
覆盖CFrameWndEx
的OnClose
功能,并手动向该子级发送WM_QUIT
消息。
将DXUTMainLoop
调用放在辅助线程上。
覆盖CFrameWndEx::DefWindowProc
并使用DXUTStaticWndProc函数(DXUT文档在使用DXUTSetWindow
时会使用该函数,但在任何示例中均未显示)。
将窗口设置为使用CFrameWndEx
的句柄,并为子窗口创建单独的交换链。似乎DXUT会使DXUTSetWindow
中使用的句柄变黑,而不管OnD3D9FrameRender回调中是否对其进行了任何处理。
更新:覆盖子窗口的DefWindowPro
c并从子窗口的DXUTStaticWndProc
调用DefWindowProc
之后,我能够使应用程序运行,调整大小,处理设备丢失并退出而不会崩溃,内存泄漏。这是通过将bHandleMessages
设置为false来完成的。但是,这会导致一个新问题:
Direct3D绘图表面比子窗口的区域小几个像素,从而在绘图表面周围留下了视频噪声的边界。即使bHandleMessages
为true,也不会发生这种情况,即使它在同一HWND
函数中的同一DXUTStaticWndProc
上运行也是如此。
更新2:看起来像素问题现在已经解决。使用从第一次更新到该问题的方案,我发现仅在CWnd::DefWindowProc
不返回0的情况下,才需要在子窗口的覆盖的DefWindowProc
中调用DXUTStaticWndProc
。因此,以下代码似乎可以解决该问题:
LRESULT ChildView::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam){
LRESULT lr = DXUTStaticWndProc(this->GetSafeHwnd(), message, wParam, lParam);
if(lr != 0) {
return CWnd::DefWindowProcW(message, wParam, lParam);
}
return lr;
}
我的另一个问题仍然存在,甚至值得使用DXUT库吗?使用DirectX可以对我造成什么限制?我是否应该回到管理所有Direct3D对象,设备设置/重置和手动渲染的状态?
最佳答案
我认为DXUT库是垃圾。我只是从中窃取所需的任何代码,然后将其直接插入到您的应用程序中,然后自由地应用重构。整个DXUT的哲学似乎是“即使在2009年,人们仍然认为对象很硬,因此我们将为1988年设置回溯机器,并使用全局函数对C语言的所有代码进行编码”。简直太糟糕了。