#!/usr/bin/env python # Copyright (C) 2002-2003 Gideon May (gideon@computer.org) # # Permission to copy, use, sell and distribute this software is granted # provided this copyright notice appears in all copies. # Permission to modify the code and to distribute modified code is granted # provided this copyright notice appears in all copies, and a notice # that the code was modified is included with the copyright notice. # # This software is provided "as is" without express or implied warranty, # and with no claim as to its suitability for any purpose. import sys import math from PyOSG import Producer from PyOSG import osg from PyOSG import osgDB from PyOSG import osgGA from PyOSG import osgUtil from PyOSG import osgProducer from PyOSG import osgText from OpenGL.GL import * #/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield # * # * This library is open source and may be redistributed and/or modified under # * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or # * (at your option) any later version. The full license is in LICENSE file # * included with this distribution, and on the openscenegraph.org website. # * # * This library is distributed in the hope that it will be useful, # * but WITHOUT ANY WARRANTY without even the implied warranty of # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # * OpenSceneGraph Public License for more details. #*/ def createHUD(): geode = osg.Geode() timesFont = "fonts/arial.ttf" # turn lighting off for the text and disable depth test to ensure its always ontop. stateset = geode.getOrCreateStateSet() stateset.setMode(GL_LIGHTING,osg.StateAttribute.OFF) position = osg.Vec3(150.0,800.0,0.0) delta = osg.Vec3(0.0,-120.0,0.0) if True: text = osgText.Text() geode.addDrawable(text) text.setFont(timesFont) text.setPosition(position) text.setText("Head Up Displays are simple :-)") position += delta if True: text = osgText.Text() geode.addDrawable(text) text.setFont(timesFont) text.setPosition(position) text.setText("All you need to do is create your text in a subgraph.") position += delta if True: text = osgText.Text() geode.addDrawable(text) text.setFont(timesFont) text.setPosition(position) text.setText("Disable depth test in this subgraph to ensure its always ontop.") position += delta if True: text = osgText.Text() geode.addDrawable(text) text.setFont(timesFont) text.setPosition(position) text.setText("Then place an osg.Projection node above the subgraph\nto create an orthographic projection.") position += delta if True: text = osgText.Text() geode.addDrawable(text) text.setFont(timesFont) text.setPosition(position) text.setText("And add an osg.ModelViewMatrix set to ABSOLUTE_RF to ensure\nit remains independent from any external model view matrices.") position += delta if True: bb = osg.BoundingBox() for i in range(geode.getNumDrawables()): bb.expandBy(geode.getDrawable(i).getBound()) geom = osg.Geometry() vertices = osg.Vec3Array() depth = bb.zMin()-0.1 vertices.push_back(osg.Vec3(bb.xMin(),bb.yMax(),depth)) vertices.push_back(osg.Vec3(bb.xMin(),bb.yMin(),depth)) vertices.push_back(osg.Vec3(bb.xMax(),bb.yMin(),depth)) vertices.push_back(osg.Vec3(bb.xMax(),bb.yMax(),depth)) geom.setVertexArray(vertices) normals = osg.Vec3Array() normals.push_back(osg.Vec3(0.0,0.0,1.0)) geom.setNormalArray(normals) geom.setNormalBinding(osg.Geometry.BIND_OVERALL) colors = osg.Vec4Array() colors.push_back(osg.Vec4(1.0,1.0,0.8,0.2)) geom.setColorArray(colors) geom.setColorBinding(osg.Geometry.BIND_OVERALL) geom.addPrimitiveSet(osg.DrawArrays(GL_QUADS,0,4)) stateset = geom.getOrCreateStateSet() stateset.setMode(GL_BLEND,osg.StateAttribute.ON) #stateset.setAttribute(new osg.PolygonOffset(1.0,1.0),osg.StateAttribute.ON) stateset.setRenderingHint(osg.StateSet.TRANSPARENT_BIN) geode.addDrawable(geom) camera = osg.CameraNode() # set the projection matrix camera.setProjectionMatrix(osg.Matrix.ortho2D(0,1280,0,1024)) # set the view matrix camera.setReferenceFrame(osg.Transform.ABSOLUTE_RF) camera.setViewMatrix(osg.Matrix.identity()) # only clear the depth buffer camera.setClearMask(GL_DEPTH_BUFFER_BIT) # draw subgraph after main camera view. camera.setRenderOrder(osg.CameraNode.POST_RENDER) camera.addChild(geode) return camera def main(argv = None): # 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().setDescription(arguments.getApplicationName()+" is the example which demonstrates how to do Head Up Displays.") arguments.getApplicationUsage().setCommandLineUsage(arguments.getApplicationName()+" [options] [filename] ...") arguments.getApplicationUsage().addCommandLineOption("-h or --help","Display this information") # 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 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 # read the scene from the list of file specified commandline args. scene = osgDB.readNodeFiles(arguments) group = osg.Group() # add the HUD subgraph. if scene: group.addChild(scene) group.addChild(createHUD()) # set the scene to render viewer.setSceneData(group) # 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)