Okay, here's the whole demo. Unfortunately, it relies on all sorts of stuff
that I can't release, but it doesn't flicker. Things to note:
self.Refresh(eraseBackground=FALSE)
Uses double buffered OpenGL (swapbuffers)
Other than that, I'm at a loss. I used to fool with the Frame's styles to
attempt to get it to no draw in the client areas, but it didn't seem to make
a difference (so I removed it).
Good luck,
Mike
from math import pi
dependencies = '''This demo requires:
wxPython (with wxGLCanvas compiled)
PyOpenGL
Numeric Python
PyOpenGL extensions to support array drawing.
'''
try:
from wxPython.wx import *
from OpenGL.GL import *
from OpenGL.GLU import *
from wxPython import glcanvas
import Numeric # just to make sure it's there before we start
working...
except ImportError, value:
print dependencies
raise
from glscenegraph import viewplatform
from glscenegraph.constants import *
class GLCanvas(glcanvas.wxGLCanvas):
deltaTurn = pi/64
step = 0.1
multiplier = 4
fieldOfView = pi/2
lookAroundRotations = {
WXK_UP:(1,0,0,-deltaTurn),
WXK_DOWN: (1,0,0,deltaTurn),
WXK_RIGHT: (0,1,0,-deltaTurn),
WXK_LEFT: (0,1,0,deltaTurn),
}
def __init__(self, parent):
glcanvas.wxGLCanvas.__init__(self, parent, -1)
self.init = false
EVT_ERASE_BACKGROUND(self, self.OnEraseBackground)
EVT_CHAR(self, self.OnChar)
EVT_LEFT_DOWN( self, self.OnMouseClickLeft )
EVT_MOTION( self, self.OnMouseMove )
EVT_LEFT_UP( self, self.OnMouseReleaseLeft )
self.platform = viewplatform.ViewPlatform(
fieldOfView=self.fieldOfView )
def OnPaint(self, event):
dc = wxPaintDC(self)
ctx = self.GetContext()
if not ctx: return
self.SetCurrent()
if not self.init:
self.InitGL()
self.init = true
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
self.platform.render()
self.DrawGeometry ()
self.SwapBuffers()
def DrawGeometry (self, mode=RENDER_MODE_OPAQUE ):
''' Override this to draw your own geometry '''
def InitGL(self):
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
self.platform.setup()
glMatrixMode(GL_MODELVIEW);
glDisable( GL_FOG )
glDisable( GL_TEXTURE_2D );
glEnable( GL_CULL_FACE );
glFrontFace( GL_CCW );
glCullFace( GL_BACK );
glDisable( GL_COLOR_MATERIAL );
glDisable(GL_BLEND);
glShadeModel( GL_SMOOTH );
def OnMouseMove ( self, event ):
# see if we're over a sensitive child
result = glSelectWithCallback( event.GetX(), event.GetY(),
self.renderPick)
if result: # is over a sensitive object:
print "over", result
def OnMouseClickLeft( self, event ):
## print "OnMouseClickLeft", event.GetX(), event.GetY()
result = glSelectWithCallback( event.GetX(), event.GetY(),
self.renderPick)
if result: # is over a sensitive object:
print "click", result
def OnMouseReleaseLeft( self, event ):
result = glSelectWithCallback( event.GetX(), event.GetY(),
self.renderPick)
if result: # is over a sensitive object:
print "release over", result
def renderPick( self ):
self.DrawGeometry( mode = RENDER_MODE_SELECT_FORCED )
# do interpretation here...
def OnChar(self, event):
code = event.KeyCode()
# general commands
if code == ord('-'): #
self.platform.straighten()
# control modes...
elif event.ControlDown():
# This is the "look around" mode
rotation = self.lookAroundRotations.get( code)
if rotation:
self.platform.turn ( rotation )
else:
event.Skip ()
return
else:
# default is "walk/fly" mode
if event.ShiftDown():
multiplier = self.multiplier
else:
multiplier = 1
if code == WXK_UP:
# forward
self.platform.forward(self.step*multiplier)
elif code ==WXK_DOWN:
# backward
self.platform.forward
(-self.step*multiplier)
else:
# either a turn or nothing
rotation = self.lookAroundRotations.get(
code)
if rotation:
self.platform.turn ( rotation )
else:
event.Skip ()
return
# force a repaint
self.Refresh(eraseBackground=FALSE)
def OnEraseBackground(self, event):
pass # Do nothing, to avoid flashing.
def OnSize(self, event):
size = self.GetClientSize()
if self.GetContext() != 'NULL':
self.SetCurrent()
# aspect ratio calculation
# fov represents the vertical field of view
# aspect represents ratio of width to height for
field of view
# we want the field of view to the constant for the
smallest dimension
# and all visible ratios to be 1.0:1.0
if size.height > 0 and size.width >0:
ratio = size.width/float(size.height )
if size.height < size.width:
# width specifies field of view
fieldOfView = self.fieldOfView/ratio
else:
fieldOfView = self.fieldOfView
self.platform.set_frustrum( fieldOfView,
ratio)
self.platform.setup()
self.Refresh (eraseBackground=FALSE)
glViewport(0, 0, size.width, size.height)
if __name__ == '__main__':
class TestGLCanvas( GLCanvas ):
def DrawGeometry (self):
''' Override this to draw your own geometry '''
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glRotate(1,0,0,-90)
glDisable(GL_LIGHTING)
glColor3f( 0,0,.3)
fullsize = 40
tilesize = 4
glBegin(GL_QUADS)
for x in range(-(fullsize/2),(fullsize/2),tilesize):
for y in
range(-(fullsize/2),(fullsize/2),tilesize):
if (((x+y)/tilesize)%2):
glNormal3f( 0.0, 1.0, 0.0)
glVertex3f( x, 0, y)
glVertex3f( x, 0,
y+tilesize)
glVertex3f( x+tilesize, 0,
y+tilesize)
glVertex3f( x+tilesize, 0,
y)
glEnd( )
glColor3f( 1,1,0)
glBegin(GL_QUADS)
for x in range(-(fullsize/2),(fullsize/2),tilesize):
for y in
range(-(fullsize/2),(fullsize/2),tilesize):
if not (((x+y)/tilesize)%2):
glNormal3f( 0.0, 1.0, 0.0)
glVertex3f( x, 0, y)
glVertex3f( x, 0,
y+tilesize)
glVertex3f( x+tilesize, 0,
y+tilesize)
glVertex3f( x+tilesize, 0,
y)
glEnd( )
glPopMatrix()
# clear color and depth buffers
glEnable(GL_LIGHTING)
glPushMatrix()
glColor3f( .8,.8,0)
glTranslate( 0,.5,0)
glRotatef(30.0, 1.0, 0.0, 0.0);
glRotatef(30.0, 0.0, 1.0, 0.0);
# 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()
glPopMatrix()
class MyApp(wxApp):
def OnInit(self):
frame = wxFrame(NULL, -1, "GL Cube",
wxDefaultPosition, wxSize(400,300))
win = TestGLCanvas(frame)
frame.Show(TRUE)
self.SetTopWindow(frame)
return TRUE
app = MyApp(0)
app.MainLoop()
···
-----Original Message-----
From: Ryan Martin [mailto:ryanm@wag.caltech.edu]
Sent: Wednesday, July 05, 2000 8:01 PM
To: Mike Fletcher
Cc: wxpython-users@wxwindows.org
Subject: Re: [wxPython] glcanvas flickers on linux
Sorry, forgot to mention I already have an empty OnEraseBackground
handler. The problem is something else.
-Ryan
Mike Fletcher (mfletch@tpresence.com) [000705 16:54]
>From a little internal project...
class GLCanvas(glcanvas.wxGLCanvas):
def __init__(self, parent):
glcanvas.wxGLCanvas.__init__(self, parent, -1)
self.init = false
EVT_ERASE_BACKGROUND(self, self.OnEraseBackground)
EVT_CHAR(self, self.OnChar)
EVT_LEFT_DOWN( self, self.OnMouseClickLeft )
EVT_MOTION( self, self.OnMouseMove )
EVT_LEFT_UP( self, self.OnMouseReleaseLeft )
self.platform = viewplatform.ViewPlatform(
fieldOfView=self.fieldOfView )
def OnEraseBackground(self, event):
pass # Do nothing, to avoid flashing.HTH,
Mike-----Original Message-----
From: Ryan Martin [mailto:ryanm@wag.caltech.edu]
Sent: Wednesday, July 05, 2000 6:47 PM
To: wxpython-users@wxwindows.org
Subject: [wxPython] glcanvas flickers on linuxI have a program that loads and saves molecular description files and
gives the option to display them using opengl. When the user double
clicks on a molecule, I render that molecule in a second frame
containing a glcanvas object. It works fine but the moment I start
to rotate, translate or zoom on the molecule(meaning OnPaint is
being called a lot) the canvas flickers. I'm using the standard
SwapBuffers command that comes with glcanvas. Has anyone else run into
this problem using wxGTK on linux? Hopefully I can find a fix for this
so I don't have to go back to tkinter and try to get togl to work.I'm using wxPython 2.1.16, wxWindows 2.1.16, GTK+ 1.2.8, and Mesa 3.2.
I'm not subscribe to the list, so can you please cc me on any replies.
Thanks.
-Ryan
_______________________________________________
wxPython-users mailing list wxPython-users@wxwindows.org
http://wxwindows.org/mailman/listinfo/wxpython-users
_______________________________________________
wxPython-users mailing list wxPython-users@wxwindows.org
http://wxwindows.org/mailman/listinfo/wxpython-users