2016-05-31 12 views
1

Во время разработки моего движка я пытаюсь реализовать функцию, которая позволяет осуществлять горячую замену между OpenGL и DirectX. В настоящее время я тестирую на платформе Win32 и столкнулся со следующей проблемой:DirectX to OpenGL hot-swap, не отображается в окне Win32

Я реализовал оба средства визуализации (OpenGL 3.0 и Direct3D11), оба работают отлично в одиночку. Механизм замены:

Уничтожьте текущий контекст рендеринга и создайте новый. Например: Отпустите все объекты DirectX, а затем создайте контекст OpenGL через WGL. Я пытаюсь реализовать это, используя только одно окно (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 рендеринга вызовы выполняются, как ожидается, к примеру:

  1. OpenGL рендеринга с 150 кадров в секунду
  2. Переключить DirectX, рендер с 60 кадров в секунду (ВСИНХ)
  3. своп обратно в OpenGL, рендеринг снова с 150 fps (не более)

Существуют и другие сценарии, в которых OpenGL отображает более 150 кадров в секунду, поэтому вызовы рендеринга выполняются должным образом.

Я предполагаю, что перелистывание буферов не работает, но SwapBuffers возвращает TRUE в любом случае.

Я попытался использовать SaveDC и RestoreDC до и после использования DirectX, в результате получилось решение.

Использование wglSwapLayerBuffers вместо SwapBuffers не дает никаких изменений.

Могу ли я каким-то образом восстановить HWND или HDC в исходное состояние, или вы, ребята, не знаете, почему это может произойти?

ответ

0

Угадайте, что я отправил свой вопрос в ближайшее время, но, тем не менее, так я и решил.

я вырыл вокруг documnentation для 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

Edit: я нашел this вопрос после того, как некоторое время. Если у кого-то еще есть идея, как вернуться к использованию GDI снова вместо DWM backbuffer, это очень ценится.

 Смежные вопросы

  • Нет связанных вопросов^_^