#include <osg/Camera>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Image>
#include <osg/BlendFunc>
#include <osg/BlendEquation>
#include <osg/TexMat>
#include <osg/MatrixTransform>
#include <Windows.h>
#include <iostream>
using namespace std;
class RefCameraCallBack: public osg::NodeCallback//这个是反射相机的回调,这个相机是根据视点的相机的变化而变化
//位置就是视点在水平面的镜像,这个也较容易实现,我的代码写的乱,
//大家了解方法就行,可以自己动手改进一下。
{
public:
RefCameraCallBack(osg::Camera * camera):_cankaoCamera(camera),_frist(true),_yizi(1.0f)
{
//_rttCamera->attach(osg::Camera::BufferComponent::COLOR_BUFFER,_image);
}
~RefCameraCallBack(){}
virtual void operator() (osg::Node *node, osg::NodeVisitor *nv)
{
_RttCamera=dynamic_cast<osg::Camera *>(node);
//if(_RttCamera==NULL)
osg::ref_ptr<osg::GraphicsContext::WindowingSystemInterface> wsi=osg::GraphicsContext::getWindowingSystemInterface();
if(!wsi) cout<<"转型出错"<<endl;
//osg::GraphicsContext::ScreenIdentifier screen(0);
//wsi->getScreenResolution(screen,width,height);
const osg::GraphicsContext::Traits * traits=_cankaoCamera->getGraphicsContext()->getTraits();
w_h=traits->width/traits->height;
_time=_cankaoCamera->getView()->getFrameStamp()->getSimulationTime();
ViewCalculate();
cout<<_time<<endl;
_RttCamera->setViewMatrix(_cankaoCamera->getViewMatrix());
//_RttCamera->setViewMatrixAsLookAt(_eye_Positon,_eye_Center,_eye_Up);
double aspectRatio,zNear, zFar;
_cankaoCamera->getProjectionMatrixAsPerspective(fovy,aspectRatio,zNear,zFar);
//cout<<aspectRatio<<endl;
cout<<traits->width<<" "<<traits->height<<endl;
w_h=float(aspectRatio);
//double newAspect=traits->width/traits->height;
//double yizi=newAspect/aspectRatio;
//_RttCamera->setProjectionMatrix(_cankaoCamera->getProjectionMatrix()*osg::Matrix::scale(1.0/yizi,1.0,1.0));
//_RttCamera->setProjectionMatrixAsPerspective(fovy,1.0/yizi,zNear,zFar);
_RttCamera->setProjectionMatrix(_cankaoCamera->getProjectionMatrix());
}
//osg::Image * getImage(){return _image.get();}
//osg::Node * getReflectionNode(){return _water;}
float getW_H(){return w_h;}
float getFovy(){return static_cast<float>(osg::DegreesToRadians(fovy/2.0));}
osg::Vec3 &getViewPosition(){return _eye_Positon;}
double getTime(){return _time;}
protected:
virtual void ViewCalculate()
{
_cankaoCamera->getViewMatrixAsLookAt(_eye_Positon,_eye_Center,_eye_Up,10.0);
//_eye_Positon.z()=(_eye_Positon.z()-_waterHigh)*2-_eye_Positon.z();
//_eye_Center.z()=(_eye_Center.z()-_waterHigh)*2-_eye_Center.z();
//_eye_Positon.z()=-_eye_Positon.z();
//_eye_Center.z()=-_eye_Center.z();
//_m=_cankaoCamera->getProjectionMatrix();
}
private:
osg::Camera * _cankaoCamera;
osg::Camera * _RttCamera;
osg::Matrix _m;
float w_h;
double fovy;
float _waterHigh;
bool _frist;
unsigned int _Width;
float _yizi;
osg::Vec3 _eye_Positon;
osg::Vec3 _eye_Center;
osg::Vec3 _eye_Up;
mutable double _time;
float _lookDistance;//这个值的意思是指眼的位置与中心的距离,osg的观察方式设计中是一个向量,只有方向,大小直接可以自己设置,
//这个值越大则设置的焦点越远,比如建筑物。值越小则距焦点越近,比如静物写真。
//还可以讲这个值想象成3ds Max软件中目标相机的目标点与相机的距离。
//这里将这个值默认的设置成100.0
};
class updateViewShader : public osg::Uniform::Callback
{
public:
updateViewShader(RefCameraCallBack * ref):_ref(ref){}
virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
uniform->set(_ref->getViewPosition());
}
private:
RefCameraCallBack * _ref;
};
class updateW_HShader : public osg::Uniform::Callback
{
public:
updateW_HShader(RefCameraCallBack * ref):_ref(ref){}
virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
if (!uniform)
{
cout<<"转型出错"<<endl;
return;
}
uniform->set((_ref->getW_H()));
float t;
uniform->get(t);
cout<<t<<endl;
}
private:
RefCameraCallBack * _ref;
};
class updateFovyShader : public osg::Uniform::Callback
{
public:
updateFovyShader(RefCameraCallBack * ref):_ref(ref){}
virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
if (!uniform)
{
cout<<"转型出错"<<endl;
return;
}
uniform->set((_ref->getFovy()));
float t;
uniform->get(t);
cout<<t<<endl;
}
private:
RefCameraCallBack * _ref;
};
class updateTimeShader : public osg::Uniform::Callback
{
public:
updateTimeShader(RefCameraCallBack * ref):_ref(ref){}
virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
{
if (!uniform)
{
cout<<"转型出错"<<endl;
return;
}
uniform->set(static_cast<float>((_ref->getTime())));
float t;
uniform->get(t);
cout<<t<<endl;
}
private:
RefCameraCallBack * _ref;
};
int main( int argc, char** argv )
{
osgViewer::Viewer viewer;
//////////////////////////////////////////////////////////////////////////注意路径
osg::ref_ptr<osg::Node> other = osgDB::readNodeFile( "E://ALL_TEST//OSG_TEST//debug//data//other.3ds" );//这个是水两边的瓷片,呵呵,为了更像一些
osg::ref_ptr<osg::Node> water=osgDB::readNodeFile("E://ALL_TEST//OSG_TEST//debug//data//water.3ds");//水的节点,就是一个平面
osg::ref_ptr<osg::Node> tree=osgDB::readNodeFile( "E://ALL_TEST//OSG_TEST//debug//data//tree.3ds" );//树
osg::ref_ptr<osg::Node> sky=osgDB::readNodeFile( "E://ALL_TEST//OSG_TEST//debug//data//sky.3ds" );//天空球
//osg::ref_ptr<osg::Node> _ref=osgDB::readNodeFile( "E:/ALL_TEST/OSG_TEST/debug/data/ref.3ds" );//
//////////////////////////////////////////////////////////////////////////创建rtt相机
osg::ref_ptr<osg::Camera> rtt=new osg::Camera;
rtt->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
rtt->setReferenceFrame( osg::Transform::ReferenceFrame::ABSOLUTE_RF_INHERIT_VIEWPOINT );
rtt->setRenderOrder( osg::Camera::PRE_RENDER );//提前渲染
rtt->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
//////////////////////////////////////////////////////////////////////////创建rtt相机结束
//////////////////////////////////////////////////////////////////////////这里有必要说一下
//本来打