hi,Jean-Sebastien Guay ,

   Thank you for your quick reply, and sorry for my delayed response.
    
    Maybe I got the values from the previous frame, but I dont know how to 
correct it. Because I just know to use getOceanSurfaceHeightAt to get the 
surface height.

   I modified the oceanExample source directly.  I make an  example as follows:
    1. query the heights around the specifed point as the z position of 
particles, and draw the particles

    2 use a updatecallback to update the new height by VBO

That is the code:

create and add the particle node to scene group:


Code:
                osg::Node* particles = queryAndCreateParticles(&pos, 
scene->getOceanScene());
                
particles->setNodeMask(scene->getOceanScene()->getNormalSceneMask()    | 
                        scene->getOceanScene()->getReflectedSceneMask() | 
                        scene->getOceanScene()->getRefractedSceneMask() |
                        CAST_SHADOW | RECEIVE_SHADOW );
                particles->setUpdateCallback(new myParticleCallBack(&pos, 
scene->getOceanScene()));
                scene->getOceanScene()->addChild(particles);




that's the function body:


Code:

osg::Vec3Array* particleVerts = new osg::Vec3Array;
osg::Vec3Array* particleNormls = new osg::Vec3Array;

class  myParticleCallBack  : public osg::NodeCallback
{
public:
        myParticleCallBack() {}
        myParticleCallBack(osg::Vec3f* pos, osgOcean::OceanScene* 
oceanScene):_pos(pos), _oceanScene(oceanScene){}

        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
        { 
                osg::Node* particles = dynamic_cast<osg::Node*>(node);
                osg::Geode* geode = particles->asGeode();
                osg::Geometry* geom = (osg::Geometry*)geode->getDrawable(0);

                osg::Vec3Array* verts = (osg::Vec3Array*) 
geom->getVertexArray();
                osg::Vec3Array* normls = (osg::Vec3Array*) 
geom->getNormalArray();
                static int start =0;
                static int count = 0;

                verts->clear();
                normls->clear();

                float foamBottom = _oceanScene->getOceanFoamBottom();
                int num =0;
                for(int i = -128; i<128; i+=1){
                        for(int j = -128; j< 128; j+=1) {
                                osg::Vec3f tempNormal;
                                float temp = 
_oceanScene->getOceanSurfaceHeightAt(_pos->x()+i, _pos->y()+j, &tempNormal);
                                verts->push_back(osg::Vec3f(_pos->x()+i, 
_pos->y()+j, temp));
                                normls->push_back(tempNormal);  
                        }
                }               
                verts->dirty();
                normls->dirty();
        }

protected:
        osg::Vec3f *_pos;
        osgOcean::OceanScene* _oceanScene;
};

osg::Node* queryAndCreateParticles(osg::Vec3f* shipPos, osgOcean::OceanScene* 
oceanScene)
{
        particleVerts->clear();
        particleNormls->clear();
        for(int i = -128; i<128; i+=1)
        {
                for(int j = -128; j< 128; j+=1)
                {
                        osg::Vec3f tempNormal;
                        float temp = 
oceanScene->getOceanSurfaceHeightAt(shipPos->x()+i, shipPos->y()+j, 
&tempNormal);
                        particleVerts->push_back(osg::Vec3f(shipPos->x()+i, 
shipPos->y()+j, temp));
                        particleNormls->push_back(tempNormal);
                }
        }
        osg::VertexBufferObject* vertexVBO = new osg::VertexBufferObject;
        vertexVBO->setUsage( GL_DYNAMIC_DRAW );   // data will be changed 
frequently (specified and used repeatedly)
        osg::VertexBufferObject* normalVBO = new osg::VertexBufferObject;
        normalVBO->setUsage( GL_DYNAMIC_DRAW );

        // assign vbos to the master arrays
        particleVerts->setVertexBufferObject( vertexVBO );
        particleNormls->setVertexBufferObject( normalVBO );

        osg::Vec4Array* colors = new osg::Vec4Array;
        colors->push_back(osg::Vec4f(1.f, 1.f, 1.f, 1.f));

        osg::Geometry* geom = new osg::Geometry;
        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(geom);

        geom->setVertexArray(particleVerts);
        geom->setNormalArray(particleNormls);
        geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
        geom->setColorArray(colors);
        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
        geom->setUseDisplayList(false);
        geom->setUseVertexBufferObjects(true);
        geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, 
particleVerts->getNumElements()));

        osg::StateSet* set = geode->getOrCreateStateSet();
        set->setMode(GL_BLEND, osg::StateAttribute::ON);
        osg::BlendFunc *fn = new osg::BlendFunc();
        fn->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::DST_ALPHA);
        set->setAttributeAndModes(fn, osg::StateAttribute::ON);

        /// Setup the point sprites
        osg::PointSprite *sprite = new osg::PointSprite();
        set->setTextureAttributeAndModes(0, sprite, osg::StateAttribute::ON);

        /// Give some size to the points to be able to see the sprite
        osg::Point *point = new osg::Point();
        point->setSize(5);
        set->setAttribute(point);

        /// Disable depth test to avoid sort problems and Lighting
        set->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
        set->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

        /// The texture for the sprites
        osg::Texture2D *tex = new osg::Texture2D();
        tex->setImage(osgDB::readImageFile("Images/particle.rgb"));
        set->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON);

        return geode;
}




Thank you very for your kindness and help!!

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=42827#42827





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to