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