Why does this wxPython/PyOpenGL code raise an erro

2019-07-11 18:50发布

问题:

I was dusting off some wxPython/PyOpenGL code that used to run but does not any more -- apparently it stopped working after some update in one module or another, I have no idea when.

Here is a teeny sample app that reproduces the error.

import wx
from wx import glcanvas
from OpenGL.GLUT import *
from OpenGL.GL import *

class WxMyTestApp(wx.App):
  def __init__(self):
    wx.App.__init__(self)
  def OnInit(self):
    self.viewFrame = wx.Frame(None, -1, 'viewFrame', wx.DefaultPosition, (400,400))
    self.canvas = glcanvas.GLCanvas(self.viewFrame)
    self.canvas.Bind(wx.EVT_PAINT, self.OnPaint)
    return True
  def OnPaint(self, ev):
    print "OnPaint ",
    dc = wx.PaintDC(self.canvas)
    self.canvas.SetCurrent()
    self.redraw(ev)
  def redraw(self, ignoredEvent):
    glPushMatrix()
    glColor3f(1.0, 1.0, 0.0)
    glLineWidth(1)
    glutWireSphere(0.5, 10,10)
    glPopMatrix()
    glFlush()
    self.canvas.SwapBuffers()

if __name__ == '__main__':
  d = WxMyTestApp()
  d.viewFrame.Show()
  d.MainLoop()

(Note I am using wx.App instead of wx.PySimpleApp because my real code uses more than one window.) Running the test code, the frame shows a small white rectangle in the upper-left corner and upon a resize gives this repeated error:

Traceback (most recent call last):
  File "myTestApp.py", line 18, in OnPaint
    self.redraw(ev)
  File "myTestApp.py", line 20, in redraw
    glPushMatrix()
  File "C:\users\user\appdata\local\enthought\canopy\user\lib\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
    return self( *args, **named )
  File "C:\users\user\appdata\local\enthought\canopy\user\lib\site-packages\OpenGL\error.py", line 232, in glCheckError
    baseOperation = baseOperation,
OpenGL.error.GLError: GLError(
        err = 1282,
        description = 'invalid operation',
        baseOperation = glPushMatrix,
        cArguments = ()

Is there really a problem with doing a push here? I suspect the problem has something to do with GL device context but have no idea how to debug it. Python 2.7.10, wxPython 3.0.2.0-3, PyOpenGL 3.1.0-2 (Canopy distribution).

回答1:

I benefited from the documentation of GLCanvas and GLContext apparently produced under the wxWidgets/wxPython Phoenix effort. Seems that earlier versions of wxWidgets would create a GLContext for you implicitly but this has been deprecated. Using this info I was able to get the code up to date. The two changes I needed were:

In OnInit, add a line after the assignment to self.canvas:

self.canvas = glcanvas.GLCanvas(self.viewFrame)
self.context = glcanvas.GLContext(self.canvas)  # add this line

Then in OnPaint change this line:

self.canvas.SetCurrent()

to this:

self.canvas.SetCurrent(self.context)  # add the argument

These little changes got my code up and running again. Hope someone else can benefit from this.