Implemented seemless update of precipitation properties.
This commit is contained in:
@@ -31,71 +31,19 @@ class MyGustCallback : public osg::NodeCallback
|
||||
osgParticle::PrecipitationEffect* pe = dynamic_cast<osgParticle::PrecipitationEffect*>(node);
|
||||
|
||||
float value = sin(nv->getFrameStamp()->getReferenceTime());
|
||||
if (value<-0.5) pe->setWind(osg::Vec3(5.0f,0.0f,0.0f));
|
||||
else pe->setWind(osg::Vec3(1.0,0.0,0.0));
|
||||
if (value<-0.5)
|
||||
{
|
||||
pe->snow(1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
pe->rain(0.5);
|
||||
}
|
||||
|
||||
traverse(node, nv);
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
osg::Node* createModel(osg::Node* loadedModel, osgParticle::PrecipitationParameters& parameters)
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
|
||||
osg::BoundingBox bb(0.0, 0.0, 0.0, 100.0, 100.0, 100.0);
|
||||
|
||||
if (loadedModel)
|
||||
{
|
||||
group->addChild(loadedModel);
|
||||
|
||||
osg::BoundingSphere bs = loadedModel->getBound();
|
||||
|
||||
bb.set( -500, -500, 0, +500, +500, 10);
|
||||
|
||||
parameters.boundingBox = bb;
|
||||
|
||||
osg::StateSet* stateset = loadedModel->getOrCreateStateSet();
|
||||
|
||||
osg::Fog* fog = new osg::Fog;
|
||||
|
||||
if (parameters.fogExponent<1.0)
|
||||
{
|
||||
fog->setMode(osg::Fog::LINEAR);
|
||||
}
|
||||
else if (parameters.fogExponent<2.0)
|
||||
{
|
||||
fog->setMode(osg::Fog::EXP);
|
||||
}
|
||||
else
|
||||
{
|
||||
fog->setMode(osg::Fog::EXP2);
|
||||
}
|
||||
|
||||
fog->setDensity(parameters.fogDensity);
|
||||
fog->setStart(0.0f);
|
||||
fog->setEnd(parameters.fogEnd);
|
||||
fog->setColor(parameters.fogColour);
|
||||
stateset->setAttributeAndModes(fog, osg::StateAttribute::ON);
|
||||
|
||||
osg::LightSource* lightSource = new osg::LightSource;
|
||||
group->addChild(lightSource);
|
||||
|
||||
osg::Light* light = lightSource->getLight();
|
||||
light->setLightNum(0);
|
||||
light->setPosition(osg::Vec4(0.0f,0.0f,1.0f,0.0f)); // directional light from above
|
||||
light->setAmbient(osg::Vec4(0.8f,0.8f,0.8f,1.0f));
|
||||
light->setDiffuse(osg::Vec4(0.2f,0.2f,0.2f,1.0f));
|
||||
light->setSpecular(osg::Vec4(0.2f,0.2f,0.2f,1.0f));
|
||||
|
||||
|
||||
}
|
||||
|
||||
group->addChild(createCellRainEffect(parameters));
|
||||
|
||||
return group;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
@@ -172,9 +120,6 @@ int main( int argc, char **argv )
|
||||
|
||||
viewer.setClearColor( precipitationEffect->getFog()->getColor() );
|
||||
|
||||
// now force the effect to update all its internal state.
|
||||
precipitationEffect->update();
|
||||
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
@@ -222,8 +167,6 @@ int main( int argc, char **argv )
|
||||
light->setSpecular(osg::Vec4(0.2f,0.2f,0.2f,1.0f));
|
||||
|
||||
|
||||
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(group.get());
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
class OSGPARTICLE_EXPORT PrecipitationEffect : public osg::Group
|
||||
class OSGPARTICLE_EXPORT PrecipitationEffect : public osg::Node
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -45,12 +45,8 @@ namespace osgParticle
|
||||
|
||||
/** Set all the parameters to create an snow effect of specified intensity.*/
|
||||
void snow(float intensity);
|
||||
|
||||
|
||||
void setIntensity(float intensity) { _intensity = intensity; }
|
||||
float getIntensity() const { return _intensity; }
|
||||
|
||||
void setMaximumParticleDensity(float density) { _maximumParticleDensity = density; }
|
||||
void setMaximumParticleDensity(float density) { if (_maximumParticleDensity==density) return; _maximumParticleDensity = density; _dirty = true;}
|
||||
float setMaximumParticleDensity() const { return _maximumParticleDensity; }
|
||||
|
||||
void setWind(const osg::Vec3& wind) { _wind = wind; }
|
||||
@@ -59,16 +55,16 @@ namespace osgParticle
|
||||
void setPosition(const osg::Vec3& position) { _origin = position; }
|
||||
const osg::Vec3& getPosition() const { return _origin; }
|
||||
|
||||
void setCellSize(const osg::Vec3& cellSize) { _cellSize = cellSize; }
|
||||
void setCellSize(const osg::Vec3& cellSize) { if (_cellSize==cellSize) return; _cellSize = cellSize; _dirty = true; }
|
||||
const osg::Vec3& getCellSize() const { return _cellSize; }
|
||||
|
||||
void setParticleSpeed(float particleSpeed) { _particleSpeed = particleSpeed; }
|
||||
void setParticleSpeed(float particleSpeed) { if (_particleSpeed==particleSpeed) return; _particleSpeed = particleSpeed; _dirty = true; }
|
||||
float getParticleSpeed() const { return _particleSpeed; }
|
||||
|
||||
void setParticleSize(float particleSize) { _particleSize = particleSize; }
|
||||
void setParticleSize(float particleSize) { if (_particleSize==particleSize) return; _particleSize = particleSize; _dirty = true;}
|
||||
float getParticleSize() const { return _particleSize; }
|
||||
|
||||
void setParticleColor(const osg::Vec4& color) { _particleColor = color; }
|
||||
void setParticleColor(const osg::Vec4& color) { if (_particleColor==color) return; _particleColor = color; _dirty = true;}
|
||||
const osg::Vec4& getParticleColor() const { return _particleColor; }
|
||||
|
||||
void setNearTransition(float nearTransition) { _nearTransition = nearTransition; }
|
||||
@@ -81,14 +77,19 @@ namespace osgParticle
|
||||
osg::Fog* getFog() { return _fog.get(); }
|
||||
const osg::Fog* getFog() const { return _fog.get(); }
|
||||
|
||||
void compileGLObjects(osg::State& state) const;
|
||||
|
||||
osg::Geometry* getQuadGeometry() { return _quadGeometry.get(); }
|
||||
osg::StateSet* getQuadStateSet() { return _quadStateSet.get(); }
|
||||
|
||||
void update();
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~PrecipitationEffect() {}
|
||||
|
||||
void compileGLObjects(osg::State& state) const;
|
||||
|
||||
void update();
|
||||
|
||||
void createGeometry(unsigned int numParticles,
|
||||
osg::Geometry* quad_geometry,
|
||||
osg::Geometry* line_geometry,
|
||||
@@ -116,6 +117,12 @@ namespace osgParticle
|
||||
void setGeometry(osg::Geometry* geom) { _geometry = geom; }
|
||||
osg::Geometry* getGeometry() { return _geometry.get(); }
|
||||
const osg::Geometry* getGeometry() const { return _geometry.get(); }
|
||||
|
||||
void setDrawType(GLenum type) { _drawType = type; }
|
||||
GLenum getDrawType() const { return _drawType; }
|
||||
|
||||
void setNumberOfVertices(unsigned int numVertices) { _numberOfVertices = numVertices; }
|
||||
unsigned int getNumberOfVertices() const { return _numberOfVertices; }
|
||||
|
||||
virtual void drawImplementation(osg::State& state) const;
|
||||
|
||||
@@ -182,6 +189,9 @@ namespace osgParticle
|
||||
|
||||
mutable CellMatrixMap _currentCellMatrixMap;
|
||||
mutable CellMatrixMap _previousCellMatrixMap;
|
||||
|
||||
GLenum _drawType;
|
||||
unsigned int _numberOfVertices;
|
||||
|
||||
};
|
||||
|
||||
@@ -196,18 +206,21 @@ namespace osgParticle
|
||||
bool build(const osg::Vec3 eyeLocal, int i, int j, int k, float startTime, PrecipitationDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const;
|
||||
|
||||
// parameters
|
||||
osg::BoundingBox _boundingBox;
|
||||
float _intensity;
|
||||
osg::Vec3 _wind;
|
||||
float _particleSpeed;
|
||||
float _particleSize;
|
||||
osg::Vec4 _particleColor;
|
||||
float _maximumParticleDensity;
|
||||
osg::Vec3 _cellSize;
|
||||
float _nearTransition;
|
||||
float _farTransition;
|
||||
bool _useFarLineSegments;
|
||||
osg::ref_ptr<osg::Fog> _fog;
|
||||
bool _dirty;
|
||||
osg::Vec3 _wind;
|
||||
float _particleSpeed;
|
||||
float _particleSize;
|
||||
osg::Vec4 _particleColor;
|
||||
float _maximumParticleDensity;
|
||||
osg::Vec3 _cellSize;
|
||||
float _nearTransition;
|
||||
float _farTransition;
|
||||
bool _useFarLineSegments;
|
||||
osg::ref_ptr<osg::Fog> _fog;
|
||||
|
||||
osg::ref_ptr<osg::Uniform> _inversePeriodUniform;
|
||||
osg::ref_ptr<osg::Uniform> _particleSizeUniform;
|
||||
osg::ref_ptr<osg::Uniform> _particleColorUniform;
|
||||
|
||||
typedef std::pair< osg::NodeVisitor*, osg::NodePath > ViewIdenitifier;
|
||||
typedef std::map< ViewIdenitifier, PrecipitationDrawableSet > ViewDrawableMap;
|
||||
@@ -215,8 +228,6 @@ namespace osgParticle
|
||||
OpenThreads::Mutex _mutex;
|
||||
ViewDrawableMap _viewDrawableMap;
|
||||
|
||||
osg::ref_ptr<osg::StateSet> _precipitationStateSet;
|
||||
|
||||
osg::ref_ptr<osg::Geometry> _quadGeometry;
|
||||
osg::ref_ptr<osg::StateSet> _quadStateSet;
|
||||
|
||||
|
||||
@@ -106,12 +106,14 @@ static osg::Image* createSpotLightImage(const osg::Vec4& centerColour, const osg
|
||||
PrecipitationEffect::PrecipitationEffect()
|
||||
{
|
||||
setNumChildrenRequiringUpdateTraversal(1);
|
||||
|
||||
setUpGeometries(1024);
|
||||
|
||||
rain(0.5);
|
||||
}
|
||||
|
||||
void PrecipitationEffect::rain(float intensity)
|
||||
{
|
||||
_intensity = 1.0f;
|
||||
_wind.set(0.0f,0.0f,0.0f);
|
||||
_particleSpeed = -2.0f + -5.0f*intensity;
|
||||
_particleSize = 0.01 + 0.02*intensity;
|
||||
@@ -129,12 +131,13 @@ void PrecipitationEffect::rain(float intensity)
|
||||
|
||||
_useFarLineSegments = false;
|
||||
|
||||
_dirty = true;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void PrecipitationEffect::snow(float intensity)
|
||||
{
|
||||
_intensity = 1.0f;
|
||||
_wind.set(0.0f,0.0f,0.0f);
|
||||
_particleSpeed = -0.75f - 0.25f*intensity;
|
||||
_particleSize = 0.02f + 0.03f*intensity;
|
||||
@@ -152,13 +155,16 @@ void PrecipitationEffect::snow(float intensity)
|
||||
|
||||
_useFarLineSegments = false;
|
||||
|
||||
_dirty = true;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
PrecipitationEffect::PrecipitationEffect(const PrecipitationEffect& copy, const osg::CopyOp& copyop):
|
||||
osg::Group(copy,copyop)
|
||||
osg::Node(copy,copyop)
|
||||
{
|
||||
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
|
||||
_dirty = true;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -188,6 +194,8 @@ void PrecipitationEffect::traverse(osg::NodeVisitor& nv)
|
||||
{
|
||||
if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR)
|
||||
{
|
||||
if (_dirty) update();
|
||||
|
||||
if (nv.getFrameStamp())
|
||||
{
|
||||
double currentTime = nv.getFrameStamp()->getReferenceTime();
|
||||
@@ -197,12 +205,13 @@ void PrecipitationEffect::traverse(osg::NodeVisitor& nv)
|
||||
previousTime = currentTime;
|
||||
}
|
||||
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nv.getVisitorType() == osg::NodeVisitor::NODE_VISITOR)
|
||||
{
|
||||
if (_dirty) update();
|
||||
|
||||
osgUtil::GLObjectsVisitor* globjVisitor = dynamic_cast<osgUtil::GLObjectsVisitor*>(&nv);
|
||||
if (globjVisitor)
|
||||
{
|
||||
@@ -212,21 +221,18 @@ void PrecipitationEffect::traverse(osg::NodeVisitor& nv)
|
||||
}
|
||||
}
|
||||
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (nv.getVisitorType() != osg::NodeVisitor::CULL_VISITOR)
|
||||
{
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
|
||||
osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
|
||||
if (!cv)
|
||||
{
|
||||
Group::traverse(nv);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -246,21 +252,24 @@ void PrecipitationEffect::traverse(osg::NodeVisitor& nv)
|
||||
precipitationDrawableSet->_quadPrecipitationDrawable->setRequiresPreviousMatrix(true);
|
||||
precipitationDrawableSet->_quadPrecipitationDrawable->setGeometry(_quadGeometry.get());
|
||||
precipitationDrawableSet->_quadPrecipitationDrawable->setStateSet(_quadStateSet.get());
|
||||
|
||||
precipitationDrawableSet->_quadPrecipitationDrawable->setDrawType(GL_QUADS);
|
||||
|
||||
precipitationDrawableSet->_linePrecipitationDrawable = new PrecipitationDrawable;
|
||||
precipitationDrawableSet->_linePrecipitationDrawable->setRequiresPreviousMatrix(true);
|
||||
precipitationDrawableSet->_linePrecipitationDrawable->setGeometry(_lineGeometry.get());
|
||||
precipitationDrawableSet->_linePrecipitationDrawable->setStateSet(_lineStateSet.get());
|
||||
precipitationDrawableSet->_linePrecipitationDrawable->setDrawType(GL_LINES);
|
||||
|
||||
precipitationDrawableSet->_pointPrecipitationDrawable = new PrecipitationDrawable;
|
||||
precipitationDrawableSet->_pointPrecipitationDrawable->setRequiresPreviousMatrix(false);
|
||||
precipitationDrawableSet->_pointPrecipitationDrawable->setGeometry(_pointGeometry.get());
|
||||
precipitationDrawableSet->_pointPrecipitationDrawable->setStateSet(_pointStateSet.get());
|
||||
precipitationDrawableSet->_pointPrecipitationDrawable->setDrawType(GL_POINTS);
|
||||
}
|
||||
|
||||
cull(*precipitationDrawableSet, cv);
|
||||
|
||||
cv->pushStateSet(_precipitationStateSet.get());
|
||||
cv->pushStateSet(_stateset.get());
|
||||
float depth = 0.0f;
|
||||
|
||||
if (!precipitationDrawableSet->_quadPrecipitationDrawable->getCurrentCellMatrixMap().empty())
|
||||
@@ -287,20 +296,17 @@ void PrecipitationEffect::traverse(osg::NodeVisitor& nv)
|
||||
cv->popStateSet();
|
||||
|
||||
}
|
||||
|
||||
Group::traverse(nv);
|
||||
}
|
||||
|
||||
void PrecipitationEffect::update()
|
||||
{
|
||||
_dirty = false;
|
||||
|
||||
osg::notify(osg::INFO)<<"PrecipitationEffect::update()"<<std::endl;
|
||||
|
||||
float length_u = _cellSize.x();
|
||||
float length_v = _cellSize.y();
|
||||
float length_w = _cellSize.z();
|
||||
|
||||
// volume of a single cell
|
||||
float cellVolume = length_u*length_v*length_w;
|
||||
|
||||
// time taken to get from start to the end of cycle
|
||||
_period = fabsf(_cellSize.z() / _particleSpeed);
|
||||
@@ -316,19 +322,8 @@ void PrecipitationEffect::update()
|
||||
osg::notify(osg::INFO)<<"Cell size X="<<length_u<<std::endl;
|
||||
osg::notify(osg::INFO)<<"Cell size Y="<<length_v<<std::endl;
|
||||
osg::notify(osg::INFO)<<"Cell size Z="<<length_w<<std::endl;
|
||||
|
||||
|
||||
osg::BoundingBox& bb = _boundingBox;
|
||||
if (bb.valid())
|
||||
{
|
||||
_origin.set(bb.xMin(), bb.yMin(), bb.zMin());
|
||||
}
|
||||
else
|
||||
{
|
||||
_origin.set(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
setUpGeometries((int)(_maximumParticleDensity * cellVolume));
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
_viewDrawableMap.clear();
|
||||
@@ -336,23 +331,38 @@ void PrecipitationEffect::update()
|
||||
|
||||
// set up state/
|
||||
{
|
||||
_precipitationStateSet = new osg::StateSet;
|
||||
if (!_stateset)
|
||||
{
|
||||
_stateset = new osg::StateSet;
|
||||
_stateset->addUniform(new osg::Uniform("baseTexture",0));
|
||||
|
||||
osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/_period);
|
||||
_stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
_stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
|
||||
_precipitationStateSet->addUniform(inversePeriodUniform); // float
|
||||
osg::Texture2D* texture = new osg::Texture2D(createSpotLightImage(osg::Vec4(1.0f,1.0f,1.0f,1.0f),osg::Vec4(1.0f,1.0f,1.0f,0.0f),32,1.0));
|
||||
_stateset->setTextureAttribute(0, texture);
|
||||
}
|
||||
|
||||
_precipitationStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
_precipitationStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
if (!_inversePeriodUniform)
|
||||
{
|
||||
_inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/_period);
|
||||
_stateset->addUniform(_inversePeriodUniform.get());
|
||||
}
|
||||
else _inversePeriodUniform->set(1.0f/_period);
|
||||
|
||||
osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0);
|
||||
_precipitationStateSet->addUniform(baseTextureSampler);
|
||||
|
||||
osg::Texture2D* texture = new osg::Texture2D(createSpotLightImage(osg::Vec4(1.0f,1.0f,1.0f,1.0f),osg::Vec4(1.0f,1.0f,1.0f,0.0f),32,1.0));
|
||||
_precipitationStateSet->setTextureAttribute(0, texture);
|
||||
|
||||
_precipitationStateSet->addUniform(new osg::Uniform("particleColour", _particleColor));
|
||||
_precipitationStateSet->addUniform(new osg::Uniform("particleSize", _particleSize));
|
||||
if (!_particleSizeUniform)
|
||||
{
|
||||
_particleColorUniform = new osg::Uniform("particleColour", _particleColor);
|
||||
_stateset->addUniform(_particleColorUniform.get());
|
||||
}
|
||||
else _particleColorUniform->set(_particleColor);
|
||||
|
||||
if (!_particleSizeUniform)
|
||||
{
|
||||
_particleSizeUniform = new osg::Uniform("particleSize", _particleSize);
|
||||
_stateset->addUniform(_particleSizeUniform.get());
|
||||
}
|
||||
else _particleSizeUniform->set(_particleSize);
|
||||
|
||||
}
|
||||
|
||||
@@ -387,7 +397,6 @@ void PrecipitationEffect::createGeometry(unsigned int numParticles,
|
||||
|
||||
quad_geometry->setVertexArray(quad_vertices);
|
||||
quad_geometry->setTexCoordArray(0, quad_offsets);
|
||||
quad_geometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, numParticles*4));
|
||||
}
|
||||
|
||||
// configure line_geometry;
|
||||
@@ -402,7 +411,6 @@ void PrecipitationEffect::createGeometry(unsigned int numParticles,
|
||||
|
||||
line_geometry->setVertexArray(line_vertices);
|
||||
line_geometry->setTexCoordArray(0, line_offsets);
|
||||
line_geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, numParticles*2));
|
||||
}
|
||||
|
||||
// configure point_geometry;
|
||||
@@ -417,7 +425,6 @@ void PrecipitationEffect::createGeometry(unsigned int numParticles,
|
||||
|
||||
point_geometry->setVertexArray(point_vertices);
|
||||
point_geometry->setTexCoordArray(0, point_offsets);
|
||||
point_geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, numParticles));
|
||||
}
|
||||
|
||||
// set up vertex attribute data.
|
||||
@@ -462,6 +469,7 @@ void PrecipitationEffect::setUpGeometries(unsigned int numParticles)
|
||||
unsigned int lineRenderBin = 12;
|
||||
unsigned int pointRenderBin = 11;
|
||||
|
||||
|
||||
osg::notify(osg::INFO)<<"PrecipitationEffect::setUpGeometries("<<numParticles<<")"<<std::endl;
|
||||
|
||||
bool needGeometryRebuild = false;
|
||||
@@ -709,6 +717,15 @@ void PrecipitationEffect::cull(PrecipitationDrawableSet& pds, osgUtil::CullVisit
|
||||
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
||||
#endif
|
||||
|
||||
float cellVolume = _cellSize.x() * _cellSize.y() * _cellSize.z();
|
||||
int numberOfParticles = (int)(_maximumParticleDensity * cellVolume);
|
||||
|
||||
if (numberOfParticles==0) return;
|
||||
|
||||
pds._quadPrecipitationDrawable->setNumberOfVertices(numberOfParticles*4);
|
||||
pds._linePrecipitationDrawable->setNumberOfVertices(numberOfParticles*2);
|
||||
pds._pointPrecipitationDrawable->setNumberOfVertices(numberOfParticles);
|
||||
|
||||
pds._quadPrecipitationDrawable->newFrame();
|
||||
pds._linePrecipitationDrawable->newFrame();
|
||||
pds._pointPrecipitationDrawable->newFrame();
|
||||
@@ -836,7 +853,9 @@ bool PrecipitationEffect::build(const osg::Vec3 eyeLocal, int i, int j, int k, f
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PrecipitationEffect::PrecipitationDrawable::PrecipitationDrawable():
|
||||
_requiresPreviousMatrix(true)
|
||||
_requiresPreviousMatrix(true),
|
||||
_drawType(GL_QUADS),
|
||||
_numberOfVertices(0)
|
||||
{
|
||||
setSupportsDisplayList(false);
|
||||
}
|
||||
@@ -844,7 +863,9 @@ PrecipitationEffect::PrecipitationDrawable::PrecipitationDrawable():
|
||||
PrecipitationEffect::PrecipitationDrawable::PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop):
|
||||
Drawable(copy,copyop),
|
||||
_requiresPreviousMatrix(copy._requiresPreviousMatrix),
|
||||
_geometry(copy._geometry)
|
||||
_geometry(copy._geometry),
|
||||
_drawType(copy._drawType),
|
||||
_numberOfVertices(copy._numberOfVertices)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -912,41 +933,8 @@ void PrecipitationEffect::PrecipitationDrawable::drawImplementation(osg::State&
|
||||
|
||||
_geometry->draw(state);
|
||||
|
||||
}
|
||||
|
||||
for(CellMatrixMap::const_iterator itr = _currentCellMatrixMap.begin();
|
||||
itr != _currentCellMatrixMap.end();
|
||||
++itr)
|
||||
{
|
||||
extensions->glMultiTexCoord1f(GL_TEXTURE0+1, itr->second.startTime);
|
||||
|
||||
// load cells current modelview matrix
|
||||
if (_requiresPreviousMatrix)
|
||||
{
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadMatrix(itr->second.modelview.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.modelview.ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
// use current modelview matrix as "previous" frame value, cancelling motion blurr effect
|
||||
glMatrixMode( GL_TEXTURE );
|
||||
glLoadMatrix(itr->second.modelview.ptr());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glLoadMatrix(itr->second.modelview.ptr());
|
||||
}
|
||||
|
||||
_geometry->draw(state);
|
||||
|
||||
unsigned int numVertices = osg::minimum(_geometry->getVertexArray()->getNumElements(), _numberOfVertices);
|
||||
glDrawArrays(_drawType, 0, numVertices);
|
||||
}
|
||||
|
||||
// restore OpenGL matrices
|
||||
|
||||
Reference in New Issue
Block a user