Многопоточность приложения OpenGL / WinAPI - PullRequest
0 голосов
/ 24 октября 2010

ПРИМЕЧАНИЕ: Пожалуйста, прочитайте все перед публикацией, вы поймете, почему.

Итак, у меня есть приложение OpenGL / WinAPI. Я делаю то, что вы ожидаете, делая циклы обработки сообщений, затем рендеринга фрейма, обработки сообщений, рендеринга фрейма ...

Проблема в том, что когда я изменяю размер или перемещаю окно, экран зависает, и это может выглядеть довольно некрасиво. Я знаю по предыдущим истечениям с OpenGL, что ограничение количества сообщений, обрабатываемых между кадрами (по количеству или по времени), помогает. Кажется, что Windows блокирует мое приложение всякий раз, когда оно перемещает / изменяет размер окна. Из опыта я знаю, что помещение обработки сообщений Windows в другой поток и забывание об этом работает довольно хорошо, а также помогает с синхронизацией.

Мой вопрос таков: есть ли лучший, менее разрушительный или нетронутый способ сделать это? Есть ли недостаток в том, что я делаю (кроме многопоточных драм). Я хотел бы знать, можно ли избежать многопоточности.

Ответы [ 2 ]

3 голосов
/ 24 октября 2010

Когда пользователь нажимает на не клиентские области окна, чтобы переместить или изменить размер окна, DefwindowProc входит в модальный цикл, поэтому ваш игровой цикл больше не выполняется - пока пользователь не отменит или не завершит модальную операцию.

Существуют оконные сообщения, которые вы можете использовать для определения начала и конца модальных операций: например, WM_ENTERSIZEMOVE .

Суть вопроса в том, если ваше окно OpenGLне полноэкранный, или он отображает окна сообщений, тогда вы не можете полагаться на простой игровой цикл, чтобы продолжить рендеринг игры - вам нужно переключиться на рендерер на основе таймера.

SetTimer можно создатьтаймер, который доставит WM_TIMER сообщений, даже когда выполняются модальные операции.

PS.Примечание о многопоточности: контексты OpenGL не являются поточно-ориентированными, и доступ к ним должен быть сериализован (вручную по пользовательскому коду), если контекст является общим для потоков.Даже если используется несколько контекстов, доступ к фактическому устройству также сериализуется, поэтому выигрыш в производительности от многопоточности рендерера на основе OpenGL получить нельзя - если (как ни странно) вы не выполняете большую нагрузку на процессор (а затем что-то вроде OpenMP)Распараллеливание циклов помогло бы больше, чем попытка создать диспетчер заданий многопоточного рендеринга более высокого уровня).В основном: придерживайтесь однопоточного рендерера с OpenGL - он будет работать лучше, чем почти любая попытка многопоточности, и будет гораздо более предсказуемым для

PPS.Для оконных приложений OpenGL, вероятно, также лучше отказаться от традиционного подхода игрового цикла при рендеринге каждого кадра и полагаться на RedrawWindow для отправки WM_PAINT сообщений в окно: рисование внутри блока BeginPaint/EndPaintозначает, что поведение рендеринга ваших приложений намного более предсказуемо, и процесс DesktopWindowManager может справиться со своей задачей применения эффектов «аэростекла» и гораздо более эффективной реализации обновлений рабочего стола с помощью vsync.

0 голосов
/ 25 октября 2010

Одна идея в качестве обходного пути: визуализация в FBO, вставка FBO в окно для каждого сообщения изменения размера (потенциально его масштабирование) и повторная визуализация FBO с надлежащим разрешением, когда очередь сообщений пуста.

Таким образом, вы получаете предсказуемые перерисовки с небольшими артефактами и отсутствием потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...