Использование opengl в pyglet для рендеринга трехмерной сцены без цикла событий - PullRequest
0 голосов
/ 15 апреля 2020

Хорошо, поэтому я потратил смущающее количество времени на эту проблему и все еще в замешательстве. Я надеюсь, что кто-то может предоставить некоторые рекомендации, ресурсы, аналогичные проекты и т. Д. c. Я не уверен, что то, что я делаю, является правильным способом go об этой проблеме.

Справочная информация:

Я работаю над проектом, в котором я разрабатываю имитацию ракетной лиги ( видеоигры), чтобы я мог использовать в игре алгоритмы обучения с подкреплением (я не могу запустить саму игру, потому что она будет слишком медленной). Имитация должна соответствовать API-интерфейсу OpenAI Gym, который, по сути, требует пошагового метода (который выполняет действия, которые AI определяет необходимыми на этом временном шаге, и выводит состояние игры после временного шага) и метода рендеринга. У меня достаточно реализованной игры, и я сейчас работаю над методом рендеринга. Я хочу упаковать это и выпустить на pypi, поэтому я выбрал pyglet для реализации графики, потому что я читал, что она довольно переносимая.

Проблема:

Не думаю, что смогу использовать событие l oop для запуска моей графики. Способ настройки и использования этого API-интерфейса заключается в том, что пользователь сначала создает экземпляр среды (видеоигры), а затем настраивает al oop, в котором он запускает пошаговую функцию среды и, при желании, также выбирает метод рендеринга. в том же l oop в зависимости от того, хотят ли они видеть действия своего ИИ во время этого запуска. Пример использования доступен в средах на этой странице . Поэтому я не могу использовать событие l oop, потому что оно остановит выполнение пользователя l oop. Вместо этого мне нужно создать экземпляр окна при первом вызове рендера, а затем обновлять его, указав состояние игры при каждом последующем вызове.

Мое текущее решение:

    def render():
        if self.window is None:
            self.window = pyglet.window.Window(width, height)
        self.window.clear()
        self.window.dispatch_events()
          ... describe current 3d scence
        self.window.flip()

Проблема продолжения :

Мое текущее решение кажется немного хакерским, что мне не нравится, но большая проблема в том, что я не могу понять, как реализовать пользовательский ввод для этого решения. Я хотел бы иметь возможность панорамирования и перемещения камеры по всей сцене, чтобы я мог видеть трехмерную форму объектов, но я не знаю, как реализовать это без события l oop и декоратора on_key_press.

Также:

Я изо всех сил пытаюсь найти хорошие ресурсы для 3D-программирования с функциями OpenGL (игра 3D). Мне было интересно, если бы кто-нибудь знал о хорошем месте, чтобы узнать, что без всякой сложности я нашел на https://learnopengl.com/. Я даже не знаю, является ли pyglet / opengl правильным решением go для решения этой проблемы. Я очень мало знаю о 3D-графике и открыт для любых предложений.

1 Ответ

0 голосов
/ 16 апреля 2020

Так что для тех, у кого похожая проблема ищет решение, вот что я определил:

Если вам нужно визуализировать события, но не отдавать поток управления pyglet.app.run () или любому другому Событие l oop, пользовательское или иное, можно все же прослушивать действия пользователя Следующий код является примером псевдо-реализации для класса, который отображает свое состояние каждый раз, когда вызывается функция render (), при этом пользовательский ввод может изменять это состояние. Имейте в виду, что это далеко не оптимально с точки зрения эффективности, и вы всегда должны использовать pyglet.app.run (), когда это возможно, но этот экземпляр требует альтернативного решения.

class Env:
    # ...lots of other class stuff
    def render(self):
        if self.window is None:
            self.window = pyglet.window.Window(width, height)

            @self.window.event
            def on_close():
                self.window.close()

            @self.window.event
            def on_key_press(key, mod):
                # ...do stuff on key press

        pyglet.clock.tick()
        self.window.clear()
        self.window.dispatch_events()

        # ...transform, update, create all objects that need to be rendered

        self.window.flip()


env = Env()
for _ in range(100):
    env.doStuff()
    env.render()
...