在我的引擎开发期间,我正在尝试实现一个功能,它可以在OpenGL和DirectX之间进行热交换。目前我正在Win32平台上测试,并遇到了以下问题:
我实现了渲染器(OpenGL 3.0和Direct3D11),两者都很好。交换机制如下:
销毁当前渲染上下文,并构建新的上下文。例如:释放所有DirectX对象,然后通过WGL创建OpenGL上下文。我正在尝试使用一个窗口(HWND)来实现它。
从OpenGL 3.0交换到DirectX11可以正常工作。 (在销毁OpenGL之后,DirectX渲染得很好)
销毁OpenGL,然后再次重新创建OpenGL,有效。与DirectX相同。
当我尝试从DirectX切换到OpenGL时,窗口将停止显示新绘制的内容,只显示最后绘制的DirectX帧。
构建OpenGL上下文我正在使用WGL。窗口的类是使用CS_OWNDC
样式创建的。我正在使用SwapBuffers
翻转窗口缓冲区。在设置上下文之前,我使用SetPixelFormat
与先前从ChoosePixelFormat
返回的值。创建的上下文是3.0版,通过wglCreateContextAttribsARB
确保。
其他信息:
释放所有DirectX引用,通过调用ReportLiveDeviceObjects
并检查ID3D11Device1::Release
(0)的返回值来检查。调用了ID3D11DeviceContext1::ClearState
和Flush
来确保对象被破坏。
没有一个OpenGL方法通过glGetError
报告错误,每次调用后都会检查此错误。对于所有操作系统和WGL调用都是一样的。
OpenGL渲染调用正在按预期执行,例如:
还有其他场景,OpenGL以超过150 fps的速度渲染,因此渲染调用正在正确执行。
我的猜测是缓冲区的翻转无法以某种方式起作用,但无论如何SwapBuffers
都会返回TRUE
。
我尝试在使用DirectX之前和之后使用SaveDC
和RestoreDC
,这导致了现在的解决方案。
使用wglSwapLayerBuffers
代替SwapBuffers
不会发生任何变化。
我可以以某种方式将HWND或HDC恢复到原始状态,或者您是否知道为什么会发生这种情况?
答案 0 :(得分:1)
猜猜我很快就发布了我的问题,但是,这就是我解决它的方法。
我挖掘了DirectX的文档,对于函数CreateSwapChainForHwnd
,我发现了以下内容:
因为您一次只能将一个翻转演示模型交换链与HWND关联,所以如果您尝试销毁翻转演示模型交换链并将其替换为对象,则推迟销毁对象的Microsoft Direct3D 11策略可能会导致问题另一个交换链。
我在交换链描述符中使用DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
,这可能意味着DirectX为窗口设置了一个翻转交换链,但是当我尝试将它与OpenGL一起使用时,它将无法以某种方式交换缓冲区
解决方法是不使用FLIP
模式创建交换链:
DXGI_SWAP_CHAIN_DESC1 scd;
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scd.Scaling = DXGI_SCALING_ASPECT_RATIO_STRETCH;
您必须将Scaling
设置为DXGI_SCALING_NONE
之外的其他内容,否则创建将失败。
有趣的是,DirectX仍然没有正确破坏窗口上的翻转模型,尽管我做了文档中提出的所有内容(ClearState
和Flush
调用)。
CreateSwapChainForHwnd
see Remarks
编辑:过了一段时间后我发现了this个问题。如果有人仍然有一些想法,如何再次使用GDI而不是DWM后备缓冲器,我们非常感激。