Hi all,
 
We're trying to write an application where we render an image to an OpenGL window.  When we do this all in the main program thread, all is fine, but when we try to call the drawing code in a thread (so as to allow the main thread to go back to processing UI events), the rendering code no longer works.  The code is shown below, along with instructions for switching between the single-threaded and multi-threaded versions.  Does anyone have any ideas about why this is happening or if there's another way we can achieve our goal?
 
Thanks,
 
Ali Omidvar
 
 
# Use this code as is to run the single-threaded version.  Hitting a key should
# cause a triangle to appear and move across the screen with every key press.
#
# To run the multi-threaded version, uncomment the lines starting with ## and
# comment out line 40 as indicated.  To revert to single-threaded, comment out
# all lines ending with ## and class MyDraw(Thread)
import wx
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
##from threading import Thread ##
from wx import glcanvas # why doesn't wx.glcanvas work?
class FPFrame( wx.Frame ):
   
    def __init__(self, parent, id, title):

        wx.Frame.__init__( self, parent, wx.ID_ANY, title, size = (400, 400),
                    style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
        self.panel = wx.Panel(self, -1, size=(200,200), style=wx.SIMPLE_BORDER)
       
        # when panel has focus, send character event to FPFrame handler OnChar
        wx.EVT_CHAR( self.panel, self.OnChar )
       
        self.Show( True )
        # do initial OpenGL scene rendering
        self.GLS = TestGLScene( self.panel )
       
##        self.myDraw = MyDraw(self) ##
    def OnChar(self,event):
       
        self.GLS.DrawGeometry()  # comment this out when switching to threaded version
##        if not self.myDraw.isAlive(): ##
##             self.myDraw = MyDraw( self ) ##
##             self.myDraw.start() ##         
 
##################################################3       
# comment this class out for the single-threaded version
##class MyDraw(Thread):
##   
##    def __init__(self, frame):
##        Thread.__init__( self )
##        self.frame=frame
##       
##    def run(self): 
##        self.frame.GLS.DrawGeometry( )

################################
class TestGLScene( glcanvas.GLCanvas ):
    def __init__( self, parent ):
        glcanvas.GLCanvas.__init__( self, parent, -1,size=(200,200) )
        self.i = 0
        dc = wx.ClientDC(self)
    def DrawGeometry( self ):
        self.SetCurrent() 
        # define the scene for OpenGl 
        glClearColor( 0.0, 0.0, 0.0, 1.0 )
        glClearDepth( 1.0 )
        glDepthFunc( GL_LESS )
        glEnable( GL_DEPTH_TEST )    
        glShadeModel( GL_SMOOTH )
        glMatrixMode( GL_PROJECTION )
        glLoadIdentity()     
        gluPerspective( 45.0, 1, 0.1, 100.0 )
        glMatrixMode( GL_MODELVIEW ) 
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
        glLoadIdentity()     
        glTranslatef( -1.5, 0.0, -6.0 )
        glClear( GL_COLOR_BUFFER_BIT )
        # draw a triangle with left corner at x
        GLDrawTriangle( self.i )
        self.i += 1
       
        self.SwapBuffers()
        print 'Swapped buffers'

# draw an equilateral triangle with left corner at (x,0,0)
def GLDrawTriangle( x ):
    print x
    V = [ [ x, 0, 0 ], [ x+2, 0, 0 ], [x+1, 1, 0 ] ]
    GLDrawVertices( V )
   
#draw a polygon with the points in the V
def GLDrawVertices( V ):
    glBegin( GL_POLYGON )
    for item in V:
        glVertex3f( item[0], item[1], item[2] )
    glEnd()
    print "Drew vertices" # this gets called when running multithreaded, but
                          # drawing does not happen

app = wx.PySimpleApp()
frame = FPFrame(None, -1, "Localizer Display")
app.MainLoop()


Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!