#!/bin/env python import sys import math import thread from PyOSG import * from OpenGL.GL import * def createDistortionSubgraph(subgraph, clearColour): distortionNode = osg.Group() tex_width = 1024 tex_height = 1024 texture = osg.Texture2D() texture.setTextureSize(tex_width, tex_height) texture.setInternalFormat(GL_RGBA) texture.setFilter(osg.Texture2D.MIN_FILTER,osg.Texture2D.LINEAR) texture.setFilter(osg.Texture2D.MAG_FILTER,osg.Texture2D.LINEAR) # set up the render to texture camera. camera = osg.CameraNode() # set clear the color and depth buffer camera.setClearColor(clearColour) camera.setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) # just inherit the main cameras view camera.setReferenceFrame(osg.Transform.RELATIVE_RF) camera.setProjectionMatrix(osg.Matrix.identity()) camera.setViewMatrix(osg.Matrix.identity()) # set viewport camera.setViewport(0,0,tex_width,tex_height) # set the camera to render before the main camera. camera.setRenderOrder(osg.CameraNode.PRE_RENDER) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(osg.CameraNode.FRAME_BUFFER_OBJECT) # attach the texture and use it as the color buffer. camera.attach(osg.CameraNode.COLOR_BUFFER, texture,0,0,False) # add subgraph to render camera.addChild(subgraph) distortionNode.addChild(camera) # set up the render to texture camera. # 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 = origin dx = xAxis*(width/((float)(noSteps-1))) dy = yAxis*(height/((float)(noSteps-1))) bottom_texcoord = osg.Vec2(0.0,0.0) dx_texcoord = osg.Vec2(1.0/(float)(noSteps-1),0.0) dy_texcoord = osg.Vec2(0.0,1.0/(float)(noSteps-1)) cursor = bottom texcoord = bottom_texcoord for i in range(noSteps): cursor = bottom+dy*float(i) texcoord = bottom_texcoord+dy_texcoord*float(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): 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 = polyGeom.getOrCreateStateSet() stateset.setTextureAttributeAndModes(0, texture,osg.StateAttribute.ON) stateset.setMode(GL_LIGHTING,osg.StateAttribute.OFF) geode = osg.Geode() geode.addDrawable(polyGeom) # set up the camera to render the textured quad camera = osg.CameraNode() # just inherit the main cameras view camera.setReferenceFrame(osg.Transform.ABSOLUTE_RF) camera.setViewMatrix(osg.Matrix.identity()) camera.setProjectionMatrixAsOrtho2D(0,1280,0,1024) # set the camera to render before the main camera. camera.setRenderOrder(osg.CameraNode.NESTED_RENDER) # tell the camera to use OpenGL frame buffer object where supported. camera.setRenderTargetImplementation(osg.CameraNode.FRAME_BUFFER_OBJECT) # attach the texture and use it as the color buffer. camera.attach(osg.CameraNode.COLOR_BUFFER, texture,0,0,False) # add subgraph to render camera.addChild(geode) distortionNode.addChild(camera) return distortionNode 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 = createDistortionSubgraph(loadedModel, viewer.getClearColor()) 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)