Thread: [PyOpenGL-Users] glutSetWindow in a thread segfaults
Brought to you by:
mcfletch
From: U. T. <afr...@go...> - 2008-06-15 15:45:01
|
Hi people, We are working on a small program using pyode and pyopengl to simulate a very simple robot. Nearly all the modelling is finished, and the last thing left is a virtual camera that takes a snapshot of the field of view of the robot. A class called display handles visualization and the virtual camera. This class is in a thread of its own. Our program has two windows; one displays the complete simulation environment, the other displays the viewpoint of the camera. In order to save what is in the camera window as an image, we do the following: def capture(self, path): self.draw_lock.acquire() glutSetWindow(self.subwindow) glPixelStorei(GL_PACK_ALIGNMENT, 1) data = glReadPixelsub(0, 0, self.subwindow_width, self.subwindow_height, GL_RGB) image = Image.fromstring( 'RGB', (int(self.subwindow_width),int(self.subwindow_height)), data ) image = image.transpose( Image.FLIP_TOP_BOTTOM) image.save(path) self.draw_lock.release() return True The Image object is from PIL. As you can see, thread locks are necessary to stop the display functions from changing the displays; otherwise, an OpenGL error is thrown. When this routine is called from the display class of which it is a member, there are no errors; the image is saved in the given path. When it is called from outside the thread, however, glutSetWindow causes a segmentation fault. This happens not each and every time but most of the time, which puzzled me even more. Before we put in locks for the drawing functions, segfaults and OpenGL errors would each happen. I am suspecting that there is another resource which has to be locked, but no idea what and how. Any ideas what the reason might be, or how to find a workaround? Cheers, Ulas |
From: Mike C. F. <mcf...@vr...> - 2008-06-15 19:13:22
|
Ulas Türkmen wrote: ... > The Image object is from PIL. As you can see, thread locks are > necessary to stop the display functions from changing the displays; > otherwise, an OpenGL error is thrown. > > When this routine is called from the display class of which it is a > member, there are no errors; the image is saved in the given path. > When it is called from outside the thread, however, glutSetWindow > causes a segmentation fault. This happens not each and every time but > most of the time, which puzzled me even more. Before we put in locks > for the drawing functions, segfaults and OpenGL errors would each > happen. > I would have been surprised had it worked, actually. Most GUI libraries are inherently non-thread-safe and will mess up rather badly when you try to call functions from another thread. Normally you get around this by having a queue of tasks to accomplish in the GUI thread and adding your operation to that queue. The GUI thread checks the queue (non-blocking) and executes the operations when it is in a stable state, returning the result on another queue that you (the client code) wait on (blocking). Not to say you *couldn't* make it work with enough locks and the like, but I'd be tempted to go with an "all GUI code in one thread" approach for stability. HTH, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com |