Hi Robert,
thanks, disabled auto-inlining attachments, it should work now.
regards,
Michael.
Robert Osfield wrote:
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