From 051f2a5eb907d6f7972abf34072ccdc4f40f64da Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 5 Apr 2006 15:13:17 +0000 Subject: [PATCH] Added beginings osgprecipitation example. --- Make/makedirdefs | 1 + examples/osgprecipitation/GNUmakefile | 18 ++ examples/osgprecipitation/GNUmakefile.inst | 14 + .../osgprecipitation/osgprecipitation.cpp | 281 ++++++++++++++++++ examples/osgprecipitation/rain.frag | 6 + examples/osgprecipitation/rain.vert | 15 + examples/osgsimulation/osgsimulation.cpp | 38 ++- 7 files changed, 364 insertions(+), 9 deletions(-) create mode 100644 examples/osgprecipitation/GNUmakefile create mode 100644 examples/osgprecipitation/GNUmakefile.inst create mode 100644 examples/osgprecipitation/osgprecipitation.cpp create mode 100644 examples/osgprecipitation/rain.frag create mode 100644 examples/osgprecipitation/rain.vert diff --git a/Make/makedirdefs b/Make/makedirdefs index 61060bf33..3a4ca571d 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -235,6 +235,7 @@ ifeq ($(PRODUCER_INSTALLED),yes) osgplanets \ osgpoints \ osgpointsprite \ + osgprecipitation \ osgprerender \ osgprerendercubemap \ osgreflect \ diff --git a/examples/osgprecipitation/GNUmakefile b/examples/osgprecipitation/GNUmakefile new file mode 100644 index 000000000..2a5df2185 --- /dev/null +++ b/examples/osgprecipitation/GNUmakefile @@ -0,0 +1,18 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgprecipitation.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgprecipitation + +INC += $(X_INC) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgprecipitation/GNUmakefile.inst b/examples/osgprecipitation/GNUmakefile.inst new file mode 100644 index 000000000..585df3e8d --- /dev/null +++ b/examples/osgprecipitation/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgprecipitation.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgprecipitation + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgprecipitation/osgprecipitation.cpp b/examples/osgprecipitation/osgprecipitation.cpp new file mode 100644 index 000000000..57aa2bf72 --- /dev/null +++ b/examples/osgprecipitation/osgprecipitation.cpp @@ -0,0 +1,281 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application 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. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +float random(float min,float max) { return min + (max-min)*(float)rand()/(float)RAND_MAX; } + +osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles, bool useShaders) +{ + osg::Geometry* geometry = new osg::Geometry; + + osg::StateSet* stateset = geometry->getOrCreateStateSet(); + + // set up geometry. + { + + // per vertex properties + osg::Vec3Array* vertices = new osg::Vec3Array(numParticles*2); + osg::FloatArray* offsets = new osg::FloatArray(numParticles*2); + + osg::Vec3 frameDelta = velocity*(2.0f/60.0f); + + for(unsigned int i=0; i< numParticles; ++i) + { + (*vertices)[i*2].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax()); + (*vertices)[i*2+1] = (*vertices)[i*2] + frameDelta; + (*offsets)[i*2] = random(0.0, 1.0); + (*offsets)[i*2+1] = (*offsets)[i*2]; + } + + geometry->setVertexArray(vertices); + geometry->setTexCoordArray(0, offsets); + + // overall attributes + osg::Vec4Array* colours = new osg::Vec4Array(1); + (*colours)[0].set(0.5f,0.5f,0.5f,0.5f); + geometry->setColorArray(colours); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + + geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, numParticles)); + } + + // set up state. + { + // time taken to get from start to the end of cycle + float period = fabs((bb.zMax()-bb.zMin()) / velocity.z()); + + // distance between start point and end of cyclce + osg::Vec3 delta = velocity * period; + + // set up uniforms + osg::Uniform* deltaUniform = new osg::Uniform("delta",delta); + osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period); + osg::Uniform* startTime = new osg::Uniform("startTime",0.0f); + + osg::Program* program = new osg::Program; + stateset->setAttribute(program); + + // get shaders from source + program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("rain.vert"))); + program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("rain.frag"))); + + stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateset->setMode(GL_BLEND, osg::StateAttribute::ON); + + stateset->addUniform(deltaUniform); + stateset->addUniform(inversePeriodUniform); + stateset->addUniform(startTime); + } + + geometry->setUseVertexBufferObjects(true); + geometry->setInitialBound(bb); + + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + + return geode; +} +/* +osg::Node* createSnowEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles, bool useShaders) +{ + osg::Geometry* geometry = new osg::Geometry; + + osg::StateSet* stateset = geometry->getOrCreateStateSet(); + + // set up geometry. + { + + // per vertex properties + osg::Vec3Array* vertices = new osg::Vec3Array(numParticles); + osg::FloatArray* offsets = new osg::FloatArray(numParticles); + + for(unsigned int i=0; i< numParticles; ++i) + { + (*vertices)[i].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax()); + (*offsets)[i] = random(0.0, 1.0); + } + + geometry->setVertexArray(vertices); + geometry->setTexCoordArray(0, offsets); + + // overall attributes + osg::Vec4Array* colours = new osg::Vec4Array(1); + (*colours)[0].set(1.0f,1.0f,1.0f,1.0f); + geometry->setColorArray(colours); + geometry->setColorBinding(osg::Geometry::BIND_OVERALL); + + geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, numParticles)); + } + + // set up state. + { + // time taken to get from start to the end of cycle + float period = fabs((bb.zMax()-bb.zMin()) / velocity.z()); + + // distance between start point and end of cyclce + osg::Vec3 delta = velocity * period; + + // set up uniforms + osg::Uniform* deltaUniform = new osg::Uniform("delta",delta); + osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period); + osg::Uniform* startTime = new osg::Uniform("startTime",0.0f); + + osg::Program* program = new osg::Program; + stateset->setAttribute(program); + + // get shaders from source + program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, osgDB::findDataFile("snow.vert"))); + program->addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, osgDB::findDataFile("snow.frag"))); + + stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + + stateset->addUniform(deltaUniform); + stateset->addUniform(inversePeriodUniform); + stateset->addUniform(startTime); + } + + geometry->setInitialBound(bb); + + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); + + return geode; +} +*/ +osg::Node* createModel(osg::Node* loadedModel, bool useShaders) +{ + osg::Group* group = new osg::Group; + + osg::BoundingBox bb(0.0, 0.0, 0.0, 100.0, 100.0, 100.0); + osg::Vec3 velocity(0.0,0.0,-2.0); + unsigned int numParticles = 100000; + + if (loadedModel) + { + group->addChild(loadedModel); + + osg::BoundingSphere bs = loadedModel->getBound(); + bs.radius() *= 0.75; + bb.init(); + bb.expandBy(bs); + } + + group->addChild(createRainEffect(bb, velocity, numParticles, useShaders)); + + return group; +} + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,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()+" example provides an interactive viewer for visualising point clouds.."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("--shader","Use GLSL shaders."); + arguments.getApplicationUsage()->addCommandLineOption("--fixed","Use fixed function pipeline."); + + + // construct the viewer. + osgProducer::Viewer 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()); + + bool shader = true; + while (arguments.read("--shader")) shader = true; + while (arguments.read("--fixed")) shader = false; + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + 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(std::cout); + return 1; + } + + osg::Timer timer; + osg::Timer_t start_tick = timer.tick(); + + // read the scene from the list of file specified commandline args. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + + loadedModel = createModel(loadedModel.get(), shader); + + // if no model has been successfully loaded report failure. + if (!loadedModel) + { + std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; + return 1; + } + + osg::Timer_t end_tick = timer.tick(); + + std::cout << "Time to load = "< #include #include +#include +#include #include #include @@ -310,11 +312,15 @@ int main(int argc, char **argv) viewer.setSceneData(root.get()); osg::CoordinateSystemNode* csn = dynamic_cast(root.get()); + osg::Group * overlaySubGraph = new osg::Group; if (csn) { bool insertOverlayNode = true; osg::ref_ptr overlayNode; + osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); + double s = 200000.0 / cessna->getBound().radius(); + if (insertOverlayNode) { @@ -325,21 +331,34 @@ int main(int argc, char **argv) { overlayNode->addChild( csn->getChild(i) ); } - csn->removeChild(0, csn->getNumChildren()); csn->addChild(overlayNode.get()); + + osg::ref_ptr polymode = new osg::PolygonMode; + polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE); + osg::NodeCallback* sphereCb = new ModelPositionCallback; + osg::ref_ptr mt = new osg::MatrixTransform; + mt->setUpdateCallback(sphereCb); + + osg::ref_ptr geode = new osg::Geode; + osg::ref_ptr sd; + sd = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),s)); + sd->setColor(osg::Vec4(1.0,0.0,0.0,1.0)); + geode->addDrawable(sd.get()); + + mt->addChild(geode.get()); + overlaySubGraph->addChild(mt.get()); + geode->getOrCreateStateSet()->setAttributeAndModes(polymode.get(), osg::StateAttribute::ON); // tell the overlay node to continously update its overlay texture // as we know we'll be tracking a moving target. overlayNode->setContinuousUpdate(true); } - osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); + //osg::Node* cessna = osgDB::readNodeFile("f15.ive"); if (cessna) { - double s = 200000.0 / cessna->getBound().radius(); - osg::MatrixTransform* scaler = new osg::MatrixTransform; scaler->addChild(cessna); scaler->setMatrix(osg::Matrixd::scale(s,s,s)*osg::Matrixd::rotate(rotation)); @@ -348,18 +367,15 @@ int main(int argc, char **argv) osg::MatrixTransform* mt = new osg::MatrixTransform; mt->addChild(scaler); - if (!nc) nc = new ModelPositionCallback; mt->setUpdateCallback(nc); csn->addChild(mt); + + // if (overlaySubGraph) overlaySubGraph->addChild(mt); // if we are using an overaly node, use the cessna subgraph as the overlay subgraph - if (overlayNode.valid()) - { - overlayNode->setOverlaySubgraph(mt); - } osgGA::NodeTrackerManipulator* tm = new osgGA::NodeTrackerManipulator; tm->setTrackerMode(trackerMode); @@ -374,6 +390,10 @@ int main(int argc, char **argv) std::cout<<"Failed to read cessna.osg"<setOverlaySubgraph(overlaySubGraph); + } }