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

  • 简介

这节课NeHe课程教我们怎样使用OpenGL中的多视口来显示场景,多视口的方式可以用来显示场景中更多的信息。在3DMax中我们经常会看到模型的正视图、侧视图等可以在OpenGL中使用不同的视口达到同样的效果。在OSG中每一个osg::Camera可以用来渲染不同的场景,我们可以使用多个相机并通过给这些相机设置不同的视口来达到这样的效果。在OSG中提供了这样的类来管理多个View视景器,不同的视景器拥有不同的Camera和场景根节点。

  • 实现

首先需要修改的是我们框架中的osgViewer::Viewer类的继承,我们将它修改成CompositeView,用它来管理多个视景器:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class ViewerWidget : public QWidget, public osgViewer::CompositeViewer  

我们在创建窗口的过程中创建多个View:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. //添加多个相机  
  2.     // view one  
  3.     {  
  4.         osgViewer::View* view = new osgViewer::View;  
  5.         view->setName("View one");  
  6.         this->addView(view);  
  7.         view->setSceneData(scene1);  
  8.           
  9.   
  10.         view->getCamera()->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  11.         view->getCamera()->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  12.         view->getCamera()->setName("Cam one");  
  13.         view->getCamera()->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height/2));  
  14.         view->getCamera()->setGraphicsContext(gw);  
  15.         view->addEventHandler(new ManipulatorSceneHandler);  
  16.     }  

按课程中的方式添加了4个View用来显示不同的场景,这些View的参数可以不同,我们把其中一个按NeHe课程中的方式设置为正投影的方式(Ortho)

接下来我们创建每一个View加载的场景根节点:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Node*  buildScene1()  
  2. {  
  3.     osg::Group *scene1= new osg::Group;  
  4.     osg::MatrixTransform *zoomMT1 = new osg::MatrixTransform;  
  5.     zoomMT1->setMatrix(osg::Matrix::translate(0,0,-7));  
  6.     osg::MatrixTransform *rotX1 = new osg::MatrixTransform;  
  7.     rotX1->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::X_AXIS, 0.5));  
  8.     osg::MatrixTransform *rotY1 = new osg::MatrixTransform;  
  9.     rotY1->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Y_AXIS, 0.3));  
  10.     osg::MatrixTransform *rotZ1 = new osg::MatrixTransform;  
  11.     rotZ1->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 0.2));  
  12.   
  13.     scene1->addChild(zoomMT1);  
  14.     zoomMT1->addChild(rotX1);  
  15.     rotX1->addChild(rotY1);  
  16.     rotY1->addChild(rotZ1);  
  17.     rotZ1->addChild(createCylinder());  
  18.   
  19.     return scene1;  
  20. }  
最后在场景的帧循环事件中我们需要更新几何体的纹理,方式参考NeHe中的实现,在几何体表面绘制迷宫图案。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. case (osgGA::GUIEventAdapter::FRAME):  
  2.             {  
  3.                 done=true;                                                          // Set done To True  
  4.                 for (int x=0; x<width; x+=2)                                     // Loop Through All The Rooms  
  5.                 {  
  6.                     for (int y=0; y<height; y+=2)                                    // On X And Y Axis  
  7.                     {  
  8.                         if (tex_data[((x+(width*y))*3)]==0)                         // If Current Texture Pixel (Room) Is Blank  
  9.                             done=false;                                             // We Have To Set done To False (Not Finished Yet)  
  10.                     }  
  11.                 }  
  12.   
  13.                 if (done)                                                           // If done Is True Then There Were No Unvisited Rooms  
  14.                 {         
  15.                     Sleep(5000);  
  16.                     Reset();  
  17.                 }  
  18.                            .......  
  19. }  

最后把不同的场景添加到各自的视景器View之中,运行程序:


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

[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 <osgViewer/CompositeViewer>  
  9. #include <osgDB/ReadFile>  
  10. #include <osgQt/GraphicsWindowQt>  
  11.   
  12. #include <osg/MatrixTransform>  
  13.   
  14. #include <osg/Texture2D>  
  15. #include <osg/ShapeDrawable>  
  16. #include <osg/AnimationPath>  
  17.   
  18. //  
  19. // User Defined Variables  
  20. int mx,my;                        
  21.   
  22. const   int width   = 128;    
  23. const   int height  = 128;    
  24.   
  25. BOOL    done;                     
  26. BOOL    sp;                       
  27.   
  28. BYTE    r[4], g[4], b[4];     
  29. BYTE    *tex_data;            
  30.   
  31. osg::Texture2D  *g_Texture2D;  
  32.   
  33. GLfloat xrot, yrot, zrot;     
  34.   
  35.   
  36. void UpdateTex(int dmx, int dmy)                                      
  37. {  
  38.     tex_data[0+((dmx+(width*dmy))*3)]=255;                    
  39.     tex_data[1+((dmx+(width*dmy))*3)]=255;                    
  40.     tex_data[2+((dmx+(width*dmy))*3)]=255;                    
  41. }  
  42.   
  43. void Reset (void)                                                         
  44. {  
  45.     ZeroMemory(tex_data, width * height *3);                      
  46.   
  47.     srand(GetTickCount());                                                
  48.   
  49.     for (int loop=0; loop<4; loop++)                                   
  50.     {  
  51.         r[loop]=rand()%128+128;                                       
  52.         g[loop]=rand()%128+128;                                       
  53.         b[loop]=rand()%128+128;                                       
  54.     }  
  55.   
  56.     mx=int(rand()%(width/2))*2;                                       
  57.     my=int(rand()%(height/2))*2;                                          
  58. }  
  59.   
  60.   
  61. bool Initialize()  
  62. {  
  63.     tex_data=new BYTE[width*height*3];  
  64.     Reset();  
  65.   
  66.     osg::Image *image = new osg::Image;  
  67.     image->setImage(width, height, 1, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tex_data, osg::Image::NO_DELETE);  
  68.     g_Texture2D = new osg::Texture2D;  
  69.     g_Texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  70.     g_Texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  71.     g_Texture2D->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP);  
  72.     g_Texture2D->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP);  
  73.   
  74.     return true;  
  75. }  
  76.   
  77.   
  78.   
  79.   
  80.   
  81. class DrawableTextureUpdateCallback : public osg::Drawable::UpdateCallback  
  82. {  
  83. public:  
  84.   
  85.     virtual void update(osg::NodeVisitor*, osg::Drawable* d)  
  86.     {  
  87.         if (!d)  
  88.             return;  
  89.   
  90.         osg::Image *image = new osg::Image;  
  91.         image->setImage(width, height, 1, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tex_data, osg::Image::NO_DELETE);  
  92.   
  93.         g_Texture2D->setImage(image);  
  94.   
  95.         d->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Texture2D);  
  96.   
  97.     }  
  98.   
  99. };  
  100.   
  101. //  
  102.   
  103. osg::Geode*  createFirstQuad()  
  104. {  
  105.     osg::Geode *geode = new osg::Geode;  
  106.     osg::Geometry *geometry = new osg::Geometry;  
  107.     osg::Vec2Array *texArray = new osg::Vec2Array;  
  108.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  109.     osg::Vec3Array *colorArray = new osg::Vec3Array;  
  110.   
  111.     colorArray->push_back(osg::Vec3(1, 1, 1.0));  
  112.   
  113.     vertexArray->push_back(osg::Vec3(320,  0, 0.0f));  
  114.     vertexArray->push_back(osg::Vec3(0,  0, 0.0f));  
  115.     vertexArray->push_back(osg::Vec3(0,  240, 0.0f));  
  116.     vertexArray->push_back(osg::Vec3(320,  240, 0.0f));  
  117.   
  118.     texArray->push_back(osg::Vec2(1.0f, 0.0f));  
  119.     texArray->push_back(osg::Vec2(0.0f, 0.0f));  
  120.     texArray->push_back(osg::Vec2(0.0f, 1.0f));  
  121.     texArray->push_back(osg::Vec2(1.0f, 1.0f));  
  122.   
  123.     geometry->setVertexArray(vertexArray);  
  124.     geometry->setColorArray(colorArray, osg::Array::BIND_OVERALL);  
  125.     geometry->setTexCoordArray(0, texArray, osg::Array::BIND_PER_VERTEX);  
  126.     geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  127.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  128.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Texture2D);  
  129.     geometry->setUpdateCallback(new DrawableTextureUpdateCallback);  
  130.     geode->addDrawable(geometry);  
  131.       
  132.     return geode;  
  133. }  
  134.   
  135.   
  136.   
  137. osg::Geode* createThirdQuad()  
  138. {  
  139.     osg::Geode *geode = new osg::Geode;  
  140.     osg::Geometry *geometry = new osg::Geometry;  
  141.     osg::Vec2Array *texArray = new osg::Vec2Array;  
  142.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  143.     osg::Vec3Array *colorArray = new osg::Vec3Array;  
  144.   
  145.     colorArray->push_back(osg::Vec3(1, 1, 1.0));  
  146.   
  147.     vertexArray->push_back(osg::Vec3(1.0f,  1.0f, 0.0f));  
  148.     vertexArray->push_back(osg::Vec3(-1.0f,  1.0f, 0.0f));  
  149.     vertexArray->push_back(osg::Vec3(-1.0f,  -1.0f, 0.0f));  
  150.     vertexArray->push_back(osg::Vec3(1.0f,  -1.0f, 0.0f));  
  151.   
  152.     texArray->push_back(osg::Vec2(1.0f, 1.0f));  
  153.     texArray->push_back(osg::Vec2(0.0f, 1.0f));  
  154.     texArray->push_back(osg::Vec2(0.0f, 0.0f));  
  155.     texArray->push_back(osg::Vec2(1.0f, 0.0f));  
  156.   
  157.     geometry->setVertexArray(vertexArray);  
  158.     geometry->setColorArray(colorArray, osg::Array::BIND_OVERALL);  
  159.     geometry->setTexCoordArray(0, texArray, osg::Array::BIND_PER_VERTEX);  
  160.     geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  161.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  162.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Texture2D);  
  163.     geometry->setUpdateCallback(new DrawableTextureUpdateCallback);  
  164.     geode->addDrawable(geometry);  
  165.     return geode;  
  166. }  
  167.   
  168.   
  169. osg::Geode* createSphere()  
  170. {  
  171.     osg::Geode *sphere = new osg::Geode;  
  172.     osg::ShapeDrawable *sphereDrawable = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0,0,0), 4.0));  
  173.     sphere->addDrawable(sphereDrawable);  
  174.     sphereDrawable->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Texture2D);  
  175.     sphereDrawable->setUpdateCallback(new DrawableTextureUpdateCallback);  
  176.     return sphere;  
  177. }     
  178.   
  179.   
  180. osg::Geode* createCylinder()  
  181. {  
  182.     osg::Geode *cylinder = new osg::Geode;  
  183.     osg::ShapeDrawable *cylinderDrawable = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0,0,0), 1.5, 4.0));  
  184.     cylinder->addDrawable(cylinderDrawable);  
  185.     cylinderDrawable->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Texture2D);  
  186.     cylinderDrawable->setUpdateCallback(new DrawableTextureUpdateCallback);  
  187.     return cylinder;  
  188. }  
  189.   
  190.   
  191.   
  192. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  193. {  
  194. public:  
  195.     ManipulatorSceneHandler()  
  196.     {  
  197.     }  
  198.   
  199. public:  
  200.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  201.     {  
  202.         osgViewer::View *viewer = dynamic_cast<osgViewer::View*>(&aa);  
  203.         if (!viewer)  
  204.             return false;  
  205.         if (!viewer->getSceneData())  
  206.             return false;  
  207.         if (ea.getHandled())   
  208.             return false;  
  209.   
  210.         osg::Group *root = viewer->getSceneData()->asGroup();  
  211.   
  212.         switch(ea.getEventType())  
  213.         {  
  214.         case (osgGA::GUIEventAdapter::FRAME):  
  215.             {  
  216.                 done=TRUE;                                                          // Set done To True  
  217.                 for (int x=0; x<width; x+=2)                                     // Loop Through All The Rooms  
  218.                 {  
  219.                     for (int y=0; y<height; y+=2)                                    // On X And Y Axis  
  220.                     {  
  221.                         if (tex_data[((x+(width*y))*3)]==0)                         // If Current Texture Pixel (Room) Is Blank  
  222.                             done=FALSE;                                             // We Have To Set done To False (Not Finished Yet)  
  223.                     }  
  224.                 }  
  225.   
  226.                 if (done)                                                           // If done Is True Then There Were No Unvisited Rooms  
  227.                 {         
  228.                     Sleep(5000);  
  229.                     Reset();  
  230.                 }  
  231.   
  232.                 // Check To Make Sure We Are Not Trapped (Nowhere Else To Move)  
  233.                 if (((mx>(width-4) || tex_data[(((mx+2)+(width*my))*3)]==255)) && ((mx<2 || tex_data[(((mx-2)+(width*my))*3)]==255)) &&  
  234.                     ((my>(height-4) || tex_data[((mx+(width*(my+2)))*3)]==255)) && ((my<2 || tex_data[((mx+(width*(my-2)))*3)]==255)))  
  235.                 {  
  236.                     do                                                              // If We Are Trapped  
  237.                     {  
  238.                         mx=int(rand()%(width/2))*2;                                 // Pick A New Random X Position  
  239.                         my=int(rand()%(height/2))*2;                                // Pick A New Random Y Position  
  240.                     }  
  241.                     while (tex_data[((mx+(width*my))*3)]==0);                       // Keep Picking A Random Position Until We Find  
  242.                 }                                                                   // One That Has Already Been Tagged (Safe Starting Point)  
  243.   
  244.                 int dir=int(rand()%4);                                                  // Pick A Random Direction  
  245.   
  246.                 if ((dir==0) && (mx<=(width-4)))                                 // If The Direction Is 0 (Right) And We Are Not At The Far Right  
  247.                 {  
  248.                     if (tex_data[(((mx+2)+(width*my))*3)]==0)                       // And If The Room To The Right Has Not Already Been Visited  
  249.                     {  
  250.                         UpdateTex(mx+1,my);                                         // Update The Texture To Show Path Cut Out Between Rooms  
  251.                         mx+=2;                                                      // Move To The Right (Room To The Right)  
  252.                     }  
  253.                 }  
  254.   
  255.                 if ((dir==1) && (my<=(height-4)))                                    // If The Direction Is 1 (Down) And We Are Not At The Bottom  
  256.                 {  
  257.                     if (tex_data[((mx+(width*(my+2)))*3)]==0)                       // And If The Room Below Has Not Already Been Visited  
  258.                     {  
  259.                         UpdateTex(mx,my+1);                                         // Update The Texture To Show Path Cut Out Between Rooms  
  260.                         my+=2;                                                      // Move Down (Room Below)  
  261.                     }  
  262.                 }  
  263.   
  264.                 if ((dir==2) && (mx>=2))                                         // If The Direction Is 2 (Left) And We Are Not At The Far Left  
  265.                 {  
  266.                     if (tex_data[(((mx-2)+(width*my))*3)]==0)                       // And If The Room To The Left Has Not Already Been Visited  
  267.                     {  
  268.                         UpdateTex(mx-1,my);                                         // Update The Texture To Show Path Cut Out Between Rooms  
  269.                         mx-=2;                                                      // Move To The Left (Room To The Left)  
  270.                     }  
  271.                 }  
  272.   
  273.                 if ((dir==3) && (my>=2))                                         // If The Direction Is 3 (Up) And We Are Not At The Top  
  274.                 {  
  275.                     if (tex_data[((mx+(width*(my-2)))*3)]==0)                       // And If The Room Above Has Not Already Been Visited  
  276.                     {  
  277.                         UpdateTex(mx,my-1);                                         // Update The Texture To Show Path Cut Out Between Rooms  
  278.                         my-=2;                                                      // Move Up (Room Above)  
  279.                     }  
  280.                 }  
  281.   
  282.                 UpdateTex(mx,my);                                                   // Update Current Room  
  283.   
  284.             }  
  285.             break;  
  286.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  287.             {  
  288.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)  
  289.                 {  
  290.                     Reset();  
  291.                 }  
  292.             }  
  293.             break;  
  294.   
  295.         defaultbreak;  
  296.         }  
  297.         return false;  
  298.     }  
  299. };  
  300.   
  301.   
  302.   
  303.   
  304.   
  305. class ViewerWidget : public QWidget, public osgViewer::CompositeViewer  
  306. {  
  307. public:  
  308.     ViewerWidget(osg::Node *scene1 = NULL, osg::Node *scene2 = NULL, osg::Node *scene3 = NULL, osg::Node *scene4 = NULL)  
  309.     {  
  310.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,640,480), scene1, scene2, scene3, scene4);  
  311.   
  312.         QVBoxLayout* layout = new QVBoxLayout;  
  313.         layout->addWidget(renderWidget);  
  314.         layout->setContentsMargins(0, 0, 0, 1);  
  315.         setLayout( layout );  
  316.   
  317.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  318.         _timer.start( 10 );  
  319.     }  
  320.   
  321.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw,   
  322.                                                   osg::Node* scene1=0,  
  323.                                                   osg::Node* scene2=0,  
  324.                                                   osg::Node* scene3=0,  
  325.                                                   osg::Node* scene4=0)  
  326.     {  
  327.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  328.   
  329.     //  
  330.     //添加多个相机  
  331.         // view one  
  332.         {  
  333.             osgViewer::View* view = new osgViewer::View;  
  334.             view->setName("View one");  
  335.             this->addView(view);  
  336.             view->setSceneData(scene1);  
  337.               
  338.   
  339.             view->getCamera()->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  340.             view->getCamera()->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  341.             view->getCamera()->setName("Cam one");  
  342.             view->getCamera()->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height/2));  
  343.             view->getCamera()->setGraphicsContext(gw);  
  344.             view->addEventHandler(new ManipulatorSceneHandler);  
  345.         }  
  346.   
  347.         // view two  
  348.         {  
  349.             osgViewer::View* view = new osgViewer::View;  
  350.             view->setName("View two");  
  351.             this->addView(view);  
  352.             view->setSceneData(scene2);  
  353.   
  354.             view->getCamera()->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  355.             view->getCamera()->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  356.             view->getCamera()->setName("Cam two");  
  357.             view->getCamera()->setViewport(new osg::Viewport(traits->width/2,0, traits->width/2, traits->height/2));  
  358.             view->getCamera()->setGraphicsContext(gw);  
  359.         }  
  360.   
  361.         // view three  
  362.         {  
  363.             osgViewer::View* view = new osgViewer::View;  
  364.             view->setName("View three");  
  365.             this->addView(view);  
  366.             view->setSceneData(scene3);  
  367.   
  368.             view->getCamera()->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  369.             //view->getCamera()->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  370.             view->getCamera()->setProjectionMatrixAsOrtho(0, traits->width/2.0, 0, traits->height/2.0, -1,1);  
  371.             view->getCamera()->setName("Cam three");  
  372.             view->getCamera()->setViewport(new osg::Viewport(0, traits->height/2, traits->width / 2, traits->height/2));  
  373.             view->getCamera()->setGraphicsContext(gw);  
  374.   
  375.         }  
  376.           
  377.         // view four  
  378.         {  
  379.             osgViewer::View* view = new osgViewer::View;  
  380.             view->setName("View four");  
  381.             this->addView(view);  
  382.             view->setSceneData(scene4);  
  383.   
  384.             view->getCamera()->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  385.             view->getCamera()->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  386.             view->getCamera()->setName("Cam four");  
  387.             view->getCamera()->setViewport(new osg::Viewport(traits->width/2, traits->height/2, traits->width / 2, traits->height/2));  
  388.             view->getCamera()->setGraphicsContext(gw);  
  389.   
  390.         }  
  391.   
  392.         return gw->getGLWidget();  
  393.     }  
  394.   
  395.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  396.     {  
  397.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  398.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  399.         traits->windowName = name;  
  400.         traits->windowDecoration = windowDecoration;  
  401.         traits->x = x;  
  402.         traits->y = y;  
  403.         traits->width = w;  
  404.         traits->height = h;  
  405.         traits->doubleBuffer = true;  
  406.         traits->alpha = ds->getMinimumNumAlphaBits();  
  407.         traits->stencil = ds->getMinimumNumStencilBits();  
  408.         traits->sampleBuffers = ds->getMultiSamples();  
  409.         traits->samples = ds->getNumMultiSamples();  
  410.   
  411.         return new osgQt::GraphicsWindowQt(traits.get());  
  412.     }  
  413.   
  414.     virtual void paintEvent( QPaintEvent* event )  
  415.     {   
  416.         frame();   
  417.     }  
  418.   
  419. protected:  
  420.   
  421.     QTimer _timer;  
  422. };  
  423.   
  424.   
  425.   
  426.   
  427. osg::Node*  buildScene1()  
  428. {  
  429.     osg::Group *scene1= new osg::Group;  
  430.     osg::MatrixTransform *zoomMT1 = new osg::MatrixTransform;  
  431.     zoomMT1->setMatrix(osg::Matrix::translate(0,0,-7));  
  432.     osg::MatrixTransform *rotX1 = new osg::MatrixTransform;  
  433.     rotX1->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::X_AXIS, 0.5));  
  434.     osg::MatrixTransform *rotY1 = new osg::MatrixTransform;  
  435.     rotY1->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Y_AXIS, 0.3));  
  436.     osg::MatrixTransform *rotZ1 = new osg::MatrixTransform;  
  437.     rotZ1->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 0.2));  
  438.   
  439.     scene1->addChild(zoomMT1);  
  440.     zoomMT1->addChild(rotX1);  
  441.     rotX1->addChild(rotY1);  
  442.     rotY1->addChild(rotZ1);  
  443.     rotZ1->addChild(createCylinder());  
  444.   
  445.     return scene1;  
  446. }  
  447.   
  448.   
  449. osg::Node*  buildScene2()  
  450. {  
  451.     osg::Group *scene2 = new osg::Group;  
  452.   
  453.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  454.     zoomMT->setMatrix(osg::Matrix::translate(0,0,-2));  
  455.     osg::MatrixTransform *rotX = new osg::MatrixTransform;  
  456.     rotX->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(-45.0), osg::X_AXIS));  
  457.     osg::MatrixTransform *rotZ = new osg::MatrixTransform;  
  458.     rotZ->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 0.5));  
  459.   
  460.     scene2->addChild(zoomMT);  
  461.     zoomMT->addChild(rotX);  
  462.     rotX->addChild(rotZ);  
  463.     rotZ->addChild(createThirdQuad());  
  464.   
  465.     return scene2;  
  466. }  
  467.   
  468.   
  469. osg::Node*  buildScene3()  
  470. {  
  471.     return createFirstQuad();  
  472. }  
  473.   
  474.   
  475. osg::Node*  buildScene4()  
  476. {  
  477.     osg::Group *scene= new osg::Group;  
  478.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  479.     zoomMT->setMatrix(osg::Matrix::translate(0,0,-14));  
  480.     osg::MatrixTransform *rotX = new osg::MatrixTransform;  
  481.     rotX->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::X_AXIS, 0.5));  
  482.     osg::MatrixTransform *rotY = new osg::MatrixTransform;  
  483.     rotY->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Y_AXIS, 0.2));  
  484.     osg::MatrixTransform *rotZ = new osg::MatrixTransform;  
  485.     rotZ->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 0.4));  
  486.   
  487.     scene->addChild(zoomMT);  
  488.     zoomMT->addChild(rotX);  
  489.     rotX->addChild(rotY);  
  490.     rotY->addChild(rotZ);  
  491.     rotZ->addChild(createSphere());  
  492.   
  493.     return scene;  
  494. }  
  495.   
  496.   
  497.   
  498.   
  499. int main( int argc, char** argv )  
  500. {  
  501.     QApplication app(argc, argv);  
  502.      Initialize();  
  503.     ViewerWidget* viewWidget = new ViewerWidget(buildScene1(), buildScene2(),buildScene3(),buildScene4());  
  504.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  505.     viewWidget->show();  
  506.     return app.exec();  
  507. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值