#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中的例子
效果如下图