Hi Guys,
I have rewritten the code block to using unsigned int indices rather
than iterators, the modified file is attached, could you apply this
and let me know if it works fine for the test case that was failing
before. If things work fine I'll clean up my changes and check them
in.
Robert.
#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;
float scale = sqrtf(static_cast<float>(_detail));
#if 1
const Particle* startParticle = &_particles[0];
startParticle->beginRender();
for(unsigned int i=0; i<_particles.size(); i+=_detail)
{
const Particle* currentParticle = &_particles[i];
if (currentParticle->isAlive())
{
if (currentParticle->getShape() != startParticle->getShape());
{
startParticle->endRender();
currentParticle->beginRender();
startParticle = currentParticle;
}
++_draw_count;
switch (_alignment) {
case BILLBOARD:
currentParticle->render(modelview.preMult(currentParticle->getPosition()), osg::Vec3(1, 0, 0), osg::Vec3(0, 1, 0), scale);
break;
case FIXED:
currentParticle->render(currentParticle->getPosition(), _align_X_axis, _align_Y_axis, scale);
break;
default:;
}
}
}
startParticle->endRender();
#else
Particle_vector::const_iterator i;
Particle_vector::const_iterator i0 = _particles.begin();
Particle_vector::const_iterator end = _particles.end();
i0->beginRender();
for (i=i0; i<end; i+=_detail) {
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();
#endif
}
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