import wx try: from wx import glcanvas haveGLCanvas = True except ImportError: haveGLCanvas = False try: # The Python OpenGL package can be found at # http://PyOpenGL.sourceforge.net/ from OpenGL.GL import * from OpenGL.GLUT import * haveOpenGL = True except ImportError: haveOpenGL = False #---------------------------------------------------------------------- buttonDefs = { wx.NewId() : ('CubeCanvas', 'Cube'), wx.NewId() : ('ConeCanvas', 'Cone'), } class ButtonPanel(wx.Panel): def __init__(self, parent, log): wx.Panel.__init__(self, parent, -1) self.log = log box = wx.BoxSizer(wx.VERTICAL) box.Add((20, 30)) keys = buttonDefs.keys() keys.sort() for k in keys: text = buttonDefs[k][1] btn = wx.Button(self, k, text) box.Add(btn, 0, wx.ALIGN_CENTER|wx.ALL, 15) self.Bind(wx.EVT_BUTTON, self.OnButton, btn) #** Enable this to show putting a GLCanvas on the wx.Panel if 0: c = CubeCanvas(self) c.SetSize((200, 200)) box.Add(c, 0, wx.ALIGN_CENTER|wx.ALL, 15) self.SetAutoLayout(True) self.SetSizer(box) def OnButton(self, evt): if not haveGLCanvas: dlg = wx.MessageDialog(self, 'The GLCanvas class has not been included with this build of wxPython!', 'Sorry', wx.OK | wx.ICON_WARNING) dlg.ShowModal() dlg.Destroy() elif not haveOpenGL: dlg = wx.MessageDialog(self, 'The OpenGL package was not found. You can get it at\n' 'http://PyOpenGL.sourceforge.net/', 'Sorry', wx.OK | wx.ICON_WARNING) dlg.ShowModal() dlg.Destroy() else: canvasClassName = buttonDefs[evt.GetId()][0] canvasClass = eval(canvasClassName) frame = wx.Frame(None, -1, canvasClassName, size=(400,400)) canvas = canvasClass(frame) frame.Show(True) class MyCanvasBase(glcanvas.GLCanvas): def __init__(self, parent): glcanvas.GLCanvas.__init__(self, parent, -1) self.init = False # initial mouse position self.lastx = self.x = 30 self.lasty = self.y = 30 self.size = None self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown) self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp) self.Bind(wx.EVT_MOTION, self.OnMouseMotion) def OnEraseBackground(self, event): pass # Do nothing, to avoid flashing on MSW. def OnSize(self, event): size = self.size = self.GetClientSize() if self.GetContext(): self.SetCurrent() glViewport(0, 0, size.width, size.height) event.Skip() def OnPaint(self, event): dc = wx.PaintDC(self) self.SetCurrent() if not self.init: self.InitGL() self.init = True self.OnDraw() def OnMouseDown(self, evt): self.CaptureMouse() self.x, self.y = self.lastx, self.lasty = evt.GetPosition() def OnMouseUp(self, evt): self.ReleaseMouse() def OnMouseMotion(self, evt): if evt.Dragging() and evt.LeftIsDown(): self.lastx, self.lasty = self.x, self.y self.x, self.y = evt.GetPosition() self.Refresh(False) class CubeCanvas(MyCanvasBase): def InitGL(self): # set viewing projection glMatrixMode(GL_PROJECTION) glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0) # position viewer glMatrixMode(GL_MODELVIEW) glTranslatef(0.0, 0.0, -2.0) # position object glRotatef(self.y, 1.0, 0.0, 0.0) glRotatef(self.x, 0.0, 1.0, 0.0) glEnable(GL_DEPTH_TEST) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) def OnDraw(self): # clear color and depth buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # draw six faces of a cube glBegin(GL_QUADS) glNormal3f( 0.0, 0.0, 1.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f(-0.5, 0.5, 0.5) glVertex3f(-0.5,-0.5, 0.5) glVertex3f( 0.5,-0.5, 0.5) glNormal3f( 0.0, 0.0,-1.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f(-0.5, 0.5,-0.5) glVertex3f( 0.5, 0.5,-0.5) glVertex3f( 0.5,-0.5,-0.5) glNormal3f( 0.0, 1.0, 0.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f( 0.5, 0.5,-0.5) glVertex3f(-0.5, 0.5,-0.5) glVertex3f(-0.5, 0.5, 0.5) glNormal3f( 0.0,-1.0, 0.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f( 0.5,-0.5,-0.5) glVertex3f( 0.5,-0.5, 0.5) glVertex3f(-0.5,-0.5, 0.5) glNormal3f( 1.0, 0.0, 0.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f( 0.5,-0.5, 0.5) glVertex3f( 0.5,-0.5,-0.5) glVertex3f( 0.5, 0.5,-0.5) glNormal3f(-1.0, 0.0, 0.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f(-0.5,-0.5, 0.5) glVertex3f(-0.5, 0.5, 0.5) glVertex3f(-0.5, 0.5,-0.5) glEnd() if self.size is None: self.size = self.GetClientSize() w, h = self.size w = max(w, 1.0) h = max(h, 1.0) xScale = 180.0 / w yScale = 180.0 / h glRotatef((self.y - self.lasty) * yScale, 1.0, 0.0, 0.0); glRotatef((self.x - self.lastx) * xScale, 0.0, 1.0, 0.0); self.SwapBuffers() class ConeCanvas(MyCanvasBase): def InitGL( self ): glMatrixMode(GL_PROJECTION) # camera frustrum setup glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0) glMaterial(GL_FRONT, GL_AMBIENT, [0.2, 0.2, 0.2, 1.0]) glMaterial(GL_FRONT, GL_DIFFUSE, [0.8, 0.8, 0.8, 1.0]) glMaterial(GL_FRONT, GL_SPECULAR, [1.0, 0.0, 1.0, 1.0]) glMaterial(GL_FRONT, GL_SHININESS, 50.0) glLight(GL_LIGHT0, GL_AMBIENT, [0.0, 1.0, 0.0, 1.0]) glLight(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0]) glLight(GL_LIGHT0, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0]) glLight(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0]) glLightModel(GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0]) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glDepthFunc(GL_LESS) glEnable(GL_DEPTH_TEST) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # position viewer glMatrixMode(GL_MODELVIEW) # position viewer glTranslatef(0.0, 0.0, -2.0); def OnDraw(self): # clear color and depth buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # use a fresh transformation matrix glPushMatrix() # position object #glTranslate(0.0, 0.0, -2.0) glRotate(30.0, 1.0, 0.0, 0.0) glRotate(30.0, 0.0, 1.0, 0.0) glTranslate(0, -1, 0) glRotate(250, 1, 0, 0) glutSolidCone(0.5, 1, 30, 5) glPopMatrix() glRotatef((self.y - self.lasty), 0.0, 0.0, 1.0); glRotatef((self.x - self.lastx), 1.0, 0.0, 0.0); # push into visible buffer self.SwapBuffers() #---------------------------------------------------------------------- def runTest(frame, nb, log): win = ButtonPanel(nb, log) return win overview = """\ """ if __name__ == '__main__': import sys,os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) #----------------------------------------------------------------------