#!/usr/bin/env python from PyOSG import * from OpenGL.GL import * class MotionBlurDrawCallback(osgProducer.OsgSceneHandler.Callback): def __init__(self, persistence): osgProducer.OsgSceneHandler.Callback.__init__(self) self.cleared_ = False self.persistence_ = persistence self.t0_ = 0 def apply(self, handler, camera): t = handler.getSceneView().getFrameStamp().getReferenceTime() if not self.cleared_: # clear the accumulation buffer glClearColor(0, 0, 0, 0) glClear(GL_ACCUM_BUFFER_BIT) self.cleared_ = True self.t0_ = t dt = abs(t - self.t0_) self.t0_ = t # call the scene handler's draw function handler.drawImplementation(camera) # compute the blur factor s =pow(0.2, dt / self.persistence_) # scale, accumulate and return glAccum(GL_MULT, s) glAccum(GL_ACCUM, 1 - s) glAccum(GL_RETURN, 1.0) def __del__(self): print "Deleting MotionBlurDrawCallback" def main(argv ): # use an ArgumentParser object to manage the program arguments. arguments = osg.ArgumentParser(argv) # set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage().setApplicationName(arguments.getApplicationName()) arguments.getApplicationUsage().setDescription(arguments.getApplicationName()+" is an OpenSceneGraph example that shows how to use the accumulation buffer to achieve a simple motion blur effect.") arguments.getApplicationUsage().setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...") arguments.getApplicationUsage().addCommandLineOption("-h or --help","Display this information") arguments.getApplicationUsage().addCommandLineOption("-P or --persistence","Set the motion blur persistence time") # construct the viewer. viewer = osgProducer.Viewer(arguments) # set up the value with sensible default event handlers. viewer.setUpViewer(osgProducer.Viewer.STANDARD_SETTINGS) # get details on keyboard and mouse bindings used by the viewer. viewer.getUsage(arguments.getApplicationUsage()) # if user request help write it out to cout. if arguments.read("-h") or arguments.read("--help"): arguments.getApplicationUsage().write() return 1 persistence = 0.25 # FIXME arguments.read("-P", persistence) or arguments.read("--persistence", persistence) # report any errors if they have occured when parsing the program aguments. if arguments.errors(): arguments.writeErrorMessages() return 1 if arguments.argc()<=1: arguments.getApplicationUsage().write(osg.ApplicationUsage.COMMAND_LINE_OPTION) return 1 start_tick = osg.Timer.instance().tick() # read the scene from the list of file specified commandline args. loadedModel = osgDB.readNodeFiles(arguments) # if no model has been successfully loaded report failure. if not loadedModel: print arguments.getApplicationName(),": No data loaded" return 1 # any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized() # report any errors if they have occured when parsing the program aguments. if arguments.errors(): arguments.writeErrorMessages() end_tick = osg.Timer.instance().tick() print "Time to load = ", osg.Timer.instance().delta_s(start_tick,end_tick) # optimize the scene graph, remove rendundent nodes and state etc. optimizer = osgUtil.Optimizer() optimizer.optimize(loadedModel) # pass the loaded scene graph to the viewer. viewer.setSceneData(loadedModel) # create the windows and run the threads. viewer.realize() # set our motion blur callback as the draw callback for each scene handler shl = viewer.getSceneHandlerList() for i in shl: i.setDrawCallback(MotionBlurDrawCallback(persistence)) while not viewer.done(): # wait for all cull and draw threads to complete. viewer.sync() # update the scene by traversing it with the the update visitor which will # call all node update callbacks and animations. viewer.update() # fire off the cull and draw traversals of the scene. viewer.frame() # wait for all cull and draw threads to complete before exit. viewer.sync() return 0 if __name__ == "__main__": import sys main(sys.argv)