Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance #12

Open
traverseda opened this issue Apr 9, 2016 · 10 comments
Open

Improve performance #12

traverseda opened this issue Apr 9, 2016 · 10 comments

Comments

@traverseda
Copy link
Owner

No description provided.

@traverseda
Copy link
Owner Author

I doubt the problem is opengl. So the first step should be profiling.

@traverseda
Copy link
Owner Author

<@traverseda> I doubt the speed problems are openGL. We're not rending a complex scene. Reducing number of objects probably isn't going to help
<@traverseda> It might be pyglet related, in which case, fuck.
<@Nitori> hm... the update method takes like 0.0003 seconds
<@Nitori> hmhm, pyglet calls the window.update method repeatedly, right? the wohle method and all the python stuff takes like 0.0003 seconds, but from update call to update call (meaning the part that pyglet does) it takes around 0.1-0.2 seconds
<@Nitori> but I don't know anything of that stuff
<@traverseda> I'm presuming it's stuff like checking what blocks are visable, or re-calculating the current sectors
<@traverseda> Or the collision detection
<@Nitori> isn't that done in main.py?
<@Nitori> that's all part of the update and _update method afaik
<@Nitori> which takes less than a millisecond
<@traverseda> Hmm, weird
<@Nitori> maybe research into other libs like PySDL2 might be good?
<@Nitori> or maybe just read the pyglet docs for now
<@traverseda> Nitori, yeah, I was thinking about things along those lines. Also the possibility of having this project essentially just be a "server" and to write a 3D client in golang. For now even the slow stuff lets people immediatly see the results of their effors, though.
<@Nitori> hm yea
<@traverseda> I set the tickrate to 600 (on my shitty arm chromebook) and performance seems a lot better. I think there's something wrong with pyglets clock.

@traverseda
Copy link
Owner Author

In hindsight, I'm not certain about that tickrate thing. It goes up a bit, but I'm nearing max CPU anyway.

@syegulalp
Copy link

On my own pyglet-related projects, I had to patch out part of the idle method to keep it from calling update repeatedly, and that helped performance quite a bit. Here's what I did (I found this code elsewhere:)

import pyglet
# Patch for pyglet idle loop
def patch_idle_loop():
    def idle(self):
        self.clock.call_scheduled_functions(self.clock.update_time())
        return self.clock.get_sleep_time(True)
    if pyglet.app.EventLoop.idle != idle:
        pyglet.app.EventLoop.idle = idle

# Window patch for OpenGL
def patch_window_for_opengl_core():
    def draw_mouse_cursor(self):
        pass
    pyglet.window.BaseWindow.draw_mouse_cursor = draw_mouse_cursor

patch_idle_loop()
patch_window_for_opengl_core()

Also don't forget that if you don't run any Pyglet application with the -O or -OO switches passed to the Python interpreter, it starts in debug mode by default, another performance killer.

@syegulalp
Copy link

Also note that if you use this, you have to write some event-loop functions yourself. Example:

import pyglet

#assume the above patch goes here...

import random

w = pyglet.window.Window()
b = pyglet.graphics.Batch()

l = pyglet.text.Label("abc", font_size=w.height,
                          batch=b,
                          x=w.width/2, y=w.height/2,
                          anchor_x="center", anchor_y="center")

def update(n):
    w.dispatch_events()
    w.clear()
    b.draw()
    w.flip()

pyglet.clock.schedule_interval(update,1/60)
pyglet.app.run()

@traverseda
Copy link
Owner Author

Might make sense to use python3.5's async loop. Now sure how that would interact with pyglet's event parsing stuff.

http://www.curiousefficiency.org/posts/2015/07/asyncio-background-calls.html

@tartley
Copy link

tartley commented Apr 21, 2016

I've written pyglet/OpenGL projects before, using Pyglet's own event loop, that drew hundreds of separate OpenGL meshes, with independent positions and orientations for each, at 60fps or better on very old/modest hardware. I don't think your problem is fundamentally due to Pyglet's event loop.

The '-O' or '-OO' flags (mentioned in a prevoious comment) are CRITICAL for good performance.

@tartley
Copy link

tartley commented Apr 21, 2016

Wild speculation: If you are re-creating the vertices and sending them over to OpenGL every frame, that is very slow. Creating the contiguous arrays of vertex data in memory is slow, then sending that data over to the GPU is slow. You need to create your mesh(es) once, then send them over to OpenGL on startup (using VAO/VBOs) and then each frame, request that OpenGL render each mesh, by passing in integer handles to identify the mesh (rather than re-sending the mesh vertex data.)

If meshes get modified while running (which presumably they do, when blocks are added or removed) then perhaps instead of regenerating a mesh for the whole world every time a block is added or removed, you need to split the world into a number of meshes (e.g. maybe one for every 16x16 column of the world) and regen just the modified mesh.

@syegulalp
Copy link

syegulalp commented Apr 21, 2016

@tartley In my case I think I was experiencing problems w/Pyglet triggered into doing a full repaint outside of the event loop, and I didn't need repaints more than every 1/60th of a second. Hence my loop patch. But yes, -O or -OO is vital, and many people don't know it.

BTW, am following the Gloopy project, love the idea!

@tartley
Copy link

tartley commented Apr 21, 2016

Fair enough, I shall staunch my uninformed speculations. Love what you folks are doing here, too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants