Я экспериментирую с идеей встроить игру в редактор и использовать интерфейс, чтобы они могли общаться друг с другом. Все идет хорошо, за исключением того факта, что теперь я должен сделать пользовательский игровой цикл, когда игра закреплена в редакторе.
Игра представляет собой консольное приложение Windows и использует OpenTK.
- Когда игра запускается сама по себе (как отдельное приложение), OpenTK создает
GameWindow
, который обрабатывает свой игровой цикл внутри себя (вы вызываете window.Run(updateSpeed, renderSpeed)
, и он запускает цикл, все еще опрашивая и обрабатываяоконные сообщения в процессе. - Когда игра запускается редактором, игра получает ссылку на редактор
GLControl
и обрабатывает различные события из элемента управления.
Редактор - это отдельный проект в том же решении, это приложение WPF, использующее WindowsFormsHost
, содержащее GLControl
для игры, которому принадлежит пространство в окне, рядом с панелями для различных элементов управления редактора.
Проблема в том, что мне нужно иметь возможность запускать игровой цикл из самой игры, и чтобы этот цикл мог рендериться с использованием OpenGL. о концепциях потоков / задач, но я также знаю, что контексты OpenGL не работают в потоках. Итак, если я запустлю стандартный цикл в игре (при запуске в редакторе), цикл заблокирует редактор и заблокирует все окно. Я не могу создать асинхронный цикл, потому что тогда он не может вызвать функцию рендеринга, так как контекст GL не установлен в этом потоке, поэтому он вызывает:
AccessViolationException
... как только будут сделаны какие-либо вызовы GL (например, очистка цветового буфера).
С точки зрения того, как все это работает в коде, класс игры имеет некоторые частные переменные, которыеопределить, встроен ли он в редактор. При нормальном запуске это false / null, и игра создает окно и работает нормально (все работает нормально). При запуске редактора редактор инициализирует GLControl
, а затем вызывает функцию в игре, которая устанавливает ссылки и сообщает игре, что она находится в редакторе. Затем, как только все компоненты WPF инициализированы, кнопка «play» вызывает функцию Run()
игры (это та же функция, которая вызывается точкой входа при запуске в качестве автономного приложения; она просто решает, что делать, основываясь на условиипеременных редактора, не являющихся ложными / нулевыми). Редактор WPF также имеет кнопку «Стоп», которая вызывает функцию игры Shutdown()
. Я бы хотел потенциально реализовать способ горячей перезагрузки кода игры с работающим редактором, в конце концов (возможно, я сделаю игру DLL и загрузлю ее таким образом - это не очень важно, верносейчас, а может и не произойти, зависит от того, действительно ли это возможно, не стесняйтесь вникнуть в это, если считаете, что это возможно). Как только игра запущена, она должна иметь возможность обновлять и рендерить (желательно на разных скоростях - мне нужно, чтобы обновление происходило 30 раз в секунду и рендерилось 60 раз в секунду (конечно, в конечном итоге это будет учитывать V-Sync))), без блокировки интерфейса редактора.
Как я могу это сделать? Я предполагаю, что потоки будут абсолютной необходимостью, поэтому мне нужен способ доступа к контексту GL из отдельного потока (предположительно). Любая помощь будет принята с благодарностью. Если кому-то нужен код, скажите мне, какие части вам нужны, поскольку их довольно много, и я не думаю, что размещать все это здесь было бы хорошей идеей. Надеюсь, вам это не понадобится, так как здесь описана настройка проекта, и в настоящее время сама игра не состоит из большого количества;пока он просто визуализирует белый квад в середине окна просмотра, пока я не перенесу свой код из более старой версии проекта;но сначала мне нужно получить основы и запустить).