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

  • 简介

本课实现在场景中绘制旋转的星星,主要的内容包括使用Blend方式设置纹理图片的颜色,在场景中操作物体实现简单的动画效果。

本课中描述的内容在前面的课程中已经有比较详细的介绍,本课综合运用了前面课程所学内容。

  • 实现

首先同NeHe教程中设置的一样,我们先创建50颗星星,代码如下

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Group *starGroup = new osg::Group;  
  2.   
  3. for (unsigned i = 0; i < StarNumber; ++i)  
  4. {  
  5.     float dist=(float(i)/StarNumber)*5.0f;  
  6.     float angle= float(i)/(StarNumber * 30);  
  7.   
  8.     osg::Group *star = new osg::Group;  
  9.       
  10.                //设置变换节点抵消对整个场景的倾斜  
  11.     osg::MatrixTransform *antiTileMT = new osg::MatrixTransform;  
  12.     antiTileMT->setUpdateCallback(new AntiTiltCallback);  
  13.   
  14.     //设置变换节点抵消每颗星星的旋转  
  15.                osg::MatrixTransform *antiDirectMT = new osg::MatrixTransform;  
  16.     antiDirectMT->setUpdateCallback(new RotateCallback(osg::Z_AXIS, -angle));  
  17.   
  18.     osg::MatrixTransform *directionMT = new osg::MatrixTransform;  
  19.     directionMT->setUpdateCallback(new RotateCallback(osg::Z_AXIS, angle));  
  20.       
  21.     osg::MatrixTransform *moveMT = new osg::MatrixTransform;  
  22.     moveMT->setMatrix(osg::Matrix::translate(dist, 0, 0));  
  23.     moveMT->setUpdateCallback(new TranslateCallback);  
  24.       
  25.     osg::MatrixTransform *spinMT = new osg::MatrixTransform;  
  26.     spinMT->setUpdateCallback(new RotateCallback(osg::Z_AXIS, 0.02));  
  27.   
  28.     star->addChild(directionMT);  
  29.     directionMT->addChild(moveMT);  
  30.   
  31.     //星星叶节点  
  32.     osg::Geode *starQuad = new osg::Geode;  
  33.     osg::Geometry *starGeometry = new osg::Geometry;  
  34.   
  35.     osg::Texture2D *texture = new osg::Texture2D;  
  36.     texture->setImage(osgDB::readImageFile("Data/Star.bmp"));  
  37.     texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  38.     texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  39.       
  40.     osg::Vec3Array *coords = new osg::Vec3Array;  
  41.     coords->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));  
  42.     coords->push_back(osg::Vec3(1.0f,-1.0f, 0.0f));  
  43.     coords->push_back(osg::Vec3(1.0f,1.0f, 0.0f));  
  44.     coords->push_back(osg::Vec3(-1.0f,1.0f, 0.0f));  
  45.     starGeometry->setVertexArray(coords);  
  46.   
  47.     osg::Vec4Array *colors = new osg::Vec4Array;  
  48.     colors->push_back(osg::Vec4(rand() % 256 / 255.0f, rand() % 256 / 255.0f, rand() % 256 / 255.0f, 1.0));  
  49.     starGeometry->setColorArray(colors);  
  50.     starGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);  
  51.     starGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  52.   
  53.     osg::Vec2Array *textureArray = new osg::Vec2Array;  
  54.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  55.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  56.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  57.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  58.     starGeometry->setTexCoordArray(0, textureArray);  
  59.   
  60.     starGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);  
  61.     starGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  62.     starGeometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);  
  63.     osg::BlendFunc *blendFunc = new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE, 0.5, 0.5);  
  64.     starGeometry->getOrCreateStateSet()->setAttributeAndModes(blendFunc,osg::StateAttribute::ON);  
  65.     starGeometry->setUseVertexBufferObjects(true);  
  66.     starGeometry->setUseDisplayList(false);  
  67.     starGeometry->setUpdateCallback(new ColorCallback);  
  68.     starQuad->addDrawable(starGeometry);  
  69.   
  70.     moveMT->addChild(antiDirectMT);  
  71.     antiDirectMT->addChild(antiTileMT);  
  72.     antiTileMT->addChild(spinMT);  
  73.     spinMT->addChild(starQuad);  
  74.   
  75.     starGroup->addChild(star);  

我们将每一颗星星设置为一个osg::Group的节点,和NeHe教程中一样对每颗星星设置了旋转和平移,并将所有的星星添加到starGroup这个组节点下面。

为了实现每一帧对场景进行更新实现动画效果,我们定义了一系列的更新回调

实现星星颜色的变化,我们定义了ColorCallback(继承于osg::Drawable::UpdateCallback)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class ColorCallback : public osg::Drawable::UpdateCallback  
  2. {  
  3.      virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)  
  4.      {  
  5.          osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);  
  6.          if (!geometry)  
  7.          {  
  8.              return;  
  9.          }  
  10.   
  11.          osg::Vec4Array *colorArray = dynamic_cast<osg::Vec4Array*>(geometry->getColorArray());  
  12.         if (colorArray)  
  13.         {  
  14.             osg::Vec4 color;  
  15.             color.set(rand() % 256 / 255.0f, rand() % 256 / 255.0f, rand() % 256 / 255.0f, 1.0);  
  16.             colorArray->clear();  
  17.             colorArray->push_back(color);  
  18.             colorArray->dirty();  
  19.         }  
  20.      }  
  21. };  
为了实现星星的旋转我们定义了旋转更新回调(与前面课程中一样)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class RotateCallback : public osg::NodeCallback  
  2. {  
  3.   
  4. public:  
  5.     RotateCallback(osg::Vec3d rotateAxis, double rotateSpeed) :   
  6.       osg::NodeCallback(),  
  7.           _rotateAxis(rotateAxis),   
  8.           _rotateSpeed(rotateSpeed),  
  9.           _rotateAngle(0.0)  
  10.       {  
  11.           //Nop  
  12.       }  
  13.   
  14.       void setRotateSpeed(double speed)  
  15.       {  
  16.           _rotateSpeed = speed;  
  17.       }  
  18.   
  19.       double getRotateSpeed() const  
  20.       {  
  21.           return _rotateSpeed;  
  22.       }  
  23.   
  24.       virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  25.       {  
  26.           osg::MatrixTransform *currentMT = dynamic_cast<osg::MatrixTransform*>(node);  
  27.           if (currentMT)  
  28.           {  
  29.               //获取当前的平移位置  
  30.               osg::Vec3d currentTranslate = currentMT->getMatrix().getTrans();  
  31.               osg::Matrix newMatrix = osg::Matrix::rotate(_rotateAngle, _rotateAxis) * osg::Matrix::translate(currentTranslate);  
  32.               currentMT->setMatrix(newMatrix);  
  33.               _rotateAngle += _rotateSpeed;  
  34.           }  
  35.   
  36.           traverse(node, nv);  
  37.       }  
  38.   
  39.   
  40. private:  
  41.     osg::Vec3d _rotateAxis;         //旋转轴  
  42.     double        _rotateSpeed;     //旋转速度  
  43.     double        _rotateAngle;     //当前旋转的角度  
  44. };  

同样实现平移操作也定义了更新回调

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class TranslateCallback : public osg::NodeCallback  
  2. {  
  3. public:  
  4.   
  5.       virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  6.       {  
  7.           osg::MatrixTransform *currentMT = dynamic_cast<osg::MatrixTransform*>(node);  
  8.           if (currentMT)  
  9.           {  
  10.               osg::Vec3d dist = currentMT->getMatrix().getTrans();  
  11.               double x = dist.x();  
  12.               x -= 0.01;  
  13.               if(x < 0.0f)  
  14.                   x += 5.0;  
  15.               osg::Vec3d newDist = osg::Vec3d(x, 0, 0);  
  16.   
  17.               currentMT->setMatrix(osg::Matrix::translate(newDist));  
  18.           }  
  19.   
  20.           traverse(node, nv);  
  21.       }  
  22. };  
响应键盘操作定义在MainpulatorSceneHandler

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
该类在第八课中已有介绍

最后将创建的星星节点添加到根节点下

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Node*  buildScene()  
  2. {  
  3.     createStars();  
  4.   
  5.     osg::Group *root = new osg::Group;  
  6.   
  7.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  8.     zoomMT->setName("zoomMT");  
  9.     zoomMT->setMatrix(osg::Matrix::translate(0, 0, -15.0f));  
  10.     root->addChild(zoomMT);  
  11.   
  12.     osg::MatrixTransform *tiltMT = new osg::MatrixTransform;  
  13.     tiltMT->setName("tiltMT");  
  14.     tiltMT->setMatrix(osg::Matrix::rotate(0, osg::X_AXIS));  
  15.     zoomMT->addChild(tiltMT);  
  16.   
  17.     tiltMT->addChild(createStars());  
  18.   
  19.     return root;  
  20. }  

需要注意的是在星星叶节点创建的时候开启Blend,同时关闭深度测试和光照(OSG中默认开启这点和OpenGL中不一致)

编译运行程序,一个漂亮的场景就出现了。


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

[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/Texture2D>  
  13.   
  14. #include <osgGA/GUIEventAdapter>  
  15. #include <osg/BlendFunc>  
  16.   
  17. #include <osg/Drawable>  
  18.   
  19. const int StarNumber = 50;  
  20. double tilt = 0.0;  
  21.   
  22.   
  23. //  
  24. //FindFirstNamedNodeVisitor用来遍历寻找与指定名称相同的节点  
  25.   
  26. class FindFirstNamedNodeVisitor : public osg::NodeVisitor  
  27. {  
  28. public:  
  29.     FindFirstNamedNodeVisitor(const std::string& name):  
  30.       osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),  
  31.           _name(name), _foundNode(NULL) {}  
  32.   
  33.       virtual void apply(osg::Node& node)  
  34.       {  
  35.           if (node.getName()==_name)  
  36.           {  
  37.               _foundNode = &node;  
  38.               return;  
  39.           }  
  40.           traverse(node);  
  41.       }  
  42.   
  43.       std::string _name;  
  44.       osg::Node *_foundNode;  
  45. };  
  46.   
  47.   
  48. //  
  49. //ColorCallback  
  50.   
  51. class ColorCallback : public osg::Drawable::UpdateCallback  
  52. {  
  53.      virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)  
  54.      {  
  55.          osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);  
  56.          if (!geometry)  
  57.          {  
  58.              return;  
  59.          }  
  60.   
  61.          osg::Vec4Array *colorArray = dynamic_cast<osg::Vec4Array*>(geometry->getColorArray());  
  62.         if (colorArray)  
  63.         {  
  64.             osg::Vec4 color;  
  65.             color.set(rand() % 256 / 255.0f, rand() % 256 / 255.0f, rand() % 256 / 255.0f, 1.0);  
  66.             colorArray->clear();  
  67.             colorArray->push_back(color);  
  68.             colorArray->dirty();  
  69.         }  
  70.      }  
  71. };  
  72.   
  73.   
  74. //  
  75. //RotateCallback  
  76.   
  77. class RotateCallback : public osg::NodeCallback  
  78. {  
  79.   
  80. public:  
  81.     RotateCallback(osg::Vec3d rotateAxis, double rotateSpeed) :   
  82.       osg::NodeCallback(),  
  83.           _rotateAxis(rotateAxis),   
  84.           _rotateSpeed(rotateSpeed),  
  85.           _rotateAngle(0.0)  
  86.       {  
  87.           //Nop  
  88.       }  
  89.   
  90.       void setRotateSpeed(double speed)  
  91.       {  
  92.           _rotateSpeed = speed;  
  93.       }  
  94.   
  95.       double getRotateSpeed() const  
  96.       {  
  97.           return _rotateSpeed;  
  98.       }  
  99.   
  100.       virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  101.       {  
  102.           osg::MatrixTransform *currentMT = dynamic_cast<osg::MatrixTransform*>(node);  
  103.           if (currentMT)  
  104.           {  
  105.               //获取当前的平移位置  
  106.               osg::Vec3d currentTranslate = currentMT->getMatrix().getTrans();  
  107.               osg::Matrix newMatrix = osg::Matrix::rotate(_rotateAngle, _rotateAxis) * osg::Matrix::translate(currentTranslate);  
  108.               currentMT->setMatrix(newMatrix);  
  109.               _rotateAngle += _rotateSpeed;  
  110.           }  
  111.   
  112.           traverse(node, nv);  
  113.       }  
  114.   
  115.   
  116. private:  
  117.     osg::Vec3d _rotateAxis;         //旋转轴  
  118.     double        _rotateSpeed;     //旋转速度  
  119.     double        _rotateAngle;     //当前旋转的角度  
  120. };  
  121.   
  122.   
  123. //  
  124. //AntiTIltCallback  
  125.   
  126. class AntiTiltCallback : public osg::NodeCallback  
  127. {  
  128. public:  
  129.   
  130.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  131.     {  
  132.         osg::MatrixTransform *currentMT = dynamic_cast<osg::MatrixTransform*>(node);  
  133.         if (currentMT)  
  134.         {  
  135.             currentMT->setMatrix(osg::Matrix::rotate(-tilt, osg::X_AXIS));  
  136.         }  
  137.   
  138.         traverse(node, nv);  
  139.     }  
  140. };  
  141.   
  142.   
  143. //  
  144. //TranslateCallback   
  145.   
  146.   
  147. class TranslateCallback : public osg::NodeCallback  
  148. {  
  149. public:  
  150.   
  151.       virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  152.       {  
  153.           osg::MatrixTransform *currentMT = dynamic_cast<osg::MatrixTransform*>(node);  
  154.           if (currentMT)  
  155.           {  
  156.               osg::Vec3d dist = currentMT->getMatrix().getTrans();  
  157.               double x = dist.x();  
  158.               x -= 0.01;  
  159.               if(x < 0.0f)  
  160.                   x += 5.0;  
  161.               osg::Vec3d newDist = osg::Vec3d(x, 0, 0);  
  162.   
  163.               currentMT->setMatrix(osg::Matrix::translate(newDist));  
  164.           }  
  165.   
  166.           traverse(node, nv);  
  167.       }  
  168. };  
  169.   
  170.   
  171.   
  172.   
  173. //  
  174.   
  175. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  176. {  
  177. public:  
  178.     ManipulatorSceneHandler()  
  179.     {  
  180.     }  
  181.   
  182.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  183.     {  
  184.         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);  
  185.         if (!viewer)  
  186.             return false;  
  187.         if (!viewer->getSceneData())  
  188.             return false;  
  189.         if (ea.getHandled())   
  190.             return false;  
  191.   
  192.         osg::Group *root = viewer->getSceneData()->asGroup();  
  193.   
  194.         switch(ea.getEventType())  
  195.         {  
  196.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  197.             {  
  198.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Up)  
  199.                 {  
  200.                     FindFirstNamedNodeVisitor fnv("tiltMT");  
  201.                     root->accept(fnv);  
  202.   
  203.                     osg::Node *mtNode = fnv._foundNode;  
  204.                     osg::MatrixTransform *tiltMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  205.                     if (!tiltMT)  
  206.                         return false;  
  207.   
  208.                     osg::Matrix tiltMatrix = tiltMT->getMatrix();  
  209.                     osg::Quat original = tiltMatrix.getRotate();          
  210.                     double angle;  
  211.                     osg::Vec3 vec;  
  212.                     original.getRotate(angle, vec);  
  213.                     angle += 0.03;  
  214.                     tiltMT->setMatrix(osg::Matrix::rotate(angle, osg::X_AXIS));  
  215.                     tilt = angle;  
  216.                 }  
  217.   
  218.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Page_Down)  
  219.                 {  
  220.                     FindFirstNamedNodeVisitor fnv("tiltMT");  
  221.                     root->accept(fnv);  
  222.   
  223.                     osg::Node *mtNode = fnv._foundNode;  
  224.                     osg::MatrixTransform *tiltMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  225.                     if (!tiltMT)  
  226.                         return false;  
  227.   
  228.                     osg::Matrix tiltMatrix = tiltMT->getMatrix();  
  229.                     osg::Quat original = tiltMatrix.getRotate();  
  230.                     double angle;  
  231.                     osg::Vec3 vec;  
  232.                     original.getRotate(angle, vec);  
  233.                     angle -= 0.03;  
  234.                     tiltMT->setMatrix(osg::Matrix::rotate(angle, osg::X_AXIS));  
  235.                     tilt = angle;  
  236.                 }  
  237.   
  238.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)  
  239.                 {  
  240.                     FindFirstNamedNodeVisitor fnv("zoomMT");  
  241.                     root->accept(fnv);  
  242.   
  243.                     osg::Node *mtNode = fnv._foundNode;  
  244.                     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  245.                     if (!zoomMT)  
  246.                         return false;  
  247.                     zoomMT->setMatrix(osg::Matrix::translate(zoomMT->getMatrix().getTrans() + osg::Vec3(0, 0, 0.5)));  
  248.                 }  
  249.   
  250.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Down)  
  251.                 {  
  252.                     FindFirstNamedNodeVisitor fnv("zoomMT");  
  253.                     root->accept(fnv);  
  254.   
  255.                     osg::Node *mtNode = fnv._foundNode;  
  256.                     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  257.                     if (!zoomMT)  
  258.                         return false;  
  259.                     zoomMT->setMatrix(osg::Matrix::translate(zoomMT->getMatrix().getTrans() + osg::Vec3(0, 0, -0.5)));                      
  260.                 }  
  261.             }  
  262.         defaultbreak;  
  263.         }  
  264.         return false;  
  265.     }  
  266. };  
  267.   
  268. //  
  269.   
  270. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  271. {  
  272. public:  
  273.     ViewerWidget(osg::Node *scene = NULL)  
  274.     {  
  275.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  276.   
  277.         QVBoxLayout* layout = new QVBoxLayout;  
  278.         layout->addWidget(renderWidget);  
  279.         layout->setContentsMargins(0, 0, 0, 1);  
  280.         setLayout( layout );  
  281.   
  282.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  283.         _timer.start( 10 );  
  284.     }  
  285.   
  286.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  287.     {  
  288.         osg::Camera* camera = this->getCamera();  
  289.         camera->setGraphicsContext( gw );  
  290.   
  291.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  292.   
  293.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 0.5) );  
  294.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  295.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  296.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  297.   
  298.         this->setSceneData( scene );  
  299.         this->addEventHandler(new ManipulatorSceneHandler());  
  300.   
  301.         return gw->getGLWidget();  
  302.     }  
  303.   
  304.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  305.     {  
  306.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  307.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  308.         traits->windowName = name;  
  309.         traits->windowDecoration = windowDecoration;  
  310.         traits->x = x;  
  311.         traits->y = y;  
  312.         traits->width = w;  
  313.         traits->height = h;  
  314.         traits->doubleBuffer = true;  
  315.         traits->alpha = ds->getMinimumNumAlphaBits();  
  316.         traits->stencil = ds->getMinimumNumStencilBits();  
  317.         traits->sampleBuffers = ds->getMultiSamples();  
  318.         traits->samples = ds->getNumMultiSamples();  
  319.   
  320.         return new osgQt::GraphicsWindowQt(traits.get());  
  321.     }  
  322.   
  323.     virtual void paintEvent( QPaintEvent* event )  
  324.     {   
  325.         frame();   
  326.     }  
  327.   
  328. protected:  
  329.   
  330.     QTimer _timer;  
  331. };  
  332.   
  333.   
  334. osg::Group* createStars()  
  335. {  
  336.     osg::Group *starGroup = new osg::Group;  
  337.   
  338.     for (unsigned i = 0; i < StarNumber; ++i)  
  339.     {  
  340.         float dist=(float(i)/StarNumber)*5.0f;  
  341.         float angle= float(i)/(StarNumber * 30);  
  342.   
  343.         osg::Group *star = new osg::Group;  
  344.           
  345.         osg::MatrixTransform *antiTileMT = new osg::MatrixTransform;  
  346.         antiTileMT->setUpdateCallback(new AntiTiltCallback);  
  347.   
  348.         osg::MatrixTransform *antiDirectMT = new osg::MatrixTransform;  
  349.         antiDirectMT->setUpdateCallback(new RotateCallback(osg::Z_AXIS, -angle));  
  350.   
  351.         osg::MatrixTransform *directionMT = new osg::MatrixTransform;  
  352.         directionMT->setUpdateCallback(new RotateCallback(osg::Z_AXIS, angle));  
  353.           
  354.         osg::MatrixTransform *moveMT = new osg::MatrixTransform;  
  355.         moveMT->setMatrix(osg::Matrix::translate(dist, 0, 0));  
  356.         moveMT->setUpdateCallback(new TranslateCallback);  
  357.           
  358.         osg::MatrixTransform *spinMT = new osg::MatrixTransform;  
  359.         spinMT->setUpdateCallback(new RotateCallback(osg::Z_AXIS, 0.02));  
  360.   
  361.         star->addChild(directionMT);  
  362.         directionMT->addChild(moveMT);  
  363.   
  364.         //星星叶节点  
  365.         osg::Geode *starQuad = new osg::Geode;  
  366.         osg::Geometry *starGeometry = new osg::Geometry;  
  367.   
  368.         osg::Texture2D *texture = new osg::Texture2D;  
  369.         texture->setImage(osgDB::readImageFile("Data/Star.bmp"));  
  370.         texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  371.         texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  372.           
  373.         osg::Vec3Array *coords = new osg::Vec3Array;  
  374.         coords->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));  
  375.         coords->push_back(osg::Vec3(1.0f,-1.0f, 0.0f));  
  376.         coords->push_back(osg::Vec3(1.0f,1.0f, 0.0f));  
  377.         coords->push_back(osg::Vec3(-1.0f,1.0f, 0.0f));  
  378.         starGeometry->setVertexArray(coords);  
  379.   
  380.         osg::Vec4Array *colors = new osg::Vec4Array;  
  381.         colors->push_back(osg::Vec4(rand() % 256 / 255.0f, rand() % 256 / 255.0f, rand() % 256 / 255.0f, 1.0));  
  382.         starGeometry->setColorArray(colors);  
  383.         starGeometry->setColorBinding(osg::Geometry::BIND_OVERALL);  
  384.         starGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  385.   
  386.         osg::Vec2Array *textureArray = new osg::Vec2Array;  
  387.         textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  388.         textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  389.         textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  390.         textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  391.         starGeometry->setTexCoordArray(0, textureArray);  
  392.   
  393.         starGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);  
  394.         starGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  395.         starGeometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);  
  396.         osg::BlendFunc *blendFunc = new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE, 0.5, 0.5);  
  397.         starGeometry->getOrCreateStateSet()->setAttributeAndModes(blendFunc,osg::StateAttribute::ON);  
  398.         starGeometry->setUseVertexBufferObjects(true);  
  399.         starGeometry->setUseDisplayList(false);  
  400.         starGeometry->setUpdateCallback(new ColorCallback);  
  401.         starQuad->addDrawable(starGeometry);  
  402.   
  403.         moveMT->addChild(antiDirectMT);  
  404.         antiDirectMT->addChild(antiTileMT);  
  405.         antiTileMT->addChild(spinMT);  
  406.         spinMT->addChild(starQuad);  
  407.   
  408.         starGroup->addChild(star);  
  409.     }  
  410.   
  411.     return starGroup;  
  412. }  
  413.   
  414.   
  415.   
  416. osg::Node*  buildScene()  
  417. {  
  418.     createStars();  
  419.   
  420.     osg::Group *root = new osg::Group;  
  421.   
  422.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  423.     zoomMT->setName("zoomMT");  
  424.     zoomMT->setMatrix(osg::Matrix::translate(0, 0, -15.0f));  
  425.     root->addChild(zoomMT);  
  426.   
  427.     osg::MatrixTransform *tiltMT = new osg::MatrixTransform;  
  428.     tiltMT->setName("tiltMT");  
  429.     tiltMT->setMatrix(osg::Matrix::rotate(0, osg::X_AXIS));  
  430.     zoomMT->addChild(tiltMT);  
  431.   
  432.     tiltMT->addChild(createStars());  
  433.   
  434.     return root;  
  435. }  
  436.   
  437.   
  438.   
  439. int main( int argc, char** argv )  
  440. {  
  441.     QApplication app(argc, argv);  
  442.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  443.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  444.     viewWidget->show();  
  445.     return app.exec();  
  446. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值