2016-05-31 28 views
1

在我的引擎开发过程中,我试图实现一个功能,可以实现OpenGL和DirectX之间的热插拔。目前我在Win32平台上测试,遇到以下问题:DirectX到OpenGL的热插拔,不会显示在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::ClearStateFlush以确保对象被破坏。

没有一个OpenGL方法通过glGetError报告错误,每次调用后都会检查这个错误。这对所有操作系统和WGL调用都是一样的。

OpenGL的渲染调用执行如预期,例如:

  1. 的OpenGL用150 fps的渲染
  2. 交换到DirectX,渲染60帧(VSYNC)
  3. 交换回OpenGL中,渲染再次以150 fps(不多于)

还有其他场景,其中OpenGL渲染超过150帧/秒,所以渲染调用正常执行。

我的猜测是缓冲区的翻转并不起作用,但SwapBuffers无论如何返回TRUE

我在使用DirectX之前和之后尝试使用SaveDCRestoreDC,这导致了现在的解决方案。

使用wglSwapLayerBuffers而不是SwapBuffers没有改变。

我可以以某种方式恢复HWND或HDC到原始状态,或者你们有什么想法,为什么会发生这种情况?

回答

0

猜猜我很快发布了我的问题,但是,这是我如何解决它。

我周围挖了documnentation支持DirectX,并为功能CreateSwapChainForHwnd,我发现:

因为你只能一个翻手演示模型交换链在同一时间与HWND,微软的Direct3D关联如果您尝试销毁翻转演示文稿模型交换链并将其替换为另一个交换链,则推迟销毁对象的策略可能会导致问题。

我是用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仍然不能正确销毁窗口上的翻转模型,尽管我在文档(ClearStateFlush调用)中做了所有建议。

CreateSwapChainForHwnd see Remarks

编辑:我发现了一些时间后this问题。如果有人仍然有一些想法,如何恢复使用GDI而不是DWM backbuffer,这是非常感谢。