OpenSceneGraph实现的NeHe OpenGL教程 - 第二十课

来源:互联网 发布:unity3d 屏幕破碎特效 编辑:程序博客网 时间:2024/05/16 10:21
  • 简介

这节课讨论的是蒙板技术。所谓蒙板技术可能很多人在2D绘图程序中已经使用过了。例如,我们希望在背景图片上绘制一个人物(精灵)。因为人物的图片是矩形的,而人物本身又是不规则图形,所以矩形图片中会有一些空白的部分。如果我们不将这些空白的部分去掉,直接绘制人物图片的话,程序的效果肯定会很差。这时我们就需要使用蒙板技术了,首先要产生一个和人物图片一样的黑白掩码图片,然后先让这幅黑白掩码图片与背景图片进行异或操作,然后再将真正的人物图像与背景图片进行与操作。这样在背景图片上就会显示出一个“干净”的人物了。在3D程序中使用的蒙板技术和2D类似,主要是用在纹理映射上,其原理是相同的。

这节课中的蒙版的方式是采用OpenGL中的混合(Blend)的方法实现的,主要用到了osg中osg::BlendFunc这个类来实现,这节课相当于第八课混合的一种应用,需要理解OpenGL中混合的作用原理。

  • 实现

首先我们先创建背景,也就是一张一直在滚动的纹理图片,设置代码如下:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. osg::Geometry *quadGeometry = new osg::Geometry;  
  2. //顶点位置坐标  
  3. osg::Vec3Array *quadVertexArray = new osg::Vec3Array;  
  4. quadVertexArray->push_back(osg::Vec3(-1.1f, -1.1f, 0.0f));  
  5. quadVertexArray->push_back(osg::Vec3(1.1f, -1.1f, 0.0f));  
  6. quadVertexArray->push_back(osg::Vec3(1.1f,1.1f, 0.0f));  
  7. quadVertexArray->push_back(osg::Vec3(-1.1f,1.1f, 0.0f));  
  8. quadGeometry->setVertexArray(quadVertexArray);  
  9.    //顶点纹理坐标  
  10. osg::Vec2Array *quadTextureArray = new osg::Vec2Array;  
  11. quadTextureArray->push_back(osg::Vec2(0,0));  
  12. quadTextureArray->push_back(osg::Vec2(3,0));  
  13. quadTextureArray->push_back(osg::Vec2(3,3));  
  14. quadTextureArray->push_back(osg::Vec2(0,3));  
  15. //纹理贴图  
  16. osg::Texture2D *quadTexture = new osg::Texture2D;  
  17. quadTexture->setImage(osgDB::readImageFile("Data/Logo.bmp"));  
  18. quadTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  19. quadTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  20. //设置WRAP方式是重复S和T方向  
  21. quadTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);  
  22. quadTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);  
  23. quadGeometry->setTexCoordArray(0, quadTextureArray);  
  24.   
  25. quadGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  26. quadGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, quadTexture);  
  27. quadGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  28. quadGeometry->setUseDisplayList(false);  
  29. //动态改变纹理坐标的回调  
  30. quadGeometry->setUpdateCallback(new TextureLogoCallback);  
代码和之前课程的很多代码都相似,主要一个不同的地方是需要设置纹理的WRAP方式,我们让纹理在几何体上重复贴图。

纹理的坐标需要在程序运行中动态的变化以实现向上的滚动,这个实现是在TextureLogoCallback这个更新回调中进行的

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. class TextureLogoCallback : public osg::Drawable::UpdateCallback  
  2. {  
  3. public:  
  4.     void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  5.     {  
  6.        ......  
  7.     }  
  8. };  
接着需要创建两个场景,当按下空格键的时候在二者之间切换。对于其中的任一场景,当按下M键的时候需要在打开和关闭Mask之间切换,为了做到这一效果,本课使用的是Switch节点的方式。Switch节点在第十八课中也有应用,具体代码如下:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. osg::Switch* createScene1()  
  2. {  
  3.    ......  
  4. }  
  5.   
  6. osg::Group* createScene2()  
  7. {  
  8.     osg::Switch *toggleMask34 = new osg::Switch;  
  9.     toggleMask34->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);  
  10.    ......  
  11. }  
在创建场景的过程中,为了实现Mask的效果,最重要的部分是设置混合参数的地方。查看NeHeOpenGL中的设置方式,对于Mask纹理图片需要设置:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //geometry3是贴有Mask的几何体  
  2.        geometry3->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture3);  
  3. osg::BlendFunc *blendFunc3 = new osg::BlendFunc(osg::BlendFunc::DST_COLOR, osg::BlendFunc::ZERO);  
  4. geometry3->getOrCreateStateSet()->setAttributeAndModes(blendFunc3);  
对于需要绘制的几何体本身也要设置混合方式:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //geometry4是需要绘制的几何体  
  2.        geometry4->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture4);  
  3. osg::BlendFunc *blendFuc4 = new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::ONE);  
  4. geometry4->getOrCreateStateSet()->setAttributeAndModes(blendFuc4);  
这样在OpenGL混合的作用之下,可以实现蒙版的效果。

最后在键盘交互中(自定义的EventHandler)实现Switch的切换:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. case(osgGA::GUIEventAdapter::KEYDOWN):  
  2.     {  
  3.         static int index = 1;  
  4.         if (index > 1)  
  5.         {  
  6.             index = 0;  
  7.         }  
  8.         if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)  
  9.         {  
  10.             g_scene->setSingleChildOn(index);  
  11.             ++index;  
  12.         }  
  13.   
  14.         if (ea.getKey() == osgGA::GUIEventAdapter::KEY_M)  
  15.         {  
  16.             if (index == 0)   //第二个场景  
  17.             {  
  18.                 if (g_scene2->getValue(0) == true) {  //Mask启用  
  19.                     g_scene2->setSingleChildOn(1);  
  20.                 }else{     //Mask未启用  
  21.                     g_scene2->setAllChildrenOn();      
  22.                 }  
  23.             }  
  24.             else               //第一个场景  
  25.             {  
  26.                 if (g_scene1->getValue(0) == true) { //Mask启用  
  27.                     g_scene1->setSingleChildOn(1);  
  28.                 }else{      //Mask未启用  
  29.                     g_scene1->setAllChildrenOn();  
  30.                 }  
  31.             }  
  32.         }  
  33.     }  
编译运行程序:


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

[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 <osg/Switch>  
  15. #include <osg/BlendFunc>  
  16. #include <osg/AnimationPath>  
  17.   
  18.   
  19. osg::Switch *g_scene, *g_scene1, *g_scene2;  
  20.   
  21.   
  22. class SceneEventHandler : public osgGA::GUIEventHandler  
  23. {  
  24. public:  
  25.     SceneEventHandler(){}  
  26.   
  27.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  28.     {  
  29.         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);  
  30.         if (!viewer)  
  31.             return false;  
  32.         if (!viewer->getSceneData())  
  33.             return false;  
  34.         if (ea.getHandled())   
  35.             return false;  
  36.   
  37.         switch(ea.getEventType())  
  38.         {  
  39.   
  40.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  41.             {  
  42.                 static int index = 1;  
  43.                 if (index > 1)  
  44.                 {  
  45.                     index = 0;  
  46.                 }  
  47.                   
  48.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)  
  49.                 {  
  50.                     g_scene->setSingleChildOn(index);  
  51.                     ++index;  
  52.                 }  
  53.   
  54.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_M)  
  55.                 {  
  56.                     if (index == 0)   //第二个场景  
  57.                     {  
  58.                         if (g_scene2->getValue(0) == true) {  //Mask启用  
  59.                             g_scene2->setSingleChildOn(1);  
  60.                         }else{     //Mask未启用  
  61.                             g_scene2->setAllChildrenOn();      
  62.                         }  
  63.                     }  
  64.                     else               //第一个场景  
  65.                     {  
  66.                         if (g_scene1->getValue(0) == true) { //Mask启用  
  67.                             g_scene1->setSingleChildOn(1);  
  68.                         }else{      //Mask未启用  
  69.                             g_scene1->setAllChildrenOn();  
  70.                         }  
  71.                     }  
  72.                 }  
  73.             }  
  74.         defaultbreak;  
  75.         }  
  76.         return false;  
  77.     }  
  78. };  
  79.   
  80.   
  81.   
  82.   
  83. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  84. {  
  85. public:  
  86.     ViewerWidget(osg::Node *scene = NULL)  
  87.     {  
  88.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  89.   
  90.         QVBoxLayout* layout = new QVBoxLayout;  
  91.         layout->addWidget(renderWidget);  
  92.         layout->setContentsMargins(0, 0, 0, 1);  
  93.         setLayout( layout );  
  94.   
  95.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  96.         _timer.start( 10 );  
  97.     }  
  98.   
  99.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  100.     {  
  101.         osg::Camera* camera = this->getCamera();  
  102.         camera->setGraphicsContext( gw );  
  103.   
  104.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  105.   
  106.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 0.0) );  
  107.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  108.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  109.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  110.   
  111.         addEventHandler(new SceneEventHandler);  
  112.   
  113.         this->setSceneData( scene );  
  114.   
  115.         return gw->getGLWidget();  
  116.     }  
  117.   
  118.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  119.     {  
  120.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  121.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  122.         traits->windowName = name;  
  123.         traits->windowDecoration = windowDecoration;  
  124.         traits->x = x;  
  125.         traits->y = y;  
  126.         traits->width = w;  
  127.         traits->height = h;  
  128.         traits->doubleBuffer = true;  
  129.         traits->alpha = ds->getMinimumNumAlphaBits();  
  130.         traits->stencil = ds->getMinimumNumStencilBits();  
  131.         traits->sampleBuffers = ds->getMultiSamples();  
  132.         traits->samples = ds->getNumMultiSamples();  
  133.   
  134.         return new osgQt::GraphicsWindowQt(traits.get());  
  135.     }  
  136.   
  137.     virtual void paintEvent( QPaintEvent* event )  
  138.     {   
  139.         frame();   
  140.     }  
  141.   
  142. protected:  
  143.   
  144.     QTimer _timer;  
  145. };  
  146.   
  147.   
  148. //纹理坐标更新  
  149. class TextureLogoCallback : public osg::Drawable::UpdateCallback  
  150. {  
  151. public:  
  152.   
  153.     void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  154.     {  
  155.         osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);  
  156.         if (!geometry)  
  157.         {  
  158.             return;  
  159.         }  
  160.         osg::Vec2Array *textureArray = dynamic_cast<osg::Vec2Array *>(geometry->getTexCoordArray(0));  
  161.         if (!textureArray)  
  162.         {  
  163.             return;  
  164.         }  
  165.   
  166.         static float roll = 0;  
  167.         roll += 0.002f;  
  168.   
  169.         if (roll > 1.0f)  
  170.             roll -= 1.0f;  
  171.   
  172.         textureArray->at(0).set(0,-roll + 0);  
  173.         textureArray->at(1).set(3,-roll + 0);  
  174.         textureArray->at(2).set(3,-roll + 3);  
  175.         textureArray->at(3).set(0,-roll + 3);  
  176.           
  177.         textureArray->dirty();  
  178.     }  
  179. };  
  180.   
  181.   
  182. class TextureImageCallback : public osg::Drawable::UpdateCallback  
  183. {  
  184. public:  
  185.   
  186.     void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  187.     {  
  188.         osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);  
  189.         if (!geometry)  
  190.         {  
  191.             return;  
  192.         }  
  193.         osg::Vec2Array *textureArray = dynamic_cast<osg::Vec2Array *>(geometry->getTexCoordArray(0));  
  194.         if (!textureArray)  
  195.         {  
  196.             return;  
  197.         }  
  198.   
  199.         static float rolling = 0.0;  
  200.         rolling += 0.002f;  
  201.   
  202.         if (rolling > 1.0f)  
  203.             rolling -= 1.0f;  
  204.         textureArray->at(0).set(-rolling + 0, 0);  
  205.         textureArray->at(1).set(rolling + 4, 0);  
  206.         textureArray->at(2).set(rolling + 4, 4);  
  207.         textureArray->at(3).set(rolling + 0, 4);  
  208.   
  209.         textureArray->dirty();  
  210.     }  
  211.   
  212. };  
  213.   
  214.   
  215. osg::Switch* createScene1()  
  216. {  
  217.     osg::Switch *toggleMask12 = new osg::Switch;  
  218.     toggleMask12->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);  
  219.   
  220.     //叶节点1  
  221.     osg::Geode *geode1 = new osg::Geode;  
  222.     osg::Geometry *geometry1 = new osg::Geometry;  
  223.     osg::Vec3Array *vertexArray1 = new osg::Vec3Array;  
  224.     vertexArray1->push_back(osg::Vec3(-1.1f, -1.1f, 0.0f));  
  225.     vertexArray1->push_back(osg::Vec3(1.1f, -1.1f, 0.0f));  
  226.     vertexArray1->push_back(osg::Vec3(1.1f,1.1f, 0.0f));  
  227.     vertexArray1->push_back(osg::Vec3(-1.1f,1.1f, 0.0f));  
  228.     geometry1->setVertexArray(vertexArray1);  
  229.     osg::Vec2Array *textureArray1 = new osg::Vec2Array;  
  230.     textureArray1->push_back(osg::Vec2(0,0));  
  231.     textureArray1->push_back(osg::Vec2(4,0));  
  232.     textureArray1->push_back(osg::Vec2(4,4));  
  233.     textureArray1->push_back(osg::Vec2(0,4));  
  234.     osg::Texture2D *texture1 = new osg::Texture2D;  
  235.     texture1->setImage(osgDB::readImageFile("Data/Mask1.bmp"));  
  236.     texture1->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  237.     texture1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  238.     texture1->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);  
  239.     texture1->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);  
  240.   
  241.     geometry1->setTexCoordArray(0, textureArray1);  
  242.     geometry1->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  243.     geometry1->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture1);  
  244.     geometry1->setUseDisplayList(false);  
  245.     osg::BlendFunc *blendFunc1 = new osg::BlendFunc(osg::BlendFunc::DST_COLOR, osg::BlendFunc::ZERO);  
  246.     geometry1->getOrCreateStateSet()->setAttributeAndModes(blendFunc1);  
  247.     geometry1->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  248.     geometry1->setUpdateCallback(new TextureImageCallback);  
  249.     geode1->addDrawable(geometry1);  
  250.   
  251.     //叶节点2  
  252.     osg::Geode *geode2 = new osg::Geode;  
  253.     osg::Geometry *geometry2 = new osg::Geometry;  
  254.     osg::Vec3Array *vertexArray2 = new osg::Vec3Array;  
  255.     vertexArray2->push_back(osg::Vec3(-1.1f, -1.1f, 0.0f));  
  256.     vertexArray2->push_back(osg::Vec3(1.1f, -1.1f, 0.0f));  
  257.     vertexArray2->push_back(osg::Vec3(1.1f,1.1f, 0.0f));  
  258.     vertexArray2->push_back(osg::Vec3(-1.1f,1.1f, 0.0f));  
  259.     geometry2->setVertexArray(vertexArray2);  
  260.   
  261.     osg::Vec2Array *textureArray2 = new osg::Vec2Array;  
  262.     textureArray2->push_back(osg::Vec2(0,0));  
  263.     textureArray2->push_back(osg::Vec2(4,0));  
  264.     textureArray2->push_back(osg::Vec2(4,4));  
  265.     textureArray2->push_back(osg::Vec2(0,4));  
  266.     osg::Texture2D *texture2 = new osg::Texture2D;  
  267.     texture2->setImage(osgDB::readImageFile("Data/Image1.bmp"));  
  268.     texture2->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  269.     texture2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  270.     texture2->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);  
  271.     texture2->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);  
  272.   
  273.     geometry2->setTexCoordArray(0, textureArray2);  
  274.     geometry2->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  275.     geometry2->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2);  
  276.     osg::BlendFunc *blendFuc2 = new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::ONE);  
  277.     geometry2->getOrCreateStateSet()->setAttributeAndModes(blendFuc2);  
  278.     geometry2->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  279.     geometry2->setUseDisplayList(false);  
  280.     geometry2->setUpdateCallback(new TextureImageCallback);  
  281.     geode2->addDrawable(geometry2);  
  282.   
  283.     toggleMask12->addChild(geode1);  
  284.     toggleMask12->addChild(geode2);  
  285.     toggleMask12->setAllChildrenOn();  
  286.   
  287.     g_scene1 = toggleMask12;  
  288.     return toggleMask12;  
  289. }  
  290.   
  291.   
  292. osg::Group* createScene2()  
  293. {  
  294.     osg::Switch *toggleMask34 = new osg::Switch;  
  295.     toggleMask34->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);  
  296.   
  297.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  298.     zoomMT->setMatrix(osg::Matrix::translate(0, 0, -0.9));  
  299.     osg::MatrixTransform *rotateMT = new osg::MatrixTransform;  
  300.     rotateMT->setMatrix(osg::Matrix::rotate(0, osg::Z_AXIS));  
  301.     rotateMT->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 1.5));  
  302.   
  303.     //叶节点3  
  304.     osg::Geode *geode3 = new osg::Geode;  
  305.     osg::Geometry *geometry3 = new osg::Geometry;  
  306.     osg::Vec3Array *vertexArray3 = new osg::Vec3Array;  
  307.     vertexArray3->push_back(osg::Vec3(-1.1f, -1.1f, 0.0f));  
  308.     vertexArray3->push_back(osg::Vec3(1.1f, -1.1f, 0.0f));  
  309.     vertexArray3->push_back(osg::Vec3(1.1f,1.1f, 0.0f));  
  310.     vertexArray3->push_back(osg::Vec3(-1.1f,1.1f, 0.0f));  
  311.     geometry3->setVertexArray(vertexArray3);  
  312.     osg::Vec2Array *textureArray3 = new osg::Vec2Array;  
  313.     textureArray3->push_back(osg::Vec2(0,0));  
  314.     textureArray3->push_back(osg::Vec2(1,0));  
  315.     textureArray3->push_back(osg::Vec2(1,1));  
  316.     textureArray3->push_back(osg::Vec2(0,1));  
  317.     osg::Texture2D *texture3 = new osg::Texture2D;  
  318.     texture3->setImage(osgDB::readImageFile("Data/Mask2.bmp"));  
  319.     texture3->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  320.     texture3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  321.     geometry3->setTexCoordArray(0, textureArray3);  
  322.     geometry3->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  323.     geometry3->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture3);  
  324.     osg::BlendFunc *blendFunc3 = new osg::BlendFunc(osg::BlendFunc::DST_COLOR, osg::BlendFunc::ZERO);  
  325.     geometry3->getOrCreateStateSet()->setAttributeAndModes(blendFunc3);  
  326.     geometry3->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  327.     geode3->addDrawable(geometry3);  
  328.   
  329.     //叶节点4  
  330.     osg::Geode *geode4 = new osg::Geode;  
  331.     osg::Geometry *geometry4 = new osg::Geometry;  
  332.     osg::Vec3Array *vertexArray4 = new osg::Vec3Array;  
  333.     vertexArray4->push_back(osg::Vec3(-1.1f, -1.1f, 0.0f));  
  334.     vertexArray4->push_back(osg::Vec3(1.1f, -1.1f, 0.0f));  
  335.     vertexArray4->push_back(osg::Vec3(1.1f,1.1f, 0.0f));  
  336.     vertexArray4->push_back(osg::Vec3(-1.1f,1.1f, 0.0f));  
  337.     geometry4->setVertexArray(vertexArray4);  
  338.   
  339.     osg::Vec2Array *textureArray4 = new osg::Vec2Array;  
  340.     textureArray4->push_back(osg::Vec2(0,0));  
  341.     textureArray4->push_back(osg::Vec2(1,0));  
  342.     textureArray4->push_back(osg::Vec2(1,1));  
  343.     textureArray4->push_back(osg::Vec2(0,1));  
  344.     osg::Texture2D *texture4 = new osg::Texture2D;  
  345.     texture4->setImage(osgDB::readImageFile("Data/Image2.bmp"));  
  346.     texture4->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  347.     texture4->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  348.   
  349.     geometry4->setTexCoordArray(0, textureArray4);  
  350.     geometry4->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  351.     geometry4->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture4);  
  352.     osg::BlendFunc *blendFuc4 = new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::ONE);  
  353.     geometry4->getOrCreateStateSet()->setAttributeAndModes(blendFuc4);  
  354.     geometry4->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  355.     geode4->addDrawable(geometry4);  
  356.   
  357.     zoomMT->addChild(rotateMT);  
  358.     rotateMT->addChild(toggleMask34);  
  359.     toggleMask34->addChild(geode3);  
  360.     toggleMask34->addChild(geode4);  
  361.     toggleMask34->setAllChildrenOn();  
  362.   
  363.     g_scene2 = toggleMask34;  
  364.     return zoomMT;  
  365. }  
  366.   
  367.   
  368.   
  369.   
  370. osg::Node*  buildScene()  
  371. {  
  372.     osg::Group *root = new osg::Group;  
  373.   
  374.     osg::MatrixTransform *quadMT = new osg::MatrixTransform;  
  375.     quadMT->setMatrix(osg::Matrix::translate(0.0, 0.0, -1.0));  
  376.       
  377.     osg::Geometry *quadGeometry = new osg::Geometry;  
  378.     //顶点位置坐标  
  379.     osg::Vec3Array *quadVertexArray = new osg::Vec3Array;  
  380.     quadVertexArray->push_back(osg::Vec3(-1.1f, -1.1f, 0.0f));  
  381.     quadVertexArray->push_back(osg::Vec3(1.1f, -1.1f, 0.0f));  
  382.     quadVertexArray->push_back(osg::Vec3(1.1f,1.1f, 0.0f));  
  383.     quadVertexArray->push_back(osg::Vec3(-1.1f,1.1f, 0.0f));  
  384.     quadGeometry->setVertexArray(quadVertexArray);  
  385.     //顶点纹理坐标  
  386.     osg::Vec2Array *quadTextureArray = new osg::Vec2Array;  
  387.     quadTextureArray->push_back(osg::Vec2(0,0));  
  388.     quadTextureArray->push_back(osg::Vec2(3,0));  
  389.     quadTextureArray->push_back(osg::Vec2(3,3));  
  390.     quadTextureArray->push_back(osg::Vec2(0,3));  
  391.     //纹理贴图  
  392.     osg::Texture2D *quadTexture = new osg::Texture2D;  
  393.     quadTexture->setImage(osgDB::readImageFile("Data/Logo.bmp"));  
  394.     quadTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  395.     quadTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  396.     //设置WRAP方式是重复S和T方向  
  397.     quadTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);  
  398.     quadTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);  
  399.     quadGeometry->setTexCoordArray(0, quadTextureArray);  
  400.   
  401.     quadGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  402.     quadGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, quadTexture);  
  403.     quadGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  404.     quadGeometry->setUseDisplayList(false);  
  405.     //动态改变纹理坐标的回调  
  406.     quadGeometry->setUpdateCallback(new TextureLogoCallback);  
  407.       
  408.     osg::Geode *quadGeode = new osg::Geode;  
  409.     quadGeode->addDrawable(quadGeometry);  
  410.     quadMT->addChild(quadGeode);  
  411.   
  412.     osg::Switch *toggleScene = new osg::Switch;  
  413.     toggleScene->addChild(createScene1());  
  414.     toggleScene->addChild(createScene2());  
  415.     toggleScene->setSingleChildOn(0);  
  416.     g_scene = toggleScene;  
  417.   
  418.     root->addChild(quadMT);  
  419.     root->addChild(toggleScene);  
  420.   
  421.     return root;  
  422. }  
  423.   
  424.   
  425.   
  426. int main( int argc, char** argv )  
  427. {  
  428.     QApplication app(argc, argv);  
  429.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  430.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  431.     viewWidget->show();  
  432.     return app.exec();  
  433. }  
0 0
原创粉丝点击