c++ - 为什么我在关闭 SDL 后无法使用 CreateWICTextureFromFileEx
问题描述
我正在尝试关闭我的 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
可以搞砸的领域吗?
解决方案
我会在这里发布一个答案,但如果@ChuckWalbourn 想要发布他自己的答案,我会删除它。
这是因为让 SDL 给CoInitialize
我打电话。
当它通过 清理时SDL_Quit
,它调用CoUninitialize
which 然后(大概)使IWICImagingFactory2
设置无效WICTextureLoader
。
通过CoInitialize
在我的渲染启动中添加一个调用,内部计数CoInitialize
保持IWICImagingFactory2
活跃,一切都很好。
推荐阅读
- javascript - 如何在 CesiumJS 中将 ClampToGround 设置为平面
- javascript - 已经由 CSS 设置的元素属性如何用 JS 更改?
- node.js - 如何在 Node.js REPL 模块中使用“--experimental-repl-await”命令行选项?
- web-applications - 从 CLI 将 Nuget 和依赖项部署到 Web 应用程序的 bin 文件夹
- flutter - 更改列表项取决于日期(颤振)
- r - R:如何解决分配空间的问题
- json - 如何使用打字稿在每个分组数组中获取第一条记录
- python-3.x - Logstash - 在 python 中通过 TCP 发生故障转移时将 Logstash 消息发送到另一台主机
- ios - 将applepay令牌交换为离子角度上的条带令牌[已解决]
- groovy - 使用 SecureASTCustomizer 从 groovy 中创建和删除限制等文件操作