In my opinion, you will be happier just using one thread for all the OpenGL
stuff, and never deviating from that.

However, if you wanna know more details... you are only supposed to use one
thread per GL context. The basic reason why is that when using the same
context, 2 threads may interleave various stateful calls - like glGetError,
or immediate mode calls, or popmatrix pushmatrix stuff. So if 2 threads were
working without communicating, basically everything you are doing can get
messed up in every way possible depending on timing, making it a testing
nightmare. But even if you are careful and do locking and state management
and all that, because multiple threads using the same context is not a very
common use case it's poorly tested, you can expect various drivers and
implementations to behave poorly in different ways as well (my xp machine
for instance used to segfault whenever I'd try to call functions to read
pixels from textures from a second thread created by the first thread
because it would mess up texture sizes, no matter what the first thread was
doing at the time of the call - while my current machine seems to be fine
with that call, but has problems with deleting textures from different
threads)

If you wanted to try to pursue multiple contexts, I'm not sure if you would
still have driver support issues (again it's rarely used therefore rarely
tested). Also, I'm not aware of a way to tell PyOpenGL which GL context you
want to draw with, or how to make multiple opengl contexts for PyOpenGL to
use, but the pyOpenGL list can probably help you with that.

On the bright side, I think every platform has a call for binding the
context to a thread, and I'm 99% sure that the thread bindings to contexts
sticks to the thread exactly the way you'd hope. (see
<http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glx/xmakecurrent.html>glXMakeCurrent,
wglMakeCurrent or aglSetCurrentControl), and you should be able to set up
contexts to draw to the same window, no problem (on Windows you need two
HDC's to the same HWND to make 2 gl contexts, but _is_ supposed to be
officially supported...)

In terms of getting parallelization without breaking the one thread per
context rule or without multiple contexts, you could set up some kind of
"queue" of stuff to load into video memory that your from-disk loader thread
adds images into as it loads them, and then your gl drawing thread can load
them lazily at it's pace. That way you still get the CPU/Memory with Disk
parallelization which is almost always the biggest paralellization benefit
you can get.


On Tue, May 12, 2009 at 12:22 PM, Zack Schilling
<zack.schill...@gmail.com>wrote:

> I want to dynamically load levels for my game in python. I use OpenGL for
> drawing, mostly display lists. I want to spawn a low-priority thread that
> can create a new level object and activate its load method. The load method
> takes up to 5 seconds to run. It is loading images with pygame, splitting
> them up, generating large numpy arrays, binding textures, and building
> display lists. I know that if I simply create a thread and tell it to go
> without any modification, the OpenGL calls building the display lists in the
> loading thread will overlap with normal display code and cause strange,
> flickery drawing (not to mention ruining the level being loaded).
>
> What's the best option here? Can a thread lock block the main program's
> execution? Because that's where the drawing code is. Is there a way to set
> up PyOpenGL so that OpenGL knows to separate the two different voices
> talking to it (but still throw everything into the same context)?
>
> This game is a fun project for me, but I also expect to plow my way though
> some advanced programming techniques, so don't hold back suggestions for the
> sake of complexity.
>
> Thanks,
>
> Zack
>

Reply via email to