#!/usr/bin/env python import sys import math import thread from PyOSG import * from OpenGL.GL import * class DistortionNode(osg.Group_base): def __init__(self): osg.Group_base.__init__(self) self.setCullingActive(False) self.createHUDSubgraph() def createHUDSubgraph(self): # create the quad to visualize. polyGeom = osg.Geometry() polyGeom.setSupportsDisplayList(False) origin = osg.Vec3(0.0,0.0,0.0) xAxis = osg.Vec3(1.0,0.0,0.0) yAxis = osg.Vec3(0.0,1.0,0.0) zAxis = osg.Vec3(0.0,0.0,1.0) height = 1024.0 width = 1280.0 noSteps = 50 vertices =osg.Vec3Array() texcoords =osg.Vec2Array() colors =osg.Vec4Array() bottom = osg.Vec3(origin) dx = xAxis*(width/(float(noSteps-1))) dy = yAxis*(height/(float(noSteps-1))) bottom_texcoord = osg.Vec3(0.0,0.0,0.0) dx_texcoord = osg.Vec3(1.0/(noSteps-1),0.0,0.0) dy_texcoord = osg.Vec3(0.0,1.0/(noSteps-1),0.0) cursor = osg.Vec3 = bottom texcoord = osg.Vec3 = bottom_texcoord for i in range(noSteps): cursor = bottom+dy*i texcoord = bottom_texcoord+dy_texcoord*i for j in range(noSteps): vertices.push_back(cursor) texcoords.push_back(osg.Vec2((math.sin(texcoord.x()*osg.PI-osg.PI*0.5)+1.0)*0.5,(math.sin(texcoord.y()*osg.PI-osg.PI*0.5)+1.0)*0.5)) colors.push_back(osg.Vec4(1.0,1.0,1.0,1.0)) cursor += dx texcoord += dx_texcoord # pass the created vertex array to the points geometry object. polyGeom.setVertexArray(vertices) polyGeom.setColorArray(colors) polyGeom.setColorBinding(osg.Geometry.BIND_PER_VERTEX) polyGeom.setTexCoordArray(0,texcoords) for i in range(noSteps-1): elements =osg.DrawElementsUShort(osg.PrimitiveSet.QUAD_STRIP) for j in range(noSteps): elements.push_back(j+(i+1)*noSteps) elements.push_back(j+(i)*noSteps) polyGeom.addPrimitiveSet(elements) #we need to add the texture to the Drawable, we do so by creating a # StateSet to contain the Texture StateAttribute. stateset =osg.StateSet() texture =osg.Texture2D() # texture.setFilter(osg.Texture2D.MIN_FILTER,osg.Texture2D.NEAREST) # texture.setFilter(osg.Texture2D.MAG_FILTER,osg.Texture2D.NEAREST) texture.setFilter(osg.Texture2D.MIN_FILTER,osg.Texture2D.LINEAR) texture.setFilter(osg.Texture2D.MAG_FILTER,osg.Texture2D.LINEAR) stateset.setTextureAttributeAndModes(0, texture,osg.StateAttribute.ON) stateset.setMode(GL_LIGHTING,osg.StateAttribute.OFF) polyGeom.setStateSet(stateset) self._texture = texture geode =osg.Geode() geode.addDrawable(polyGeom) # create the hud. modelview_abs =osg.MatrixTransform() modelview_abs.setReferenceFrame(osg.Transform.ABSOLUTE_RF) modelview_abs.setMatrix(osg.Matrix.identity()) modelview_abs.addChild(geode) projection =osg.Projection() projection.setMatrix(osg.Matrix.ortho2D(0,1280,0,1024)) projection.addChild(modelview_abs) self._hudSubgraph = projection self._localStateSet = osg.StateSet() def traverse(self, nv): if nv.getVisitorType() == osg.NodeVisitor.CULL_VISITOR: cullVisitor = osgUtil.asCullVisitor(nv) if cullVisitor and self._texture and self._hudSubgraph: self.preRender(cullVisitor) self._hudSubgraph.accept(nv) return osg.Group_base.traverse(self, nv) def preRender(self, cv): # create the render to texture stage. rtts = osg.ref(osgUtil.RenderToTextureStage()) # set up lighting. # currently ignore lights in the scene graph itself.. # will do later. previous_stage = cv.getCurrentRenderBin().getStage() # set up the background color and clear mask. rtts().setClearColor(osg.Vec4(0.1,0.1,0.3,1.0)) rtts().setClearMask(previous_stage.getClearMask()) # set up to charge the same RenderStageLighting is the parent previous stage. rtts().setRenderStageLighting(previous_stage.getRenderStageLighting()) # record the render bin, to be restored after creation # of the render to text previousRenderBin = cv.getCurrentRenderBin() # set the current renderbin to be the newly created stage. cv.setCurrentRenderBin(rtts.get()) cv.pushStateSet(self._localStateSet) if 1: # traverse the subgraph osg.Group_base.traverse(self,cv) cv.popStateSet() # restore the previous renderbin. cv.setCurrentRenderBin(previousRenderBin) if rtts().getRenderGraphList().size()==0 and rtts().getRenderBinList().size()==0: # getting to this point means that all the subgraph has been # culled by small feature culling or is beyond LOD ranges. return height = 1024 width = 1024 viewport = cv.getViewport() # offset the impostor viewport from the center of the main window # viewport as often the edges of the viewport might be obscured by # other windows, which can cause image/reading writing problems. center_x = viewport.x()+viewport.width()/2 center_y = viewport.y()+viewport.height()/2 new_viewport =osg.Viewport() new_viewport.setViewport(center_x-width/2,center_y-height/2,width,height) rtts().setViewport(new_viewport) self._localStateSet.setAttribute(new_viewport) # and the render to texture stage to the current stages # dependancy list. cv.getCurrentRenderBin().getStage().addToDependencyList(rtts.get()) # if one exist attach texture to the RenderToTextureStage. if self._texture: rtts().setTexture(self._texture) 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 the example which demonstrates pre rendering of scene to a texture, and then apply this texture to geometry.") arguments.getApplicationUsage().setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...") # 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 # 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() return 1 if arguments.argc()<=1: # arguments.getApplicationUsage().write(std.cout,osg.ApplicationUsage.COMMAND_LINE_OPTION) arguments.getApplicationUsage().write() return 1 # load the nodes from the commandline arguments. loadedModel = osgDB.readNodeFiles(arguments) if not loadedModel: # write_usage(osg.notify(osg.NOTICE),argv[0]) return 1 # create a transform to spin the model. distortionNode =DistortionNode() distortionNode.addChild(loadedModel) # add model to the viewer. viewer.setSceneData( distortionNode ) # create the windows and run the threads. viewer.realize() 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__": main(sys.argv)