我正在尝试关闭我的 DX12 渲染器,然后在同一进程中重新启动它。
所述应用程序很大程度上基于 microsoft MiniEngine 示例代码,现在进行了一些修改以允许重新初始化全局变量。我正在使用 SDL 进行窗口和事件管理。
看来,彻底关闭和重新初始化的最后一个绊脚石是在纹理管理器类中加载纹理,而后者又使用代码DirectXTK12
通过文件加载纹理。CreateWICTextureFromFileEx
.png
总结一下我正在尝试做的事情:
启动应用程序
初始化渲染到 SDL 窗口
在渲染循环中渲染
关闭所有渲染和窗口处理(移除所有资源,释放设备句柄) - 调用
SDL_Quit
重新初始化渲染到新的 SDL 窗口(获取新的设备句柄等)
在渲染循环中渲染
纹理管理类作为渲染关闭的一部分被关闭,删除所有纹理痕迹及其对资源的句柄等。
作为渲染重新初始化的一部分,默认纹理是通过CreateWICTextureFromFileEx
. (请参阅此处)并在尝试执行此操作时崩溃。
编辑:自从第一次发布以来,我可以说这种崩溃在调用后直接开始SDL_Quit()
(并且在调用重启后仍然存在SDL_Init(SDL_INIT_VIDEO)
)
我现在相当有信心这是这个区域的问题,而不是渲染器的其他部分没有正确重新初始化,因为我可以强制它使用.DDS
纹理而不是.png
s,并且系统再次很好地启动。在这种情况下,它使用DDSTextureLoader
没有任何(明显的)问题。
我已将源代码添加到我的项目中,并且在尝试执行此操作时可以看到崩溃发生:
ComPtr<IWICBitmapDecoder> decoder;
HRESULT hr = pWIC->CreateDecoderFromFilename(fileName,
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnDemand,
decoder.GetAddressOf());
报告的失败是
Unhandled exception thrown: read access violation.
pWIC->**** was 0x7FFAC0B0C610.
pWIC
这里是通过_GetWIC()
使用单例初始化获得的:
IWICImagingFactory2* _GetWIC() noexcept
{
static INIT_ONCE s_initOnce = INIT_ONCE_STATIC_INIT;
IWICImagingFactory2* factory = nullptr;
if (!InitOnceExecuteOnce(
&s_initOnce,
InitializeWICFactory,
nullptr,
reinterpret_cast<LPVOID*>(&factory)))
{
return nullptr;
}
return factory;
}
自从第一次发帖以来,我现在可以说这个崩溃是在调用SDL_Quit()
. 我有测试代码足以启动图形以获取设备并获取纹理,这将在任何时候成功完成,直到SDL_Quit
. 重新初始化 SDLSDL_Init(SDL_INIT_VIDEO)
并没有帮助。
我还注意到WICTextureLoader
评论状态“假设应用程序已经调用了 CoInitializeEx”。这是一个SDL_Quit
可以搞砸的领域吗?