SHARE
TWEET

pygletwx.py

a guest Apr 9th, 2011 401 Never
  1. import os
  2.  
  3. import wx
  4. from wx import glcanvas
  5.  
  6. import pyglet
  7. from pyglet import gl
  8.  
  9. class GLPanel(wx.Panel):
  10.  
  11.     '''A simple class for using OpenGL with wxPython.'''
  12.  
  13.     def __init__(self, parent, id, pos=wx.DefaultPosition,
  14.                  size=wx.DefaultSize, style=0):
  15.         # Forcing a no full repaint to stop flickering
  16.         style = style | wx.NO_FULL_REPAINT_ON_RESIZE
  17.         #call super function
  18.         super(GLPanel, self).__init__(parent, id, pos, size, style)
  19.  
  20.         #init gl canvas data
  21.         self.GLinitialized = False
  22.         attribList = (glcanvas.WX_GL_RGBA, # RGBA
  23.                       glcanvas.WX_GL_DOUBLEBUFFER, # Double Buffered
  24.                       glcanvas.WX_GL_DEPTH_SIZE, 32) # 24 bit
  25.         # Create the canvas
  26.         self.sizer = wx.BoxSizer(wx.HORIZONTAL)
  27.         self.canvas = glcanvas.GLCanvas(self, attribList=attribList)
  28.         self.sizer.Add(self.canvas, 1, wx.EXPAND)
  29.         self.SetSizer(self.sizer)
  30.         self.sizer.Fit(self)
  31.  
  32.         # bind events
  33.         self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent)
  34.         self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent)
  35.         self.canvas.Bind(wx.EVT_PAINT, self.processPaintEvent)
  36.        
  37.     #==========================================================================
  38.     # Canvas Proxy Methods
  39.     #==========================================================================
  40.     def GetGLExtents(self):
  41.         '''Get the extents of the OpenGL canvas.'''
  42.         return self.canvas.GetClientSize()
  43.  
  44.     def SwapBuffers(self):
  45.         '''Swap the OpenGL buffers.'''
  46.         self.canvas.SwapBuffers()
  47.  
  48.     #==========================================================================
  49.     # wxPython Window Handlers
  50.     #==========================================================================
  51.     def processEraseBackgroundEvent(self, event):
  52.         '''Process the erase background event.'''
  53.         pass # Do nothing, to avoid flashing on MSWin
  54.  
  55.     def processSizeEvent(self, event):
  56.         '''Process the resize event.'''
  57.         if self.canvas.GetContext():
  58.             # Make sure the frame is shown before calling SetCurrent.
  59.             self.Show()
  60.             self.canvas.SetCurrent()
  61.             size = self.GetGLExtents()
  62.             self.winsize = (size.width, size.height)
  63.             self.width, self.height = size.width, size.height
  64.             self.OnReshape(size.width, size.height)
  65.             self.canvas.Refresh(False)
  66.         event.Skip()
  67.  
  68.     def processPaintEvent(self, event):
  69.         '''Process the drawing event.'''
  70.         self.canvas.SetCurrent()
  71.  
  72.         # This is a 'perfect' time to initialize OpenGL ... only if we need to
  73.         if not self.GLinitialized:
  74.             self.OnInitGL()
  75.             self.GLinitialized = True
  76.  
  77.         self.OnDraw()
  78.         event.Skip()
  79.        
  80.     def Destroy(self):
  81.         #clean up the pyglet OpenGL context
  82.         self.pygletcontext.destroy()
  83.         #call the super method
  84.         super(wx.Panel, self).Destroy()
  85.  
  86.     #==========================================================================
  87.     # GLFrame OpenGL Event Handlers
  88.     #==========================================================================
  89.     def OnInitGL(self):
  90.         '''Initialize OpenGL for use in the window.'''
  91.         #create a pyglet context for this panel
  92.         self.pygletcontext = gl.Context(gl.current_context)
  93.         self.pygletcontext.set_current()
  94.         #normal gl init
  95.         gl.glEnable(gl.GL_BLEND)
  96.         gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
  97.         gl.glEnable(gl.GL_TEXTURE_2D)
  98.         gl.glShadeModel(gl.GL_SMOOTH)
  99.         gl.glClearColor(1, 1, 1, 1)
  100.        
  101.         #create objects to draw
  102.         self.create_objects()
  103.                                          
  104.     def OnReshape(self, width, height):
  105.         '''Reshape the OpenGL viewport based on the dimensions of the window.'''
  106.         gl.glViewport(0, 0, width, height)
  107.         gl.glMatrixMode(gl.GL_PROJECTION)
  108.         gl.glLoadIdentity()
  109.         gl.glOrtho(0, width, 0, height, 1, -1)
  110.         gl.glMatrixMode(gl.GL_MODELVIEW)
  111.         #pyglet stuff
  112.  
  113.         # Wrap text to the width of the window
  114.         if self.GLinitialized:
  115.             self.pygletcontext.set_current()
  116.             self.update_object_resize()
  117.            
  118.     def OnDraw(self, *args, **kwargs):
  119.         "Draw the window."
  120.         #clear the context
  121.         self.pygletcontext.set_current()
  122.         gl.glClear(gl.GL_COLOR_BUFFER_BIT|gl.GL_DEPTH_BUFFER_BIT)
  123.         #draw objects
  124.         self.draw_objects()
  125.         #update screen
  126.         self.SwapBuffers()
  127.            
  128.     #==========================================================================
  129.     # To be implamented by a sub class
  130.     #==========================================================================
  131.     def create_objects(self):
  132.         '''create opengl objects when opengl is initialized'''
  133.         pass
  134.        
  135.     def update_object_resize(self):
  136.         '''called when the window recieves only if opengl is initialized'''
  137.         pass
  138.        
  139.     def draw_objects(self):
  140.         '''called in the middle of ondraw after the buffer has been cleared'''
  141.         pass
  142.        
  143.        
  144. class TestGlPanel(GLPanel):
  145.    
  146.     def __init__(self, parent, id=wx.ID_ANY, pos=(10, 10)):
  147.         super(TestGlPanel, self).__init__(parent, id, wx.DefaultPosition, wx.DefaultSize, 0)
  148.         self.spritepos = pos
  149.        
  150.     def create_objects(self):
  151.         '''create opengl objects when opengl is initialized'''
  152.         FOO_IMAGE = pyglet.image.load('foo.png')
  153.         self.batch = pyglet.graphics.Batch()
  154.         self.sprite = pyglet.sprite.Sprite(FOO_IMAGE, batch=self.batch)
  155.         self.sprite.x = self.spritepos[0]
  156.         self.sprite.y = self.spritepos[1]
  157.         self.sprite2 = pyglet.sprite.Sprite(FOO_IMAGE, batch=self.batch)
  158.         self.sprite2.x = self.spritepos[0] + 100
  159.         self.sprite2.y = self.spritepos[1] + 200
  160.        
  161.     def update_object_resize(self):
  162.         '''called when the window recieves only if opengl is initialized'''
  163.         pass
  164.        
  165.     def draw_objects(self):
  166.         '''called in the middle of ondraw after the buffer has been cleared'''
  167.         self.batch.draw()
  168.    
  169. class TestFrame(wx.Frame):
  170.     '''A simple class for using OpenGL with wxPython.'''
  171.  
  172.     def __init__(self, parent, id, title, pos=wx.DefaultPosition,
  173.                  size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,
  174.                  name='frame'):
  175.         super(TestFrame, self).__init__(parent, id, title, pos, size, style, name)
  176.        
  177.         self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
  178.         self.GLPanel1 = TestGlPanel(self)
  179.         self.mainsizer.Add(self.GLPanel1, 1, wx.EXPAND, 5)
  180.         self.GLPanel2 = TestGlPanel(self, wx.ID_ANY, (20, 20))
  181.         self.mainsizer.Add(self.GLPanel2, 1, wx.EXPAND, 5)
  182.  
  183.         self.SetSizer(self.mainsizer)
  184.         self.mainsizer.Fit(self)
  185.        
  186.         print "testing"
  187.  
  188.    
  189.  
  190. app = wx.App(redirect=False)
  191. frame = TestFrame(None, wx.ID_ANY, 'GL Window')
  192. frame.Show()
  193.        
  194. app.MainLoop()
  195. app.Destroy()
RAW Paste Data
Top