建立独立的OSG程序
来源:互联网 发布:千锋教育java怎么样 编辑:程序博客网 时间:2024/05/29 11:43
1 /* OpenSceneGraph example, osgpick.*/ 2 3 /* osgpick sample 4 * demonstrate use of osgUtil/PickVisitor for picking in a HUD or 5 * in a 3d scene, 6 */ 7 8 #include <osgUtil/Optimizer> 9 #include <osgDB/ReadFile> 10 #include <osgViewer/Viewer> 11 #include <osgViewer/CompositeViewer> 12 13 #include <osgGA/TerrainManipulator> 14 #include <osgGA/StateSetManipulator> 15 #include <osgGA/AnimationPathManipulator> 16 #include <osgGA/TrackballManipulator> 17 #include <osgGA/FlightManipulator> 18 #include <osgGA/DriveManipulator> 19 #include <osgGA/KeySwitchMatrixManipulator> 20 #include <osgGA/StateSetManipulator> 21 #include <osgGA/AnimationPathManipulator> 22 #include <osgGA/TerrainManipulator> 23 24 #include <osg/Material> 25 #include <osg/Geode> 26 #include <osg/BlendFunc> 27 #include <osg/Depth> 28 #include <osg/Projection> 29 #include <osg/MatrixTransform> 30 #include <osg/Camera> 31 #include <osg/io_utils> 32 #include <osg/ShapeDrawable> 33 34 #include <osgText/Text> 35 36 #include <sstream> 37 38 // 处理拾取事件的类,继承自osgGA::GUIEventhandler 界面事件处理 39 class PickHandler : public osgGA::GUIEventHandler { 40 public: 41 //构造函数 42 PickHandler(osgText::Text* updateText): 43 _updateText(updateText) {} 44 //析构函数 45 ~PickHandler() {} 46 //处理(事件接口、动作接口) 47 bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa); 48 //拾取(视图、事件接口) 49 virtual void pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea); 50 //设置显示内容 51 void setLabel(const std::string& name) 52 { 53 if (_updateText.get()) 54 _updateText->setText(name); 55 } 56 57 protected: 58 //传递一个文字对象 59 osg::ref_ptr<osgText::Text> _updateText; 60 }; 61 //事件处理(事件接口、动作接口) 62 bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) 63 { 64 switch(ea.getEventType()) 65 { 66 case(osgGA::GUIEventAdapter::PUSH): 67 { 68 //dynamic_cast运算符的作用是将&aa转换成osgViewer::View*类型的对象 69 osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); 70 if (view) pick(view,ea); 71 return false; 72 } 73 case(osgGA::GUIEventAdapter::KEYDOWN): 74 { 75 if (ea.getKey()=='c') 76 { 77 osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); 78 //event也是一个指针,类型是osgGA::GUIEventAdapter 79 osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter(ea); 80 event->setX((ea.getXmin()+ea.getXmax())*0.5); 81 event->setY((ea.getYmin()+ea.getYmax())*0.5); 82 if (view) pick(view,*event); 83 } 84 return false; 85 } 86 default: 87 return false; 88 } 89 } 90 91 //拾取(视图、事件接口)通过view计算交点 ,从事件接口ea中获得 x和y 92 void PickHandler::pick(osgViewer::View* view, const osgGA::GUIEventAdapter& ea) 93 { 94 //创建一个线段交集检测对象 95 osgUtil::LineSegmentIntersector::Intersections intersections; 96 97 std::string gdlist=""; 98 //得到鼠标的位置 x和y 99 float x = ea.getX();100 float y = ea.getY();101 102 //如果发生交集运算 (即鼠标点中了物体)103 if (view->computeIntersections(x,y,intersections))104 {105 //得到相交交集的交点, hitr是一个迭代器106 for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin();107 hitr != intersections.end();108 ++hitr)109 {110 std::ostringstream os;//申请一个流111 if (!hitr->nodePath.empty() && !(hitr->nodePath.back()->getName().empty()))112 {113 // the geodes are identified by name.114 os<<"Object \""<<hitr->nodePath.back()->getName()<<"\""<<std::endl;115 }116 else if (hitr->drawable.valid())117 {118 os<<"Object \""<<hitr->drawable->className()<<"\""<<std::endl;119 }120 //将局部坐标顶点和法线输入到os这个流里面。121 os<<" local coords vertex("<< hitr->getLocalIntersectPoint()<<")"<<" normal("<<hitr->getLocalIntersectNormal()<<")"<<std::endl;122 os<<" world coords vertex("<< hitr->getWorldIntersectPoint()<<")"<<" normal("<<hitr->getWorldIntersectNormal()<<")"<<std::endl;123 //交点索引列表vil,交点存在hitr里面124 const osgUtil::LineSegmentIntersector::Intersection::IndexList& vil = hitr->indexList;125 for(unsigned int i=0;i<vil.size();++i)126 {127 os<<" vertex indices ["<<i<<"] = "<<vil[i]<<std::endl;128 }129 //gdlist是一个字符串,用来存os中要显示的文字130 gdlist += os.str();131 }132 }133 //设置显示内容134 setLabel(gdlist);135 }136 //创建HUD 参数是osgText。HUD也是作为场景中的一个节点存在137 osg::Node* createHUD(osgText::Text* updateText)138 {139 140 // create the hud. derived from osgHud.cpp (derived:来源于)141 // adds a set of quads, each in a separate Geode - which can be picked individually142 // eg to be used as a menuing/help system!143 // Can pick texts too!144 145 osg::Camera* hudCamera = new osg::Camera;//创建一个相机146 hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);//设置绝对帧引用147 hudCamera->setProjectionMatrixAsOrtho2D(0,1280,0,1024);//设置正投影矩阵148 hudCamera->setViewMatrix(osg::Matrix::identity());//设置视图矩阵149 hudCamera->setRenderOrder(osg::Camera::POST_RENDER);//设置渲染顺序为POST150 hudCamera->setClearMask(GL_DEPTH_BUFFER_BIT);//清除深度缓存151 152 //设置字体,声明一个timesFont,初始化为times.ttf153 std::string timesFont("fonts/times.ttf");154 155 //关掉字体的光照、禁用深度缓存 来保证字体一直在最上面156 157 osg::Vec3 position(150.0f,800.0f,0.0f);//设置位置158 osg::Vec3 delta(0.0f,-60.0f,0.0f);159 160 {161 osg::Geode* geode = new osg::Geode();//也可以写成osg::ref_ptr<osg::Geode> geode = new osg::Geode();-------geode就是一个指针162 osg::StateSet* stateset = geode->getOrCreateStateSet();//状态设置163 stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);//关闭光照164 stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);//关闭深度缓存165 geode->setName("simple");//设置这个geode的名字,geode是场景中的叶子节点166 hudCamera->addChild(geode);167 168 osgText::Text* text = new osgText::Text;169 geode->addDrawable( text );//geode是osg场景中的叶子节点,然后就是让所有drawable的东西成组170 171 text->setFont(timesFont);//设置字体172 text->setText("Picking in Head Up Displays is simple!\nHow to do it?\nAm I on the first quard?");//设置内容173 text->setPosition(position);//设置字体位置,用到上面申明的position174 175 position += delta;176 } 177 178 179 for (int i=0; i<6; i++) {180 osg::Vec3 dy(0.0f,-30.0f,0.0f);181 osg::Vec3 dx(120.0f,0.0f,0.0f);182 osg::Geode* geode = new osg::Geode();183 osg::StateSet* stateset = geode->getOrCreateStateSet();184 const char *opts[]={"One", "Two", "Three", "January", "Feb", "2003"};185 osg::Geometry *quad=new osg::Geometry;//申明一个指向几何体的指针186 stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);187 stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);188 std::string name="subOption";189 name += " ";190 name += std::string(opts[i]);191 geode->setName(name);//设置节点的名字192 osg::Vec3Array* vertices = new osg::Vec3Array(4); // 1 quad,弄个3元数组指针,数组有4个元素,分别保存矩形的4个顶点193 osg::Vec4Array* colors = new osg::Vec4Array;//4元数组指针 ,保存颜色194 colors = new osg::Vec4Array;195 colors->push_back(osg::Vec4(0.8-0.1*i, 0.1*i, 0.2*i, 1.0));//通过i的变化来实现块的渐变颜色196 quad->setColorArray(colors);197 quad->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE);//绑定颜色到方块上198 (*vertices)[0]=position;199 (*vertices)[1]=position+dx;200 (*vertices)[2]=position+dx+dy;201 (*vertices)[3]=position+dy;202 quad->setVertexArray(vertices);//设置顶点数组203 quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));204 geode->addDrawable(quad);205 hudCamera->addChild(geode);206 207 position += delta;208 } 209 210 211 212 { 213 //这里显示什么被选中214 osg::Geode* geode = new osg::Geode();215 osg::StateSet* stateset = geode->getOrCreateStateSet();216 stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);217 stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);218 geode->setName("The text label");219 geode->addDrawable( updateText );//这里的updateText是createHUD函数的传入参数220 hudCamera->addChild(geode);221 222 updateText->setCharacterSize(20.0f);223 updateText->setFont(timesFont);224 updateText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));225 updateText->setText("");226 updateText->setPosition(position);227 updateText->setDataVariance(osg::Object::DYNAMIC);228 229 position += delta;230 } 231 232 return hudCamera;233 234 }235 236 237 //主函数238 int main( int argc, char **argv )239 {240 //使用一个参数解析器对象来管理程序的参数241 osg::ArgumentParser arguments(&argc,argv);242 243 //从命令行参数指定的文件列表中读取场景244 osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);245 //如果场景没有创建成功246 if (!scene && arguments.read("--relative-camera-scene"))247 {248 //创建一个带有相关引用帧的相机的测试场景249 osg::Group* group = new osg::Group();250 251 osg::Geode* sphere = new osg::Geode();//创建一个球252 sphere->setName("Sphere");253 sphere->addDrawable(new osg::ShapeDrawable(new osg::Sphere()));254 255 osg::Geode* cube = new osg::Geode();//创建一个盒子256 cube->setName("Cube");257 cube->addDrawable(new osg::ShapeDrawable(new osg::Box()));258 259 osg::Camera* camera = new osg::Camera();//创建一个相机260 camera->setRenderOrder(osg::Camera::POST_RENDER);//设置渲染顺序为POST261 camera->setClearMask(GL_DEPTH_BUFFER_BIT);//清除深度缓存262 camera->setReferenceFrame(osg::Transform::RELATIVE_RF);//设置相对帧引用263 camera->setViewMatrix(osg::Matrix::translate(-2, 0, 0));//设置视图矩阵264 265 osg::MatrixTransform* xform = new osg::MatrixTransform(osg::Matrix::translate(1, 1, 1));266 xform->addChild(camera);267 268 group->addChild(sphere);269 group->addChild(xform);270 camera->addChild(cube);271 272 scene = group;273 }274 275 //如果没有载入假设的场景,没有参数传进来。试着使用默认的模型代替。276 if (!scene) scene = osgDB::readNodeFile("fountain.osgt");277 278 osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(scene.get());279 if (!group)280 {281 group = new osg::Group;282 group->addChild(scene.get());283 }284 285 osg::ref_ptr<osgText::Text> updateText = new osgText::Text;286 287 // add the HUD subgraph. 288 group->addChild(createHUD(updateText.get()));289 290 if (arguments.read("--CompositeViewer"))291 {292 osg::ref_ptr<osgViewer::View> view = new osgViewer::View;293 // 添加处理拾取事件的handler到视图中294 view->addEventHandler(new PickHandler(updateText.get()));295 296 // set the scene to render,设置场景到渲染中297 view->setSceneData(group.get());298 299 view->setUpViewAcrossAllScreens();300 301 osgViewer::CompositeViewer viewer;302 viewer.addView(view.get());303 304 return viewer.run();305 306 }307 else308 {309 osgViewer::Viewer viewer;310 311 312 // add all the camera manipulators313 {314 osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;315 316 keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );317 keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );318 keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );319 320 unsigned int num = keyswitchManipulator->getNumMatrixManipulators();321 keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );322 323 std::string pathfile;324 char keyForAnimationPath = '5';325 while (arguments.read("-p",pathfile))326 {327 osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);328 if (apm || !apm->valid()) 329 {330 num = keyswitchManipulator->getNumMatrixManipulators();331 keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );332 ++keyForAnimationPath;333 }334 }335 336 keyswitchManipulator->selectMatrixManipulator(num);337 338 viewer.setCameraManipulator( keyswitchManipulator.get() );339 }340 341 // add the handler for doing the picking342 viewer.addEventHandler(new PickHandler(updateText.get()));343 344 // set the scene to render345 viewer.setSceneData(group.get());346 347 return viewer.run();348 }349 350 }
0 0
- 建立独立的OSG程序
- Qt、OSG独立环境变量的建立,临时设置运行环紧变量启动vc2008
- C语言中独立图形程序的建立!!
- 独立运行的程序
- 独立运行的程序
- 独立运行的程序
- 独立运行的程序
- 独立运行的程序
- C下图形模式的初始化、独立图形程序的建立
- 我的独立博客建立啦
- OSG基础教程:官方的四程序
- OSG控制帧速的小程序
- OSG入门即osgEarth建立一个地球的详细步骤
- [osg]OSG的分格化
- AXIS2 独立建立工程
- 如何建立独立博客
- 多线程程序的建立
- 单链表的建立程序
- python网络爬虫入门(二)———模拟登陆知乎
- Java内部类、本地类、匿名类、文件类解读
- Android sqlite security网页收藏
- [LeetCode]129. Sum Root to Leaf Numbers
- Linux下查找特定时间创建的文件
- 建立独立的OSG程序
- 解决Link 2001错误的一种方法
- MT MTd MD MDd
- GLUT教程
- android.view.WindowManager$BadTokenException: Unable to add window
- 关于Console程序和win32程序的程序入口
- error C2630: initialization of * label 错误的原因及解决方法
- 四元数[转]
- 设计模式之装饰模式