OpenSceneGraph实现的NeHe OpenGL教程 - 第七课

  • 简介

这节课我们将讨论如何在OSG中使用键盘和灯光。我们将会学习指定三种纹理过滤方式,学习如何使用键盘来移动场景中的立方体。

在osg中通过osgGA库来实现与用户的交互,在用户端,通常使用GUIEventAdapter类作为系统交互事件和OSG交互事件的适配接口。

  • 实现

首先定义一个类用来查找场景中我们需要的节点,这个类会遍历场景子节点,返回第一个查找到与输入名称相同的节点。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //  
  2. //FindFirstNamedNodeVisitor用来遍历寻找与指定名称相同的节点  
  3.   
  4. class FindFirstNamedNodeVisitor : public osg::NodeVisitor  
  5. {  
  6. public:  
  7.     FindFirstNamedNodeVisitor(const std::string& name):  
  8.       osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),  
  9.           _name(name), _foundNode(NULL) {}  
  10.   
  11.       virtual void apply(osg::Node& node)  
  12.       {  
  13.           if (node.getName()==_name)  
  14.           {  
  15.               _foundNode = &node;  
  16.               return;  
  17.           }  
  18.           traverse(node);  
  19.       }  
  20.   
  21.       std::string _name;  
  22.       osg::Node *_foundNode;  
  23. };  

为了实现用户设备与场景的交互,我们定义继承自osgGA::GUIEventHandler的类

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  2. {  
  3. public:  
  4.     ManipulatorSceneHandler()  
  5.     {  
  6.     }  
  7.   
  8.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);  
  9. };  

主要需要交互的代码在重载的handle函数中完成

使用PageDown和PageUp可以对场景进行Zoom in 和Zoom out的操作,通过修改平移矩阵来完成

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Up)  
  2. {     
  3.     FindFirstNamedNodeVisitor fnv("zoomMT");  
  4.     root->accept(fnv);  
  5.   
  6.     osg::Node *mtNode = fnv._foundNode;  
  7.     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  8.     if (!zoomMT)  
  9.         return false;  
  10.       
  11.     osg::Vec3 trans = zoomMT->getMatrix().getTrans();  
  12.     trans.set(trans.x(), trans.y(), trans.z() + 0.2);  
  13.     zoomMT->setMatrix(osg::Matrix::translate(trans));  
  14. }  
  15.   
  16. if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Down)  
  17. {  
  18.     FindFirstNamedNodeVisitor fnv("zoomMT");  
  19.     root->accept(fnv);  
  20.   
  21.     osg::Node *mtNode = fnv._foundNode;  
  22.     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  23.     if (!zoomMT)  
  24.         return false;  
  25.   
  26.     osg::Vec3 trans = zoomMT->getMatrix().getTrans();  
  27.     trans.set(trans.x(), trans.y(), trans.z() - 0.2);  
  28.     zoomMT->setMatrix(osg::Matrix::translate(trans));  
  29. }  
对X轴和Y轴的旋转,同样可以修改旋转矩阵参数完成

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)  
  2. {  
  3.     FindFirstNamedNodeVisitor fnv("yRotMT");  
  4.     root->accept(fnv);  
  5.   
  6.     osg::Node *mtNode = fnv._foundNode;  
  7.     osg::MatrixTransform *yRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  8.     if (!yRotMT)  
  9.         return false;  
  10.   
  11.     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(yRotMT->getUpdateCallback());  
  12.   
  13.     if (!rotCallback)  
  14.         return false;  
  15.   
  16.     double speed = rotCallback->getRotateSpeed();  
  17.     speed += 0.02;  
  18.     rotCallback->setRotateSpeed(speed);  
  19.   
  20. }  
  21.   
  22. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)  
  23. {  
  24.     FindFirstNamedNodeVisitor fnv("yRotMT");  
  25.     root->accept(fnv);  
  26.   
  27.     osg::Node *mtNode = fnv._foundNode;  
  28.     osg::MatrixTransform *yRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  29.     if (!yRotMT)  
  30.         return false;  
  31.   
  32.     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(yRotMT->getUpdateCallback());  
  33.   
  34.     if (!rotCallback)  
  35.         return false;  
  36.   
  37.     double speed = rotCallback->getRotateSpeed();  
  38.     speed -= 0.02;  
  39.     rotCallback->setRotateSpeed(speed);  
  40. }  
osg中默认开启了0号灯光LIGHT0, 同时osg和opengl一样也开启了环境光LightModel,使得场景中存在微弱的环境光(默认为(0.2, 0.2, 0.2, 1.0))

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::StateSet* globalStateset = camera->getStateSet();  
  2. if (globalStateset)  
  3. {  
  4.     osg::LightModel* lightModel = new osg::LightModel;  
  5.     lightModel->setAmbientIntensity(osg::Vec4(0,0,0,0));  
  6.     globalStateset->setAttributeAndModes(lightModel, osg::StateAttribute::ON);  
  7. }  
上述代码设置了环境光为0,同时我们可以设置osg中的默认开启的LIGHT0(在osg::View类中进行设置),也可以自己声明一个灯光,灯光的设置方式如下:

通过一个LightSource来关联Light,并将LightSource添加到场景之中。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Group *root = new osg::Group;  
  2.   
  3. osg::Light* light = new osg::Light();  
  4. light->setLightNum(0);  
  5. light->setAmbient(osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f));  
  6. light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));  
  7. light->setPosition(osg::Vec4(0.0f, 0.0f, 2.0f, 1.0f));  
  8. osg::LightSource* lightsource = new osg::LightSource();  
  9. lightsource->setLight (light);  
  10. root->addChild (lightsource);   
在点击L键时,关闭和打开光照计算

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. if (ea.getKey()== osgGA::GUIEventAdapter::KEY_L)  
  2. {  
  3.     static int i = 0;  
  4.     if (i % 2 == 0) {  
  5.         root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  6.     } else {  
  7.         root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);  
  8.     }  
  9.     ++i;  
  10. }  
点击F键时,通过修改节点纹理状态参数完成纹理的Filter方式

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. if (ea.getKey()== osgGA::GUIEventAdapter::KEY_F)  
  2. {  
  3.     FindFirstNamedNodeVisitor fnv("quadGeode");  
  4.     root->accept(fnv);  
  5.   
  6.     osg::Node *mtNode = fnv._foundNode;  
  7.     osg::Geode *quadGeode = dynamic_cast<osg::Geode*>(mtNode);  
  8.     if (!quadGeode)  
  9.         return false;  
  10.   
  11.     osg::Texture2D *texture2D = dynamic_cast<osg::Texture2D*>(quadGeode->getOrCreateStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE));  
  12.       
  13.     static int i = 0;  
  14.     if (i % 3 == 0) {  
  15.         texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  16.         texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  17.     } else if (i % 3 == 1) {  
  18.         texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  19.         texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR_MIPMAP_NEAREST);  
  20.     } else {  
  21.         texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);  
  22.         texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);  
  23.     }  
  24.     ++i;  
  25. }  
最后将我们定义的GUIEventHandler添加到Viewer之中,之后就可以实现场景与外设的交互

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. this->addEventHandler(new ManipulatorSceneHandler());  
编译运行程序


附:本课源码(源码中可能存在错误和不足,仅供参考)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include "../osgNeHe.h"  
  2.   
  3. #include <QtCore/QTimer>  
  4. #include <QtGui/QApplication>  
  5. #include <QtGui/QVBoxLayout>  
  6.   
  7. #include <osgViewer/Viewer>  
  8. #include <osgDB/ReadFile>  
  9. #include <osgQt/GraphicsWindowQt>  
  10.   
  11. #include <osg/MatrixTransform>  
  12. #include <osg/NodeVisitor>  
  13. #include <osg/Texture2D>  
  14.   
  15. #include <osgGA/GUIEventAdapter>  
  16.   
  17. #include <osg/Light>  
  18. #include <osg/LightModel>  
  19. #include <osg/LightSource>  
  20.   
  21. float textureVertices[][2] = {  
  22.     //Front Face  
  23.     {0.0f, 0.0f},  
  24.     {1.0f, 0.0f},  
  25.     {1.0f, 1.0f},  
  26.     {0.0f, 1.0f},  
  27.     // Back Face  
  28.     {1.0f, 0.0f},  
  29.     {1.0f, 1.0f},  
  30.     {0.0f, 1.0f},  
  31.     {0.0f, 0.0f},  
  32.     // Top Face  
  33.     {0.0f, 1.0f},  
  34.     {0.0f, 0.0f},  
  35.     {1.0f, 0.0f},  
  36.     {1.0f, 1.0f},  
  37.     // Bottom Face  
  38.     {1.0f, 1.0f},  
  39.     {0.0f, 1.0f},  
  40.     {0.0f, 0.0f},  
  41.     {1.0f, 0.0f},  
  42.     // Right face  
  43.     {1.0f, 0.0f},  
  44.     {1.0f, 1.0f},  
  45.     {0.0f, 1.0f},  
  46.     {0.0f, 0.0f},  
  47.     // Left Face  
  48.     {0.0f, 0.0f},  
  49.     {1.0f, 0.0f},  
  50.     {1.0f, 1.0f},  
  51.     {0.0f, 1.0f}  
  52. };  
  53.   
  54. float QuadVertices[][3] = {  
  55.   
  56.     {-1.0f, -1.0f,  1.0f},  
  57.     { 1.0f, -1.0f,  1.0f},  
  58.     { 1.0f,  1.0f,  1.0f},  
  59.     {-1.0f,  1.0f,  1.0f},  
  60.   
  61.     {-1.0f, -1.0f, -1.0f},  
  62.     {-1.0f,  1.0f, -1.0f},  
  63.     { 1.0f,  1.0f, -1.0f},  
  64.     { 1.0f, -1.0f, -1.0f},  
  65.   
  66.     {-1.0f,  1.0f, -1.0f},  
  67.     {-1.0f,  1.0f,  1.0f},  
  68.     { 1.0f,  1.0f,  1.0f},  
  69.     { 1.0f,  1.0f, -1.0f},  
  70.   
  71.     {-1.0f, -1.0f, -1.0f},  
  72.     { 1.0f, -1.0f, -1.0f},  
  73.     { 1.0f, -1.0f,  1.0f},  
  74.     {-1.0f, -1.0f,  1.0f},  
  75.   
  76.     { 1.0f, -1.0f, -1.0f},  
  77.     { 1.0f,  1.0f, -1.0f},  
  78.     { 1.0f,  1.0f,  1.0f},  
  79.     { 1.0f, -1.0f,  1.0f},  
  80.   
  81.     {-1.0f, -1.0f, -1.0f},  
  82.     {-1.0f, -1.0f,  1.0f},  
  83.     {-1.0f,  1.0f,  1.0f},  
  84.     {-1.0f,  1.0f, -1.0f}  
  85.   
  86. };  
  87.   
  88. float normalVertics[][3] = {  
  89.     // Front Face  
  90.     { 0.0f, 0.0f, 1.0f},  
  91.     // Back Face  
  92.     { 0.0f, 0.0f,-1.0f},  
  93.     // Top Face  
  94.     { 0.0f, 1.0f, 0.0f},  
  95.     // Bottom Face  
  96.     { 0.0f,-1.0f, 0.0f},  
  97.     // Right face  
  98.     { 1.0f, 0.0f, 0.0f},  
  99.     // Left Face  
  100.     {-1.0f, 0.0f, 0.0f}  
  101. };  
  102.   
  103. //  
  104. //FindFirstNamedNodeVisitor用来遍历寻找与指定名称相同的节点  
  105.   
  106. class FindFirstNamedNodeVisitor : public osg::NodeVisitor  
  107. {  
  108. public:  
  109.     FindFirstNamedNodeVisitor(const std::string& name):  
  110.       osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),  
  111.           _name(name), _foundNode(NULL) {}  
  112.   
  113.       virtual void apply(osg::Node& node)  
  114.       {  
  115.           if (node.getName()==_name)  
  116.           {  
  117.               _foundNode = &node;  
  118.               return;  
  119.           }  
  120.           traverse(node);  
  121.       }  
  122.   
  123.       std::string _name;  
  124.       osg::Node *_foundNode;  
  125. };  
  126.   
  127. //  
  128. //RotateCallback  
  129.   
  130. class RotateCallback : public osg::NodeCallback  
  131. {  
  132.   
  133. public:  
  134.     RotateCallback(osg::Vec3d rotateAxis, double rotateSpeed) :   
  135.       osg::NodeCallback(),  
  136.           _rotateAxis(rotateAxis),   
  137.           _rotateSpeed(rotateSpeed),  
  138.           _rotateAngle(0.0)  
  139.       {  
  140.           //Nop  
  141.       }  
  142.   
  143.       void setRotateSpeed(double speed)  
  144.       {  
  145.           _rotateSpeed = speed;  
  146.       }  
  147.   
  148.       double getRotateSpeed() const  
  149.       {  
  150.           return _rotateSpeed;  
  151.       }  
  152.   
  153.       virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  154.       {  
  155.           osg::MatrixTransform *currentMT = dynamic_cast<osg::MatrixTransform*>(node);  
  156.           if (currentMT)  
  157.           {  
  158.               //获取当前的平移位置  
  159.               osg::Vec3d currentTranslate = currentMT->getMatrix().getTrans();  
  160.               osg::Matrix newMatrix = osg::Matrix::rotate(_rotateAngle, _rotateAxis) * osg::Matrix::translate(currentTranslate);  
  161.               currentMT->setMatrix(newMatrix);  
  162.               _rotateAngle += _rotateSpeed;  
  163.           }  
  164.   
  165.           traverse(node, nv);  
  166.       }  
  167.   
  168.   
  169. private:  
  170.     osg::Vec3d _rotateAxis;         //旋转轴  
  171.     double        _rotateSpeed;     //旋转速度  
  172.     double        _rotateAngle;     //当前旋转的角度  
  173. };  
  174.   
  175.   
  176.   
  177.   
  178. //  
  179.   
  180. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  181. {  
  182. public:  
  183.     ManipulatorSceneHandler()  
  184.     {  
  185.     }  
  186.   
  187.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  188.     {  
  189.         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);  
  190.         if (!viewer)  
  191.             return false;  
  192.         if (!viewer->getSceneData())  
  193.             return false;  
  194.         if (ea.getHandled())   
  195.             return false;  
  196.   
  197.         osg::Group *root = viewer->getSceneData()->asGroup();  
  198.   
  199.         switch(ea.getEventType())  
  200.         {  
  201.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  202.             {  
  203.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)  
  204.                 {  
  205.                     FindFirstNamedNodeVisitor fnv("yRotMT");  
  206.                     root->accept(fnv);  
  207.   
  208.                     osg::Node *mtNode = fnv._foundNode;  
  209.                     osg::MatrixTransform *yRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  210.                     if (!yRotMT)  
  211.                         return false;  
  212.   
  213.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(yRotMT->getUpdateCallback());  
  214.   
  215.                     if (!rotCallback)  
  216.                         return false;  
  217.   
  218.                     double speed = rotCallback->getRotateSpeed();  
  219.                     speed += 0.02;  
  220.                     rotCallback->setRotateSpeed(speed);  
  221.   
  222.                 }  
  223.   
  224.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)  
  225.                 {  
  226.                     FindFirstNamedNodeVisitor fnv("yRotMT");  
  227.                     root->accept(fnv);  
  228.   
  229.                     osg::Node *mtNode = fnv._foundNode;  
  230.                     osg::MatrixTransform *yRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  231.                     if (!yRotMT)  
  232.                         return false;  
  233.   
  234.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(yRotMT->getUpdateCallback());  
  235.   
  236.                     if (!rotCallback)  
  237.                         return false;  
  238.   
  239.                     double speed = rotCallback->getRotateSpeed();  
  240.                     speed -= 0.02;  
  241.                     rotCallback->setRotateSpeed(speed);  
  242.                 }  
  243.   
  244.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)  
  245.                 {  
  246.                     FindFirstNamedNodeVisitor fnv("xRotMT");  
  247.                     root->accept(fnv);  
  248.   
  249.                     osg::Node *mtNode = fnv._foundNode;  
  250.                     osg::MatrixTransform *xRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  251.                     if (!xRotMT)  
  252.                         return false;  
  253.   
  254.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(xRotMT->getUpdateCallback());  
  255.                       
  256.                     if (!rotCallback)  
  257.                         return false;  
  258.   
  259.                     double speed = rotCallback->getRotateSpeed();  
  260.                     speed += 0.02;  
  261.                     rotCallback->setRotateSpeed(speed);  
  262.                 }  
  263.   
  264.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Down)  
  265.                 {  
  266.                     FindFirstNamedNodeVisitor fnv("xRotMT");  
  267.                     root->accept(fnv);  
  268.   
  269.                     osg::Node *mtNode = fnv._foundNode;  
  270.                     osg::MatrixTransform *xRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  271.                     if (!xRotMT)  
  272.                         return false;  
  273.   
  274.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(xRotMT->getUpdateCallback());  
  275.   
  276.                     if (!rotCallback)  
  277.                         return false;  
  278.   
  279.                     double speed = rotCallback->getRotateSpeed();  
  280.                     speed -= 0.02;  
  281.                     rotCallback->setRotateSpeed(speed);  
  282.                 }  
  283.                   
  284.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Up)  
  285.                 {     
  286.                     FindFirstNamedNodeVisitor fnv("zoomMT");  
  287.                     root->accept(fnv);  
  288.   
  289.                     osg::Node *mtNode = fnv._foundNode;  
  290.                     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  291.                     if (!zoomMT)  
  292.                         return false;  
  293.                       
  294.                     osg::Vec3 trans = zoomMT->getMatrix().getTrans();  
  295.                     trans.set(trans.x(), trans.y(), trans.z() + 0.2);  
  296.                     zoomMT->setMatrix(osg::Matrix::translate(trans));  
  297.                 }  
  298.   
  299.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Down)  
  300.                 {  
  301.                     FindFirstNamedNodeVisitor fnv("zoomMT");  
  302.                     root->accept(fnv);  
  303.   
  304.                     osg::Node *mtNode = fnv._foundNode;  
  305.                     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  306.                     if (!zoomMT)  
  307.                         return false;  
  308.   
  309.                     osg::Vec3 trans = zoomMT->getMatrix().getTrans();  
  310.                     trans.set(trans.x(), trans.y(), trans.z() - 0.2);  
  311.                     zoomMT->setMatrix(osg::Matrix::translate(trans));  
  312.                 }  
  313.   
  314.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_L)  
  315.                 {  
  316.                     static int i = 0;  
  317.                     if (i % 2 == 0) {  
  318.                         root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  319.                     } else {  
  320.                         root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);  
  321.                     }  
  322.                     ++i;  
  323.                 }  
  324.   
  325.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_F)  
  326.                 {  
  327.                     FindFirstNamedNodeVisitor fnv("quadGeode");  
  328.                     root->accept(fnv);  
  329.   
  330.                     osg::Node *mtNode = fnv._foundNode;  
  331.                     osg::Geode *quadGeode = dynamic_cast<osg::Geode*>(mtNode);  
  332.                     if (!quadGeode)  
  333.                         return false;  
  334.   
  335.                     osg::Texture2D *texture2D = dynamic_cast<osg::Texture2D*>(quadGeode->getOrCreateStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE));  
  336.                       
  337.                     static int i = 0;  
  338.                     if (i % 3 == 0) {  
  339.                         texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  340.                         texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  341.                     } else if (i % 3 == 1) {  
  342.                         texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  343.                         texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR_MIPMAP_NEAREST);  
  344.                     } else {  
  345.                         texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);  
  346.                         texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);  
  347.                     }  
  348.                     ++i;  
  349.                 }  
  350.             }  
  351.         defaultbreak;  
  352.         }  
  353.         return false;  
  354.     }  
  355. };  
  356.   
  357. //  
  358.   
  359.   
  360.   
  361. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  362. {  
  363. public:  
  364.     ViewerWidget(osg::Node *scene = NULL)  
  365.     {  
  366.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  367.   
  368.         QVBoxLayout* layout = new QVBoxLayout;  
  369.         layout->addWidget(renderWidget);  
  370.         layout->setContentsMargins(0, 0, 0, 1);  
  371.         setLayout( layout );  
  372.   
  373.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  374.         _timer.start( 10 );  
  375.     }  
  376.   
  377.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  378.     {  
  379.         osg::Camera* camera = this->getCamera();  
  380.         camera->setGraphicsContext( gw );  
  381.   
  382.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  383.   
  384.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  385.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  386.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  387.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  388.   
  389.         osg::StateSet* globalStateset = camera->getStateSet();  
  390.         if (globalStateset)  
  391.         {  
  392.             osg::LightModel* lightModel = new osg::LightModel;  
  393.             lightModel->setAmbientIntensity(osg::Vec4(0,0,0,0));  
  394.             globalStateset->setAttributeAndModes(lightModel, osg::StateAttribute::ON);  
  395.         }  
  396.   
  397.         this->setSceneData( scene );  
  398.         this->addEventHandler(new ManipulatorSceneHandler());  
  399.   
  400.         return gw->getGLWidget();  
  401.     }  
  402.   
  403.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  404.     {  
  405.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  406.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  407.         traits->windowName = name;  
  408.         traits->windowDecoration = windowDecoration;  
  409.         traits->x = x;  
  410.         traits->y = y;  
  411.         traits->width = w;  
  412.         traits->height = h;  
  413.         traits->doubleBuffer = true;  
  414.         traits->alpha = ds->getMinimumNumAlphaBits();  
  415.         traits->stencil = ds->getMinimumNumStencilBits();  
  416.         traits->sampleBuffers = ds->getMultiSamples();  
  417.         traits->samples = ds->getNumMultiSamples();  
  418.   
  419.         return new osgQt::GraphicsWindowQt(traits.get());  
  420.     }  
  421.   
  422.     virtual void paintEvent( QPaintEvent* event )  
  423.     {   
  424.         frame();   
  425.     }  
  426.   
  427. protected:  
  428.   
  429.     QTimer _timer;  
  430. };  
  431.   
  432.   
  433.   
  434. osg::Node*  buildScene()  
  435. {  
  436.     osg::Group *root = new osg::Group;  
  437.   
  438.     osg::Light* light = new osg::Light();  
  439.     light->setLightNum(0);  
  440.     light->setAmbient(osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f));  
  441.     light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));  
  442.     light->setPosition(osg::Vec4(0.0f, 0.0f, 2.0f, 1.0f));  
  443.     osg::LightSource* lightsource = new osg::LightSource();  
  444.     lightsource->setLight (light);  
  445.     root->addChild (lightsource);   
  446.   
  447.     osg::MatrixTransform *quadMT = new osg::MatrixTransform;  
  448.     quadMT->setName("zoomMT");  
  449.     quadMT->setMatrix(osg::Matrix::translate(0.0, 0.0, -5.0));  
  450.   
  451.     osg::MatrixTransform *quadXRotMT = new osg::MatrixTransform;  
  452.     quadXRotMT->setName("xRotMT");  
  453.     RotateCallback *xRotCallback = new RotateCallback(osg::X_AXIS, 0.0);  
  454.     quadXRotMT->setUpdateCallback(xRotCallback);  
  455.   
  456.   
  457.     osg::MatrixTransform *quadYRotMT = new osg::MatrixTransform;  
  458.     quadYRotMT->setName("yRotMT");  
  459.     RotateCallback *yRotCallback = new RotateCallback(osg::Y_AXIS, 0.0);  
  460.     quadYRotMT->setUpdateCallback(yRotCallback);  
  461.   
  462.     osg::Geometry *quadGeometry = new osg::Geometry;  
  463.     osg::Vec3Array *quadVertexArray = new osg::Vec3Array;  
  464.     for (unsigned i = 0; i < sizeof(QuadVertices); ++i)  
  465.     {  
  466.         quadVertexArray->push_back(osg::Vec3(QuadVertices[i][0], QuadVertices[i][1], QuadVertices[i][2]));  
  467.     }  
  468.     quadGeometry->setVertexArray(quadVertexArray);  
  469.   
  470.     osg::Vec2Array* texcoords = new osg::Vec2Array;  
  471.     for (unsigned i = 0; i < sizeof(textureVertices); ++i)  
  472.     {  
  473.         texcoords->push_back(osg::Vec2(textureVertices[i][0], textureVertices[i][1]));  
  474.     }  
  475.     quadGeometry->setTexCoordArray(0,texcoords);  
  476.   
  477.     osg::Vec3Array *quadNormalArray = new osg::Vec3Array;  
  478.     for (unsigned i = 0; i < sizeof(normalVertics); ++i)  
  479.     {  
  480.         quadNormalArray->push_back(osg::Vec3(normalVertics[i][0], normalVertics[i][1], normalVertics[i][2]));  
  481.     }  
  482.     quadGeometry->setNormalArray(quadNormalArray, osg::Array::BIND_PER_PRIMITIVE_SET);  
  483.   
  484.     int first = 0;  
  485.     for (unsigned i = 0; i < 6; ++i)  
  486.     {  
  487.         osg::DrawArrays *vertexIndices = new osg::DrawArrays(osg::PrimitiveSet::QUADS, first, 4);  
  488.         first += 4;  
  489.         quadGeometry->addPrimitiveSet(vertexIndices);  
  490.     }  
  491.   
  492.     osg::Image *textureImage = osgDB::readImageFile("Data/Crate.bmp");  
  493.     osg::Texture2D *texture2D = new osg::Texture2D;  
  494.     texture2D->setImage(textureImage);  
  495.     texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);  
  496.     texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);  
  497.   
  498.     osg::Geode *quadGeode = new osg::Geode;  
  499.     quadGeode->setName("quadGeode");  
  500.     quadGeode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D);  
  501.     quadGeode->addDrawable(quadGeometry);  
  502.     quadYRotMT->addChild(quadGeode);  
  503.     quadXRotMT->addChild(quadYRotMT);  
  504.     quadMT->addChild(quadXRotMT);  
  505.   
  506.     root->addChild(quadMT);  
  507.   
  508.     return root;  
  509. }  
  510.   
  511.   
  512.   
  513. int main( int argc, char** argv )  
  514. {  
  515.     QApplication app(argc, argv);  
  516.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  517.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  518.     viewWidget->show();  
  519.     return app.exec();  
  520. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译运行 OpenSceneGraph-OpenSceneGraph-3.6.4 需要按照以下步骤进行操作: 1. 首先,确保你的计算机上已经安装了 CMake,C++ 编译器和 OpenGL 兼容的图形驱动程序。这些是编译和运行 OpenSceneGraph 所必需的工具和库。 2. 下载 OpenSceneGraph-OpenSceneGraph-3.6.4 的源代码,可以在官方网站或开源项目托管网站上找到。确保下载的版本正确,避免出错。 3. 解压源代码文件并进入解压后的目录。 4. 创建一个用于构建的构建目录,并进入该目录。例如:mkdir build && cd build。 5. 运行 CMake 命令来生成构建系统所需的文件和配置。命令可能类似于:cmake path/to/OpenSceneGraph-OpenSceneGraph-3.6.4。你可以使用其他参数和选项来自定义构建过程。 6. 确保 CMake 执行成功并生成了构建系统所需的文件。 7. 使用你的 C++ 编译器来构建 OpenSceneGraph。可以使用 make 命令,或者其他编译工具,根据你的操作系统和编译环境来选择。例如:make。 8. 等待编译完成,这可能需要一段时间,具体取决于你的计算机性能。 9. 构建完成后,检查是否有错误或警告信息。如果有,需要解决它们,并重新运行编译步骤。 10. 运行编译好的 OpenSceneGraph 可执行文件,这将启动 OpenSceneGraph 程序并运行示例或其他自定义的应用程序。 总之,编译和运行 OpenSceneGraph-OpenSceneGraph-3.6.4 需要先安装必需的工具和库,然后使用 CMake 生成构建系统所需的文件,再使用 C++ 编译器进行编译,最后运行生成的可执行文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值