简体   繁体   中英

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

Ok so I've spent an embarrassing amount of time on this problem and still am fairly confused. I'm hoping someone can provide some guidance, resources, similar projects, etc. I am unsure that what I am doing is the right way to go about this problem.

Background:

I am working on a project where I am developing an imitation of rocket league (a video game) so that I can run reinforcement learning algorithms on the game (I can't run the game itself because it would be too slow). The imitation needs to comply with OpenAI Gym's API, which essentially demands a step method (which takes in the actions the AI determines necessary at that timestep and outputs the state of the game after the timestep), and a render method. I have enough of the game implemented that I am currently working on the render method. I want to package this and release it on pypi, so I chose pyglet to implement the graphics because I read it is fairly portable.

Problem:

I don't think I can use an event loop to run my graphics. The way this api is set-up and used is that the user first instantiates the environment (the video game) and then sets up a loop in which they run the step function of the environment and optionally choose to also place the render method in that same loop depending on whether or not they want to see their AI's actions during that run. An example usage is available under environments on this page . So I can't use an event loop because it would stop execution of the user's loop. Instead I need to instantiate a window on the first call of render, and then update it with the state of the game on every subsequent call.

My current solution:

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

Problem cont:

My current solution feels a bit hacky which I don't love, but more of a problem is that I can't figure out how to implement user input for this solution. I would like to be able to pan and move the camera all around the scene so that I view the 3-dimensional shape of objects, but I don't know how to implement that without the event loop and on_key_press decorator.

Also:

I am struggling to find good resources for 3d programming with OpenGL functions (the game is 3d). I was wondering if anyone knew of a good place to learn that without all complexity I found on https://learnopengl.com/ . I don't even know if pyglet/opengl is the right way to go about solving this problem. I know very little about 3d graphics and am open to any suggestions.

So for anyone with a similar problem looking for the solution, here is what I determined:

If you need to render events but not give up control flow to pyglet.app.run() or any other event loop, custom or otherwise, it is possible to still listen for user actions. The following code is an example pseudo-implementation for a class that renders its state each time the render() function is called, with user input optionally changing that state. Be warned that this is far optimal from an efficiency perspective, and you should always use pyglet.app.run() when possible, but this instance demanded an alternative solution.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM