- #include <osgViewer/Viewer>
- #include <osgDB/ReadFile>
- #include <osgGA/TrackballManipulator>
- #include <osgOcean/OceanScene>
- #include <osgOcean/FFTOceanSurface>
- #include <osgViewer/ViewerEventHandlers>
- #include <osg/TextureCubeMap>
- #include <osg/MatrixTransform>
- #include "SkyDome.h"
- #include "SphereSegment.h"
- osg::ref_ptr<osg::TextureCubeMap> loadMap(){
- osg::ref_ptr<osg::TextureCubeMap> cubeMap = new osg::TextureCubeMap;
- cubeMap->setInternalFormat(GL_RGB);
- cubeMap->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_LINEAR);
- cubeMap->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
- cubeMap->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
- cubeMap->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
- cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_X,osgDB::readImageFile("resources/textures/west.png"));
- cubeMap->setImage(osg::TextureCubeMap::POSITIVE_X,osgDB::readImageFile("resources/textures/east.png"));
- cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Y,osgDB::readImageFile("resources/textures/up.png"));
- cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Y,osgDB::readImageFile("resources/textures/down.png"));
- cubeMap->setImage(osg::TextureCubeMap::NEGATIVE_Z,osgDB::readImageFile("resources/textures/south.png"));
- cubeMap->setImage(osg::TextureCubeMap::POSITIVE_Z,osgDB::readImageFile("resources/textures/north.png"));
- return cubeMap;
- }
- class CameraTrackCallback: public osg::NodeCallback
- {
- public:
- virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
- {
- if( nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR )
- {
- osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(nv);
- osg::Vec3f centre,up,eye;
- cv->getRenderStage()->getCamera()->getViewMatrixAsLookAt(eye,centre,up);
- osg::MatrixTransform* mt = static_cast<osg::MatrixTransform*>(node);
- mt->setMatrix( osg::Matrix::translate( eye.x(), eye.y(), mt->getMatrix().getTrans().z() ) );
- }
- traverse(node, nv);
- }
- };
- class BoatPositionCallback :public osg::NodeCallback{
- public:
- BoatPositionCallback(osgOcean::OceanScene * scene){
- _scene = scene;
- }
- virtual void operator()(osg::Node* node, osg::NodeVisitor* nv){
- if(nv->getVisitorType() ==osg::NodeVisitor::UPDATE_VISITOR)
- {
- osg::MatrixTransform * mat =dynamic_cast<osg::MatrixTransform*>(node);
- if(mat){
- osg::Matrix matrix = osg::computeLocalToWorld(nv->getNodePath());
- osg::Vec3d pos = matrix.getTrans();
- osg::Vec3f normal;
- float height = _scene->getOceanSurfaceHeightAt(pos[0],pos[1],&normal);
- static float a = 0;
- matrix.makeTranslate(osg::Vec3(pos[0]+cosf(a),pos[1]+sinf(a),height));
- osg::Matrixf rot;
- rot.makeIdentity();
- rot.makeRotate(normal.x(),osg::X_AXIS,
- normal.y(),osg::Y_AXIS,
- a,osg::Z_AXIS);
- a+=0.005;
- matrix = rot * matrix;
- mat->setMatrix(matrix);
- }
- }
- }
- private:
- osgOcean::OceanScene * _scene;
- };
- int main()
- {
- osg::ref_ptr<osgViewer::Viewer>viewer = new osgViewer::Viewer ;
- viewer->setUpViewInWindow(150,150,1024,768,0);
- osg::ref_ptr<osgOcean::FFTOceanSurface>surface = new osgOcean::FFTOceanSurface(64,256,17,osg::Vec2(1.1f,1.1f),12,10,0.8,1e-8,true,2.5,20.0,256);
- osg::ref_ptr<osgOcean::OceanScene> scene = new osgOcean::OceanScene(surface.get());
- //天空盒
- osg::ref_ptr<osg::TextureCubeMap> cubeMAP = loadMap();
- osg::ref_ptr<SkyDome> sky = new SkyDome(1900,16,16,cubeMAP.get());
- sky->setNodeMask(scene->getReflectedSceneMask() | scene->getNormalSceneMask());
- osg::MatrixTransform * mat =new osg::MatrixTransform;
- mat->setDataVariance(osg::Object::DYNAMIC);
- mat->setMatrix(osg::Matrixf::translate(osg::Vec3d(0,0,0)));
- mat->addChild(sky.get());
- mat->setCullCallback(new CameraTrackCallback);
- scene->addChild(mat);
- //雾效和反射
- scene->setAboveWaterFog(0.0012,osg::Vec4(0.67,0.87,0.97,1.0));
- scene->enableReflections(true);
- surface->setEnvironmentMap(cubeMAP);
- //水花
- surface->setFoamBottomHeight(2.2);
- surface->setFoamTopHeight(3.0);
- surface->enableCrestFoam(true);
- viewer->addEventHandler(surface->getEventHandler());
- viewer->addEventHandler(scene->getEventHandler());
- //添加小船
- osg::ref_ptr<osg::Node> galley = osgDB::readNodeFile("resources/boat/boat.3ds");
- galley->setNodeMask(scene->getNormalSceneMask() | scene->getReflectedSceneMask() | scene->getRefractedSceneMask());
- osg::MatrixTransform * trans = new osg::MatrixTransform;
- trans->setMatrix(osg::Matrix::translate(osg::Vec3(0,0,0)));
- trans->setUpdateCallback(new BoatPositionCallback(scene));
- trans->addChild(galley);
- scene->addChild(trans);
- osgGA::TrackballManipulator *tb = new osgGA::TrackballManipulator;
- tb->setHomePosition(osg::Vec3d(0,0,20),osg::Vec3d(0,20,20),osg::Z_AXIS);
- viewer->setCameraManipulator(tb);
- viewer->addEventHandler(new osgViewer::StatsHandler);
- viewer->setSceneData(scene.get());
- viewer->run();
- return 0;
- }
-
其中天空盒用的是osgocean中的例子
效果如下图