Show
Ignore:
Timestamp:
04/07/06 20:24:52 (8 years ago)
Author:
robert
Message:

Added quad based rain effect

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgprecipitation/osgprecipitation.cpp

    r5076 r5078  
    1313#include <osgDB/FileUtils> 
    1414#include <osgUtil/Optimizer> 
     15#include <osgUtil/CullVisitor> 
    1516#include <osgProducer/Viewer> 
    1617 
     
    2021#include <osg/PointSprite> 
    2122#include <osg/Program> 
     23#include <osg/Fog> 
     24#include <osg/io_utils> 
    2225 
    2326float random(float min,float max) { return min + (max-min)*(float)rand()/(float)RAND_MAX; } 
    2427 
     28class PrecipitationGeometry : public osg::Geometry 
     29{ 
     30public: 
     31        virtual bool supports(const osg::PrimitiveFunctor&) const { return false; } 
     32        virtual void accept(osg::PrimitiveFunctor&) const {} 
     33        virtual bool supports(const osg::PrimitiveIndexFunctor&) const { return false; } 
     34        virtual void accept(osg::PrimitiveIndexFunctor&) const {} 
     35 
     36}; 
     37 
     38class CullCallback : public osg::NodeCallback 
     39{ 
     40public: 
     41 
     42    CullCallback(osg::Uniform* uniform): 
     43        _previousFrame(0), 
     44        _initialized(false), 
     45        _uniform(uniform) 
     46    { 
     47    } 
     48 
     49    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) 
     50    {  
     51        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv); 
     52        if (cv) 
     53        { 
     54            if (!_initialized) 
     55            { 
     56                _previousModelViewMatrix = cv->getModelViewMatrix(); 
     57                _previousFrame = nv->getFrameStamp()->getFrameNumber(); 
     58                _initialized = true; 
     59            } 
     60         
     61            _uniform->set(_previousModelViewMatrix); 
     62             
     63            // osg::notify(osg::NOTICE)<<"Updating uniform "<<_previousModelViewMatrix<<std::endl; 
     64 
     65            traverse(node, nv); 
     66             
     67            if (_previousFrame != nv->getFrameStamp()->getFrameNumber()) 
     68            { 
     69                _previousModelViewMatrix = cv->getModelViewMatrix(); 
     70                _previousFrame = nv->getFrameStamp()->getFrameNumber(); 
     71            } 
     72        } 
     73        else 
     74        { 
     75            traverse(node, nv); 
     76        } 
     77    } 
     78     
     79    int _previousFrame; 
     80    bool _initialized; 
     81    osg::Matrix _previousModelViewMatrix; 
     82    osg::ref_ptr<osg::Uniform> _uniform;     
     83}; 
     84 
    2585osg::Node* createRainEffect(const osg::BoundingBox& bb, const osg::Vec3& velocity, unsigned int numParticles, bool useShaders) 
    2686{ 
    27     osg::Geometry* geometry = new osg::Geometry; 
     87    osg::Geode* geode = new osg::Geode; 
     88 
     89    osg::Geometry* geometry = new PrecipitationGeometry; 
     90    geode->addDrawable(geometry); 
    2891 
    2992    osg::StateSet* stateset = geometry->getOrCreateStateSet(); 
     
    3396     
    3497        // per vertex properties 
    35         osg::Vec3Array* vertices = new osg::Vec3Array(numParticles*2); 
    36         osg::FloatArray* offsets = new osg::FloatArray(numParticles*2); 
     98        osg::Vec3Array* vertices = new osg::Vec3Array(numParticles*4); 
     99        osg::Vec3Array* offsets = new osg::Vec3Array(numParticles*4); 
    37100         
    38101        osg::Vec3 frameDelta = velocity*(2.0f/60.0f); 
     102        float size = 1.0; 
    39103         
    40104        for(unsigned int i=0; i< numParticles; ++i) 
    41105        { 
    42             (*vertices)[i*2].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax()); 
    43             (*vertices)[i*2+1] = (*vertices)[i*2] + frameDelta; 
    44             (*offsets)[i*2] = random(0.0, 1.0); 
    45             (*offsets)[i*2+1] = (*offsets)[i*2]; 
     106            (*vertices)[i*4].set(random(bb.xMin(), bb.xMax()), random(bb.yMin(),bb.yMax()), bb.zMax()); 
     107            (*vertices)[i*4+1] = (*vertices)[i*4]; 
     108            (*vertices)[i*4+2] = (*vertices)[i*4]; 
     109            (*vertices)[i*4+3] = (*vertices)[i*4]; 
     110            (*offsets)[i*4].z() = random(0.0, 1.0); 
     111            (*offsets)[i*4+1].z() = (*offsets)[i*4].z(); 
     112            (*offsets)[i*4+2].z() = (*offsets)[i*4].z(); 
     113            (*offsets)[i*4+3].z() = (*offsets)[i*4].z(); 
     114            (*offsets)[i*4].x() = 0.0; 
     115            (*offsets)[i*4].y() = 0.0; 
     116            (*offsets)[i*4+1].x() = 0.0; 
     117            (*offsets)[i*4+1].y() = 1.0; 
     118            (*offsets)[i*4+2].x() = 1.0; 
     119            (*offsets)[i*4+2].y() = 1.0; 
     120            (*offsets)[i*4+3].x() = 1.0; 
     121            (*offsets)[i*4+3].y() = 0.0; 
    46122        } 
    47123 
     
    51127        // overall attributes 
    52128        osg::Vec4Array* colours = new osg::Vec4Array(1); 
    53         (*colours)[0].set(0.5f,0.5f,0.5f,0.5f); 
     129        (*colours)[0].set(0.5f,0.5f,0.5f,1.0f); 
    54130        geometry->setColorArray(colours); 
    55131        geometry->setColorBinding(osg::Geometry::BIND_OVERALL); 
    56132         
    57         geometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, numParticles)); 
     133        geometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, numParticles*4)); 
    58134    } 
    59135 
     
    84160        stateset->addUniform(inversePeriodUniform); 
    85161        stateset->addUniform(startTime); 
     162         
     163        osg::Uniform* baseTextureSampler = new osg::Uniform("baseTexture",0); 
     164        stateset->addUniform(baseTextureSampler); 
     165         
     166        osg::Texture2D* texture = new osg::Texture2D(osgDB::readImageFile("Images/particle.rgb")); 
     167        stateset->setTextureAttribute(0, texture); 
     168 
     169        // make it render after the normal transparent bin 
     170        stateset->setRenderBinDetails(11,"DepthSortedBin"); 
     171 
     172        osg::Uniform* previousModelViewUniform = new osg::Uniform("previousModelViewMatrix",osg::Matrix()); 
     173        stateset->addUniform(previousModelViewUniform); 
     174        geode->setCullCallback(new CullCallback(previousModelViewUniform)); 
     175 
    86176    } 
    87177     
    88178    geometry->setUseVertexBufferObjects(true); 
    89179    geometry->setInitialBound(bb); 
    90  
    91  
    92     osg::Geode* geode = new osg::Geode; 
    93     geode->addDrawable(geometry); 
    94180 
    95181    return geode; 
     
    169255    osg::BoundingBox bb(0.0, 0.0, 0.0, 100.0, 100.0, 100.0); 
    170256    osg::Vec3 velocity(0.0,0.0,-2.0); 
    171     unsigned int numParticles = 100000; 
     257    unsigned int numParticles = 150000; 
    172258     
    173259    if (loadedModel) 
     
    176262         
    177263        osg::BoundingSphere bs = loadedModel->getBound(); 
    178         bs.radius() *= 0.75; 
    179         bb.init(); 
    180         bb.expandBy(bs); 
     264 
     265        bb.set( -100, -100, 0, +100, +100, 10); 
     266         
     267        osg::StateSet* stateset = loadedModel->getOrCreateStateSet(); 
     268         
     269        osg::Fog* fog = new osg::Fog; 
     270        fog->setMode(osg::Fog::LINEAR); 
     271        fog->setDensity(0.1f); 
     272        fog->setStart(0.0f); 
     273        fog->setEnd(1000.0f); 
     274        fog->setColor(osg::Vec4(0.5f,0.5f,0.5f,1.0f)); 
     275        stateset->setAttributeAndModes(fog, osg::StateAttribute::ON); 
     276         
     277        osg::LightSource* lightSource = new osg::LightSource; 
     278        group->addChild(lightSource); 
     279 
     280        osg::Light* light = lightSource->getLight(); 
     281        light->setLightNum(0); 
     282        light->setPosition(osg::Vec4(0.0f,0.0f,1.0f,0.0f)); // directional light from above 
     283        light->setAmbient(osg::Vec4(0.8f,0.8f,0.8f,1.0f)); 
     284        light->setDiffuse(osg::Vec4(0.2f,0.2f,0.2f,1.0f)); 
     285        light->setSpecular(osg::Vec4(0.2f,0.2f,0.2f,1.0f)); 
     286 
     287                 
    181288    } 
    182289