diff --git a/examples/osgprecipitation/GNUmakefile b/examples/osgprecipitation/GNUmakefile index b6348bfc5..92bb794f1 100644 --- a/examples/osgprecipitation/GNUmakefile +++ b/examples/osgprecipitation/GNUmakefile @@ -3,7 +3,6 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ PrecipitationEffect.cpp\ - PrecipitationDrawable.cpp\ osgprecipitation.cpp\ LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) diff --git a/examples/osgprecipitation/PrecipitationDrawable.cpp b/examples/osgprecipitation/PrecipitationDrawable.cpp deleted file mode 100644 index 932f07ba2..000000000 --- a/examples/osgprecipitation/PrecipitationDrawable.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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. -*/ - -#include "PrecipitationDrawable.h" - -#include -#include - -using namespace osgParticle; - -PrecipitationDrawable::PrecipitationDrawable() -{ - setSupportsDisplayList(false); -} - -PrecipitationDrawable::PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop): - Drawable(copy,copyop) -{ -} - -void PrecipitationDrawable::setParameters(PrecipitationParameters* parameters) -{ - _parameters = parameters; -} - - -void PrecipitationDrawable::compileGLObjects(osg::State& state) const -{ - osg::notify(osg::NOTICE)<<"PrecipitationDrawable::compileGLObjects()"<glMultiTexCoord1f(GL_TEXTURE0+1, _startTime); - - // load cells current modelview matrix - glMatrixMode( GL_MODELVIEW ); - glLoadMatrix(itr->second.ptr()); - - - CellMatrixMap::const_iterator pitr = _previousCellMatrixMap.find(itr->first); - if (pitr != _previousCellMatrixMap.end()) - { - // load previous frame modelview matrix for motion blurr effect - glMatrixMode( GL_TEXTURE ); - glLoadMatrix(pitr->second.ptr()); - } - else - { - // use current modelview matrix as "previous" frame value, cancelling motion blurr effect - glMatrixMode( GL_TEXTURE ); - glLoadMatrix(itr->second.ptr()); - } - - _geometry->draw(state); - - } - - // restore OpenGL matrices - glMatrixMode( GL_TEXTURE ); - glPopMatrix(); - glMatrixMode( GL_MODELVIEW ); - glPopMatrix(); - - -} diff --git a/examples/osgprecipitation/PrecipitationDrawable.h b/examples/osgprecipitation/PrecipitationDrawable.h deleted file mode 100644 index 5edc5932d..000000000 --- a/examples/osgprecipitation/PrecipitationDrawable.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 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. -*/ - -#ifndef OSGPARTICLE_PRECIPITATIODRAWABLE -#define OSGPARTICLE_PRECIPITATIODRAWABLE - -#include -#include - -#include "PrecipitationParameters.h" - -namespace osgParticle -{ - - class OSGPARTICLE_EXPORT PrecipitationDrawable : public osg::Drawable - { - public: - - PrecipitationDrawable(); - PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); - - META_Object(osgParticle, PrecipitationDrawable); - - virtual bool supports(const osg::PrimitiveFunctor&) const { return false; } - virtual void accept(osg::PrimitiveFunctor&) const {} - virtual bool supports(const osg::PrimitiveIndexFunctor&) const { return false; } - virtual void accept(osg::PrimitiveIndexFunctor&) const {} - - void setParameters(PrecipitationParameters* parameters); - PrecipitationParameters* getParameters() { return _parameters.get(); } - const PrecipitationParameters* getParameters() const { return _parameters.get(); } - - void setGeometry(osg::Geometry* geom) { _geometry = geom; } - osg::Geometry* getGeometry() { return _geometry.get(); } - const osg::Geometry* getGeometry() const { return _geometry.get(); } - - virtual void compileGLObjects(osg::State& state) const; - - virtual void drawImplementation(osg::State& state) const; - - - - struct Cell - { - Cell(int in_i, int in_j, int in_k): - i(in_i), j(in_j), k(in_k) {} - - - inline bool operator == (const Cell& rhs) const - { - return i==rhs.i && j==rhs.j && k==rhs.k; - } - - inline bool operator != (const Cell& rhs) const - { - return i!=rhs.i || j!=rhs.j || k!=rhs.k; - } - - inline bool operator < (const Cell& rhs) const - { - if (irhs.i) return false; - if (jrhs.j) return false; - if (krhs.k) return false; - return false; - } - - int i; - int j; - int k; - }; - - typedef std::map< Cell, osg::Matrix > CellMatrixMap; - - CellMatrixMap& getCurrentCellMatrixMap() { return _currentCellMatrixMap; } - CellMatrixMap& getPreviousCellMatrixMap() { return _previousCellMatrixMap; } - - inline void newFrame() - { - _previousCellMatrixMap.swap(_currentCellMatrixMap); - _currentCellMatrixMap.clear(); - } - - protected: - - virtual ~PrecipitationDrawable() {} - - osg::ref_ptr _parameters; - - osg::ref_ptr _geometry; - - - mutable CellMatrixMap _currentCellMatrixMap; - mutable CellMatrixMap _previousCellMatrixMap; - - }; - -} - -#endif diff --git a/examples/osgprecipitation/PrecipitationEffect.cpp b/examples/osgprecipitation/PrecipitationEffect.cpp index b1973f215..3045d4712 100644 --- a/examples/osgprecipitation/PrecipitationEffect.cpp +++ b/examples/osgprecipitation/PrecipitationEffect.cpp @@ -178,8 +178,6 @@ void PrecipitationEffect::traverse(osg::NodeVisitor& nv) precipitationDrawableSet._pointPrecipitationDrawable = new PrecipitationDrawable; precipitationDrawableSet._pointPrecipitationDrawable->setGeometry(_pointGeometry.get()); precipitationDrawableSet._pointPrecipitationDrawable->setStateSet(_pointStateSet.get()); - - precipitationDrawableSet.setParameters(_parameters.get()); } cull(precipitationDrawableSet, cv); @@ -220,15 +218,6 @@ void PrecipitationEffect::setParameters(PrecipitationParameters* parameters) if (_parameters==parameters) return; _parameters = parameters; - - // inform the PrecipitationDrawable about the change. - OpenThreads::ScopedLock lock(_mutex); - for(ViewDrawableMap::iterator itr=_viewDrawableMap.begin(); - itr!=_viewDrawableMap.end(); - ++itr) - { - (itr->second).setParameters(parameters); - } } void PrecipitationEffect::update() @@ -272,7 +261,7 @@ void PrecipitationEffect::update() float cellVolume = length_u*length_v*length_w; // time taken to get from start to the end of cycle - float period = fabsf(_parameters->cellSizeZ / _parameters->particleVelocity.z()); + _period = fabsf(_parameters->cellSizeZ / _parameters->particleVelocity.z()); _du.set(length_u, 0.0f, 0.0f); _dv.set(0.0f, length_v, 0.0f); @@ -318,8 +307,6 @@ void PrecipitationEffect::update() precipitationDrawableSet._pointPrecipitationDrawable->setGeometry(_pointGeometry.get()); precipitationDrawableSet._pointPrecipitationDrawable->setStateSet(_pointStateSet.get()); - precipitationDrawableSet.setParameters(_parameters.get()); - } } @@ -329,11 +316,9 @@ void PrecipitationEffect::update() const osg::BoundingBox& bb = _parameters->boundingBox; - osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period); - //osg::Uniform* startTime = new osg::Uniform("startTime",0.0f); + osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/_period); _precipitationStateSet->addUniform(inversePeriodUniform); // float - //stateset->addUniform(startTime); // float _precipitationStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); _precipitationStateSet->setMode(GL_BLEND, osg::StateAttribute::ON); @@ -694,8 +679,6 @@ void PrecipitationEffect::cull(PrecipitationDrawableSet& pds, osgUtil::CullVisit float eye_i = eye_kPlane*_inverse_du; float eye_j = eye_kPlane*_inverse_dv; - float _startTime = 0.0f; - osg::Polytope frustum; frustum.setToUnitFrustum(false,false); frustum.transformProvidingInverse(cv->getProjectionMatrix()); @@ -718,13 +701,19 @@ void PrecipitationEffect::cull(PrecipitationDrawableSet& pds, osgUtil::CullVisit unsigned int numTested=0; unsigned int numInFrustum=0; + float iCyle = 0.43; + float jCyle = 0.64; + for(int i = i_min; i<=i_max; ++i) { for(int j = j_min; j<=j_max; ++j) { for(int k = k_min; k<=k_max; ++k) { - if (build(eyeLocal, i,j,k, pds, frustum, cv)) ++numInFrustum; + float startTime = (float)(i)*iCyle + (float)(j)*jCyle; + startTime = (startTime-floor(startTime))*_period; + + if (build(eyeLocal, i,j,k, startTime, pds, frustum, cv)) ++numInFrustum; ++numTested; } } @@ -732,11 +721,11 @@ void PrecipitationEffect::cull(PrecipitationDrawableSet& pds, osgUtil::CullVisit osg::Timer_t endTick = osg::Timer::instance()->tick(); -// osg::notify(osg::NOTICE)<<"time for cull "<delta_m(startTick,endTick)<<"ms numTested="<getCurrentCellMatrixMap().size()<<" lines "<getCurrentCellMatrixMap().size()<<" points "<getCurrentCellMatrixMap().size()<delta_m(startTick,endTick)<<"ms numTested="<getCurrentCellMatrixMap().size()<<" lines "<getCurrentCellMatrixMap().size()<<" points "<getCurrentCellMatrixMap().size()<nearTransition) { - mymodelview = &(pds._quadPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]); + PrecipitationDrawable::MatrixStartTimePair& mstp = pds._quadPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]; + mymodelview = &mstp.first; + mstp.second = startTime; } else if (distance <= _parameters->farTransition) { if (_parameters->useFarLineSegments) { - mymodelview = &(pds._linePrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]); + PrecipitationDrawable::MatrixStartTimePair& mstp = pds._linePrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]; + mymodelview = &mstp.first; + mstp.second = startTime; } else { - mymodelview = &(pds._pointPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]); + PrecipitationDrawable::MatrixStartTimePair& mstp = pds._pointPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]; + mymodelview = &mstp.first; + mstp.second = startTime; } } else @@ -776,3 +771,72 @@ bool PrecipitationEffect::build(const osg::Vec3 eyeLocal, int i, int j, int k, P return true; } + + +///////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Precipitation Drawable +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +PrecipitationEffect::PrecipitationDrawable::PrecipitationDrawable() +{ + setSupportsDisplayList(false); +} + +PrecipitationEffect::PrecipitationDrawable::PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop): + Drawable(copy,copyop) +{ +} + +void PrecipitationEffect::PrecipitationDrawable::drawImplementation(osg::State& state) const +{ + if (!_geometry) return; + + const osg::Geometry::Extensions* extensions = osg::Geometry::getExtensions(state.getContextID(),true); + + // save OpenGL matrices + glPushMatrix(); + glMatrixMode( GL_TEXTURE ); + glPushMatrix(); + + state.setActiveTextureUnit(0); + + for(CellMatrixMap::const_iterator itr = _currentCellMatrixMap.begin(); + itr != _currentCellMatrixMap.end(); + ++itr) + { + + extensions->glMultiTexCoord1f(GL_TEXTURE0+1, itr->second.second); + + // load cells current modelview matrix + glMatrixMode( GL_MODELVIEW ); + glLoadMatrix(itr->second.first.ptr()); + + + CellMatrixMap::const_iterator pitr = _previousCellMatrixMap.find(itr->first); + if (pitr != _previousCellMatrixMap.end()) + { + // load previous frame modelview matrix for motion blurr effect + glMatrixMode( GL_TEXTURE ); + glLoadMatrix(pitr->second.first.ptr()); + } + else + { + // use current modelview matrix as "previous" frame value, cancelling motion blurr effect + glMatrixMode( GL_TEXTURE ); + glLoadMatrix(itr->second.first.ptr()); + } + + _geometry->draw(state); + + } + + // restore OpenGL matrices + glMatrixMode( GL_TEXTURE ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); + + +} diff --git a/examples/osgprecipitation/PrecipitationEffect.h b/examples/osgprecipitation/PrecipitationEffect.h index c9ba630d3..aea67a45f 100644 --- a/examples/osgprecipitation/PrecipitationEffect.h +++ b/examples/osgprecipitation/PrecipitationEffect.h @@ -18,12 +18,13 @@ #include #include #include +#include #include #include -#include "PrecipitationDrawable.h" +#include "PrecipitationParameters.h" namespace osgParticle { @@ -63,22 +64,91 @@ namespace osgParticle void setUpGeometries(unsigned int numParticles); + class OSGPARTICLE_EXPORT PrecipitationDrawable : public osg::Drawable + { + public: + + PrecipitationDrawable(); + PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); + + META_Object(osgParticle, PrecipitationDrawable); + + virtual bool supports(const osg::PrimitiveFunctor&) const { return false; } + virtual void accept(osg::PrimitiveFunctor&) const {} + virtual bool supports(const osg::PrimitiveIndexFunctor&) const { return false; } + virtual void accept(osg::PrimitiveIndexFunctor&) const {} + + void setGeometry(osg::Geometry* geom) { _geometry = geom; } + osg::Geometry* getGeometry() { return _geometry.get(); } + const osg::Geometry* getGeometry() const { return _geometry.get(); } + + virtual void drawImplementation(osg::State& state) const; + + struct Cell + { + Cell(int in_i, int in_j, int in_k): + i(in_i), j(in_j), k(in_k) {} + + + inline bool operator == (const Cell& rhs) const + { + return i==rhs.i && j==rhs.j && k==rhs.k; + } + + inline bool operator != (const Cell& rhs) const + { + return i!=rhs.i || j!=rhs.j || k!=rhs.k; + } + + inline bool operator < (const Cell& rhs) const + { + if (irhs.i) return false; + if (jrhs.j) return false; + if (krhs.k) return false; + return false; + } + + int i; + int j; + int k; + }; + + typedef std::pair MatrixStartTimePair; + + typedef std::map< Cell, MatrixStartTimePair > CellMatrixMap; + + CellMatrixMap& getCurrentCellMatrixMap() { return _currentCellMatrixMap; } + CellMatrixMap& getPreviousCellMatrixMap() { return _previousCellMatrixMap; } + + inline void newFrame() + { + _previousCellMatrixMap.swap(_currentCellMatrixMap); + _currentCellMatrixMap.clear(); + } + + protected: + + virtual ~PrecipitationDrawable() {} + + osg::ref_ptr _geometry; + + mutable CellMatrixMap _currentCellMatrixMap; + mutable CellMatrixMap _previousCellMatrixMap; + + }; + struct PrecipitationDrawableSet { - void setParameters(PrecipitationParameters* parameters) - { - if (_quadPrecipitationDrawable.valid()) _quadPrecipitationDrawable->setParameters(parameters); - if (_linePrecipitationDrawable.valid()) _linePrecipitationDrawable->setParameters(parameters); - if (_pointPrecipitationDrawable.valid()) _pointPrecipitationDrawable->setParameters(parameters); - } - osg::ref_ptr _quadPrecipitationDrawable; osg::ref_ptr _linePrecipitationDrawable; osg::ref_ptr _pointPrecipitationDrawable; }; void cull(PrecipitationDrawableSet& pds, osgUtil::CullVisitor* cv) const; - bool build(const osg::Vec3 eyeLocal, int i, int j, int k, PrecipitationDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const; + bool build(const osg::Vec3 eyeLocal, int i, int j, int k, float startTime, PrecipitationDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const; osg::ref_ptr _parameters; @@ -105,13 +175,14 @@ namespace osgParticle osg::ref_ptr _pointStateSet; - osg::Vec3 _origin; - osg::Vec3 _du; - osg::Vec3 _dv; - osg::Vec3 _dw; - osg::Vec3 _inverse_du; - osg::Vec3 _inverse_dv; - osg::Vec3 _inverse_dw; + float _period; + osg::Vec3 _origin; + osg::Vec3 _du; + osg::Vec3 _dv; + osg::Vec3 _dw; + osg::Vec3 _inverse_du; + osg::Vec3 _inverse_dv; + osg::Vec3 _inverse_dw; }; diff --git a/examples/osgprecipitation/PrecipitationParameters.h b/examples/osgprecipitation/PrecipitationParameters.h index 68767290a..8bfe2362b 100644 --- a/examples/osgprecipitation/PrecipitationParameters.h +++ b/examples/osgprecipitation/PrecipitationParameters.h @@ -61,7 +61,7 @@ namespace osgParticle void snow(float intensity) { - particleVelocity = osg::Vec3(0.0,0.0,-1.0) + osg::Vec3(0.0,0.0,-0.5)*intensity; + particleVelocity = osg::Vec3(0.0,0.0,-0.75) + osg::Vec3(0.0,0.0,-0.25)*intensity; particleSize = 0.02 + 0.03*intensity; particleColour = osg::Vec4(0.85f, 0.85f, 0.85f, 1.0f) - osg::Vec4(0.1f, 0.1f, 0.1f, 1.0f)* intensity; particleDensity = intensity * 8.2f;