HI Michael,

You you send the file zipped up as the file has come through inline
(some emailer inline by default for text files).  More details can be
found at:

   
http://www.openscenegraph.org/projects/osg/wiki/MailingLists/SubmissionsProtocol

Robert.

On Feb 18, 2008 11:22 AM, Michael Ebner <[EMAIL PROTECTED]> wrote:
> Hello,
>
> the osgParticle LOD functionality is still marked experimental. I tested
> it on Win2K and found an error where a std::vector iterator goes beyond
> the end of the vector, which is not handled on Win32 STL implementation.
> Therfore when using particle LOD the application crashed.
>
> Attached is a fix that avoids the iterator problem described above.
> Could someone check (and notify me please) if this patch is ok and if
> this is the only reason why particle LOD is marked experimental?
>
> thanks,
> Michael.
>
>
> #include <osgParticle/ParticleSystem>
>
> #include <vector>
>
> #include <osg/Drawable>
> #include <osg/CopyOp>
> #include <osg/State>
> #include <osg/Matrix>
> #include <osg/GL>
> #include <osg/StateSet>
> #include <osg/Texture2D>
> #include <osg/BlendFunc>
> #include <osg/TexEnv>
> #include <osg/Material>
> #include <osg/Notify>
>
> #include <osgDB/ReadFile>
>
> osgParticle::ParticleSystem::ParticleSystem()
> :    osg::Drawable(),
>     _def_bbox(osg::Vec3(-10, -10, -10), osg::Vec3(10, 10, 10)),
>     _alignment(BILLBOARD),
>     _align_X_axis(1, 0, 0),
>     _align_Y_axis(0, 1, 0),
>     _doublepass(false),
>     _frozen(false),
>     _bmin(0, 0, 0),
>     _bmax(0, 0, 0),
>     _reset_bounds_flag(false),
>     _bounds_computed(false),
>     _def_ptemp(Particle()),
>     _last_frame(0),
>     _freeze_on_cull(false),
>     _detail(1),
>     _draw_count(0)
> {
>     // we don't support display lists because particle systems
>     // are dynamic, and they always changes between frames
>     setSupportsDisplayList(false);
> }
>
> osgParticle::ParticleSystem::ParticleSystem(const ParticleSystem& copy, const 
> osg::CopyOp& copyop)
> :    osg::Drawable(copy, copyop),
>     _def_bbox(copy._def_bbox),
>     _alignment(copy._alignment),
>     _align_X_axis(copy._align_X_axis),
>     _align_Y_axis(copy._align_Y_axis),
>     _doublepass(copy._doublepass),
>     _frozen(copy._frozen),
>     _bmin(copy._bmin),
>     _bmax(copy._bmax),
>     _reset_bounds_flag(copy._reset_bounds_flag),
>     _bounds_computed(copy._bounds_computed),
>     _def_ptemp(copy._def_ptemp),
>     _last_frame(copy._last_frame),
>     _freeze_on_cull(copy._freeze_on_cull),
>     _detail(copy._detail),
>     _draw_count(0)
> {
> }
>
> osgParticle::ParticleSystem::~ParticleSystem()
> {
> }
>
> void osgParticle::ParticleSystem::update(double dt)
> {
>     // reset bounds
>     _reset_bounds_flag = true;
>
>
>     for(unsigned int i=0; i<_particles.size(); ++i)
>     {
>         Particle& particle = _particles[i];
>         if (particle.isAlive())
>         {
>             if (particle.update(dt))
>             {
>                 update_bounds(particle.getPosition(), 
> particle.getCurrentSize());
>             }
>             else
>             {
>                 reuseParticle(i);
>             }
>         }
>     }
>
>     // force recomputing of bounding box on next frame
>     dirtyBound();
> }
>
> void osgParticle::ParticleSystem::drawImplementation(osg::RenderInfo& 
> renderInfo) const
> {
>     osg::State& state = *renderInfo.getState();
>
>     OpenThreads::ScopedReadLock lock(_readWriteMutex);
>
>     // update the frame count, so other objects can detect when
>     // this particle system is culled
>     _last_frame = state.getFrameStamp()->getFrameNumber();
>
>     // get the current modelview matrix
>     osg::Matrix modelview = state.getModelViewMatrix();
>
>     if (_alignment == BILLBOARD)
>         state.applyModelViewMatrix(0);
>
>     // set up depth mask for first rendering pass
>     glPushAttrib(GL_DEPTH_BUFFER_BIT);
>     glDepthMask(GL_FALSE);
>
>     // render, first pass
>     single_pass_render(state, modelview);
>
>     // restore depth mask settings
>     glPopAttrib();
>
>     // render, second pass
>     if (_doublepass) {
>         // set up color mask for second rendering pass
>         glPushAttrib(GL_COLOR_BUFFER_BIT);
>         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
>
>         // render the particles onto the depth buffer
>         single_pass_render(state, modelview);
>
>         // restore color mask settings
>         glPopAttrib();
>     }
> }
>
> void osgParticle::ParticleSystem::setDefaultAttributes(const std::string& 
> texturefile, bool emissive_particles, bool lighting, int texture_unit)
> {
>     osg::StateSet *stateset = new osg::StateSet;
>
>     stateset->setMode(GL_LIGHTING, lighting? osg::StateAttribute::ON: 
> osg::StateAttribute::OFF);
>     stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
>
>     osg::Material *material = new osg::Material;
>     material->setSpecular(osg::Material::FRONT, osg::Vec4(0, 0, 0, 1));
>     material->setEmission(osg::Material::FRONT, osg::Vec4(0, 0, 0, 1));
>     material->setColorMode(lighting? osg::Material::AMBIENT_AND_DIFFUSE : 
> osg::Material::OFF);
>     stateset->setAttributeAndModes(material, osg::StateAttribute::ON);
>
>     if (!texturefile.empty()) {
>         osg::Texture2D *texture = new osg::Texture2D;
>         texture->setImage(osgDB::readImageFile(texturefile));
>         texture->setFilter(osg::Texture2D::MIN_FILTER, 
> osg::Texture2D::LINEAR);
>         texture->setFilter(osg::Texture2D::MAG_FILTER, 
> osg::Texture2D::LINEAR);
>         texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::MIRROR);
>         texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::MIRROR);
>         stateset->setTextureAttributeAndModes(texture_unit, texture, 
> osg::StateAttribute::ON);
>
>         osg::TexEnv *texenv = new osg::TexEnv;
>         texenv->setMode(osg::TexEnv::MODULATE);
>         stateset->setTextureAttribute(texture_unit, texenv);
>     }
>
>     osg::BlendFunc *blend = new osg::BlendFunc;
>     if (emissive_particles) {
>         blend->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE);
>     } else {
>         blend->setFunction(osg::BlendFunc::SRC_ALPHA, 
> osg::BlendFunc::ONE_MINUS_SRC_ALPHA);
>     }
>     stateset->setAttributeAndModes(blend, osg::StateAttribute::ON);
>
>     setStateSet(stateset);
> }
>
>
> void osgParticle::ParticleSystem::single_pass_render(osg::State&  /*state*/, 
> const osg::Matrix& modelview) const
> {
>     _draw_count = 0;
>     if (_particles.size() <= 0) return;
>
>     Particle_vector::const_iterator i;
>     Particle_vector::const_iterator i0 = _particles.begin();
>     Particle_vector::const_iterator end = _particles.end();
>
>     i0->beginRender();
>
>     float scale = sqrtf(static_cast<float>(_detail));
>     for (i=i0; i<end; i+=std::min(_detail, end-i)) {
>         if (i->isAlive()) {
>             if (i->getShape() != i0->getShape()) {
>                 i0->endRender();
>                 i->beginRender();
>                 i0 = i;
>             }
>             ++_draw_count;
>
>             switch (_alignment) {
>                 case BILLBOARD:
>                     i->render(modelview.preMult(i->getPosition()), 
> osg::Vec3(1, 0, 0), osg::Vec3(0, 1, 0), scale);
>                     break;
>                 case FIXED:
>                     i->render(i->getPosition(), _align_X_axis, _align_Y_axis, 
> scale);
>                     break;
>                 default: ;
>             }
>
>         }
>     }
>
>     i0->endRender();
>
> }
>
> osg::BoundingBox osgParticle::ParticleSystem::computeBound() const
> {
>     if (!_bounds_computed)
>     {
>         return _def_bbox;
>     } else
>     {
>         return osg::BoundingBox(_bmin,_bmax);
>     }
> }
>
>
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to