osgOcean 水面效果

#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中的例子

效果如下图

osgOcean 水面效果_第1张图片


你可能感兴趣的:(osgOcean 水面效果)