在pyglet中使用opengl渲染没有事件循环的3d场景

Using opengl in pyglet to render 3d scene without event loop

好吧,我在这个问题上花了很多时间,但仍然很困惑。我希望有人可以提供一些指导、资源、类似项目等。我不确定我正在做的是解决这个问题的正确方法。

背景:

我正在做一个项目,我正在开发一个模拟火箭联盟(视频游戏)的游戏,这样我就可以 运行 在游戏中使用强化学习算法(我不能 运行游戏本身,因为它太慢了)。模仿需要遵守 OpenAI Gym 的 API,它本质上需要一个 step 方法(它接受 AI 在该时间步确定必要的动作,并在该时间步之后输出游戏状态)和一个渲染方法。我已经实现了足够的游戏,我目前正在研究渲染方法。我想把这个打包发布到pypi上,所以我选择了pyglet来实现图形,因为我看它是相当便携的。

问题:

我不认为我可以使用事件循环来 运行 我的图形。这个 api 的设置和使用方式是,用户首先实例化环境(视频游戏),然后设置一个循环,在这个循环中,他们 运行 环境的步进函数,并可选择选择还将渲染方法放在同一个循环中,具体取决于他们是否想在 运行 期间看到他们的 AI 的动作。此 page 上的环境下提供了示例用法。所以我不能使用事件循环,因为它会停止执行用户循环。相反,我需要在第一次调用渲染时实例化一个 window,然后在每次后续调用时用游戏状态更新它。

我目前的解决方案:

    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()

问题续:

我目前的解决方案感觉有点老套,我不喜欢,但更多的问题是我不知道如何为这个解决方案实现用户输入。我希望能够在场景周围平移和移动相机,以便查看对象的 3 维形状,但我不知道如何在没有事件循环和 on_key_press 装饰器的情况下实现它。

另外:

我正在努力寻找使用 OpenGL 函数进行 3d 编程的好资源(游戏是 3d)。我想知道是否有人知道一个学习这个的好地方,而不需要我在 https://learnopengl.com/ 上发现的所有复杂性。我什至不知道 pyglet/opengl 是否是解决这个问题的正确方法。我对 3d 图形知之甚少,愿意接受任何建议。

所以对于任何有类似问题寻找解决方案的人,这是我确定的:

如果您需要呈现事件但不放弃对 pyglet.app.run() 或任何其他事件循环(自定义或其他)的控制流,仍然可以监听用户操作。以下代码是 class 的示例伪实现,它在每次调用 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()