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

版权声明:本文为zhuyingqingfen原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。