|
本帖最后由 Mooneast 于 2013-8-7 11:21 编辑
做了这样一个实验工程,使用《OSG编程实践》中的立方图纹理做了一个天空球,如下:- struct TexMatCallback:public osg::NodeCallback
- {
- public:
- TexMatCallback(osg::TexMat& tm):_texMat(tm)
- {
- }
- virtual void operator()(osg::Node*node,osg::NodeVisitor*nv)
- {
- osgUtil::CullVisitor* cv=dynamic_cast<osgUtil::CullVisitor*>(nv);
- if (cv)
- {
- const osg::Matrix& mv=*(cv->getModelViewMatrix());
- const osg::Matrix R=osg::Matrix::rotate(osg::DegreesToRadians(112.0f),0.0f,0.0f,1.0f)*osg::Matrix::rotate(osg::DegreesToRadians(90.0f),1.0f,0.0f,0.0f);
- osg::Quat q=mv.getRotate();
- const osg::Matrix C=osg::Matrix::rotate(q.inverse());
- _texMat.setMatrix(C*R);
- }
- traverse(node,nv);
- }
- osg::TexMat& _texMat;
- };
- class MoveWithEyePoint:public osg::Transform
- {
- public:
- MoveWithEyePoint()
- {
- }
- ~MoveWithEyePoint()
- {
- }
- virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor*nv)const
- {
- osgUtil::CullVisitor* cv=dynamic_cast<osgUtil::CullVisitor*>(nv);
- if (cv)
- {
- osg::Vec3 eyePointLocal=cv->getEyeLocal();
- matrix.preMult(osg::Matrix::translate(eyePointLocal));
- }
- return true;
- }
- virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*nv)const
- {
- osgUtil::CullVisitor* cv=dynamic_cast<osgUtil::CullVisitor*>(nv);
- if (cv)
- {
- osg::Vec3 eyePointLocal=cv->getEyeLocal();
- matrix.postMult(osg::Matrix::translate(-eyePointLocal));
- }
- return true;
- }
- };
- //创建天空球函数
- osg::ref_ptr<osg::Node> CreateSphere(void)
- {
- osg::ref_ptr<osg::Image> srcImage=osgDB::readImageFile(m_strBackGroundFile);
- unsigned width=srcImage->s()/4;
- unsigned height=srcImage->t()/3;
- //下面的代码是用来将一个整张的图片中的几个面的贴图截出来的,与主题没有太大关系
- osg::ref_ptr<osg::Image> topImage=getSubImage(srcImage,width,height*2,0,width,height,1);
- osg::ref_ptr<osg::Image> bottomImage=getSubImage(srcImage,width,0,0,width,height,1);
- osg::ref_ptr<osg::Image> rightImage=getSubImage(srcImage,width*2,height,0,width,height,1);
- osg::ref_ptr<osg::Image> leftImage=getSubImage(srcImage,0,height,0,width,height,1);
- osg::ref_ptr<osg::Image> frontImage=getSubImage(srcImage,width,height,0,width,height,1);
- osg::ref_ptr<osg::Image> backImage=getSubImage(srcImage,width*3,height,0,width,height,1);
- osg::ref_ptr<osg::TextureCubeMap> tcm=new osg::TextureCubeMap;
- {
- tcm->setImage(osg::TextureCubeMap::POSITIVE_X,rightImage);
- tcm->setImage(osg::TextureCubeMap::NEGATIVE_X,leftImage);
- tcm->setImage(osg::TextureCubeMap::POSITIVE_Y,bottomImage);
- tcm->setImage(osg::TextureCubeMap::NEGATIVE_Y,topImage);
- tcm->setImage(osg::TextureCubeMap::POSITIVE_Z,frontImage);
- tcm->setImage(osg::TextureCubeMap::NEGATIVE_Z,backImage);
- tcm->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
- tcm->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
- tcm->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);
- tcm->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR_MIPMAP_NEAREST);
- tcm->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);
- }
- osg::ref_ptr<osg::StateSet> stateset=new osg::StateSet;
- osg::ref_ptr<osg::TexEnv> te=new osg::TexEnv;
- te->setMode(osg::TexEnv::REPLACE);
- stateset->setTextureAttributeAndModes(0,te,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
- osg::ref_ptr<osg::TexGen> tg=new osg::TexGen;
- tg->setMode(osg::TexGen::NORMAL_MAP);
- stateset->setTextureAttributeAndModes(0,tg,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
- osg::ref_ptr<osg::TexMat> tm=new osg::TexMat;
- stateset->setTextureAttribute(0,tm);
- stateset->setTextureAttributeAndModes(0,tcm,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
- stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
- stateset->setMode(GL_CULL_FACE,osg::StateAttribute::OFF);
- osg::ref_ptr<osg::Depth> depth=new osg::Depth;
- depth->setFunction(osg::Depth::ALWAYS);
- depth->setRange(1.0,1.0);
- stateset->setAttributeAndModes(depth,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
- stateset->setRenderBinDetails(-1,"RenderBin");
- osg::ref_ptr<osg::Drawable> drawable=new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0,0.0,0.0),1.0));
- osg::ref_ptr<osg::Geode> geode=new osg::Geode;
- geode->setCullingActive(false);
- geode->setStateSet(stateset);
- geode->addDrawable(drawable);
- osg::ref_ptr<osg::Transform> transform=new MoveWithEyePoint();
- transform->addChild(geode);
- transform->setCullingActive(false);
- transform->setCullCallback(new TexMatCallback(*tm));
- return transform;
- }
复制代码 在主函数中,实现如下:- int main()
- {
- osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer;
- osg::ref_ptr<osg::Group> root=new osg::Group;
- osg::ref_ptr<osg::Node> scene=osgDB::readNodeFile("lz.osg");
- osg::ref_ptr<osg::Node> node=CreateSphere();
- osg::ref_ptr<osg::GraphicsContext::Traits> traits=new osg::GraphicsContext::Traits;
- traits->x=400;
- traits->y=50;
- traits->width=800;
- traits->height=600;
- traits->windowName="Main";
- traits->windowDecoration=true;
- traits->sharedContext=0;
- traits->doubleBuffer=true;
- traits->stencil=8;
- osg::ref_ptr<osg::GraphicsContext> gc=osg::GraphicsContext::createGraphicsContext(traits);
- if (gc->valid())
- {
- gc->setClearColor(osg::Vec4(1.0,0.0,0.0,1.0));
- gc->setClearMask(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
- }else{
- std::cout<<"Graphics has not been created !"<<std::endl;
- }
- osg::Vec3 eye(scene->getBound().center().x(),scene->getBound().center().y()-scene->getBound().radius(),scene->getBound().center().z());
- osg::Vec3 center(scene->getBound().center().x(),scene->getBound().center().y(),scene->getBound().center().z());
- osg::Vec3 up(0.0,0.0,1.0);
- {
- osg::ref_ptr<osgViewer::DepthPartitionSettings> dps=new osgViewer::DepthPartitionSettings;
- dps->_mode = osgViewer::DepthPartitionSettings::FIXED_RANGE;
- dps->_zNear=1.0;
- dps->_zMid=scene->getBound().radius()*0.7;
- dps->_zFar=scene->getBound().radius();
- viewer->setUpDepthPartition(dps);
- viewer->getCamera()->setGraphicsContext(gc);
- viewer->getCamera()->setViewport(0,0,traits->width,traits->height);
- viewer->getSlave(0)._camera->setGraphicsContext(gc);
- viewer->getSlave(0)._camera->setViewport(0,traits->height/2,traits->width/2,traits->height/2);
- viewer->getSlave(0)._camera->setAllowEventFocus(false);
- viewer->getSlave(1)._camera->setGraphicsContext(gc);
- viewer->getSlave(1)._camera->setViewport(0,0,traits->width/2,traits->height/2);
- viewer->getSlave(1)._camera->setAllowEventFocus(false);
- viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getSlave(1)._camera->getOrCreateStateSet()));
- std::cout<<viewer->getNumSlaves()<<std::endl;
- }
- root->addChild(node);
- root->addChild(scene);
- viewer->setSceneData(root);
- viewer->setCameraManipulator(new osgGA::TrackballManipulator);
- viewer->getCameraManipulator()->setHomePosition(eye,center,up,false);
- viewer->home();
- viewer->run();
- return 0;
- }
复制代码 运行的结果很奇怪,只有最后一个加入的相机被渲染出来了,但是实际上的从属相机个数仍为2,此外当视点距离scene很远的时候,会造成天空球的裁剪,情况如下图。
|
|