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

  • 简介

NeHe教程在这节课中向我们介绍了如何从文件加载3D模型,并且平滑的从一个模型变换为另一个模型。这个过程又称为逐点动画,点之间的变化过程算法十分简单,采用的是线性的算法。

  • 实现

首先我们仿照NeHe课程中定义了表示点的结构体以及读取文件的结构体OBJECT并读取文件

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void initMorphObject()  
  2. {  
  3.     objload("Data/sphere.txt",&morph1);  
  4.     objload("Data/torus.txt",&morph2);  
  5.     objload("Data/tube.txt",&morph3);  
  6.   
  7.     objallocate(&morph4,486);     
  8.     morph4.verts = 486;  
  9.     for(int i=0;i<486;i++)  
  10.     {  
  11.         morph4.points[i].x=((float)(rand()%14000)/1000)-7;  
  12.         morph4.points[i].y=((float)(rand()%14000)/1000)-7;  
  13.         morph4.points[i].z=((float)(rand()%14000)/1000)-7;    
  14.     }  
  15.       
  16.     morphGeometry1 = new osg::Geometry;  
  17.     osg::Vec3Array *vertexArray1 = new osg::Vec3Array;  
  18.     for (unsigned i = 0; i < morph1.verts; ++i)  
  19.     {  
  20.         vertexArray1->push_back(osg::Vec3(morph1.points[i].x, morph1.points[i].y, morph1.points[i].z));  
  21.     }  
  22.     morphGeometry1->setVertexArray(vertexArray1);  
  23.     morphGeometry1->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 486));  
  24.     morphGeometry1->setUseDisplayList(false);  
  25.     srcMorphGeometry = dynamic_cast<osg::Geometry*>(morphGeometry1->clone(osg::CopyOp::DEEP_COPY_ALL));  
  26.     destMorphGeometry = morphGeometry1;  
  27.        ...  
  28. }  
读取文件之后构建4个几何体对象,接着在几何体更新回调中处理逐个点的变化

上述的处理过程在几何体的更新回调MorphUpdateCallback之中

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  2. {  
  3.     osg::Geometry *geom = dynamic_cast<osg::Geometry*>(drawable);  
  4.     if (!geom)  
  5.         return;  
  6.       
  7.     osg::Vec3Array *vertices = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());  
  8.     osg::Vec3Array *destVertices = dynamic_cast<osg::Vec3Array*>(_destGeometry->getVertexArray());   
  9.     if (vertices && destVertices)  
  10.     {  
  11.         for (unsigned i = 0; i < vertices->size(); ++i)  
  12.         {  
  13.             osg::Vec3 delta = (destVertices->at(i) - vertices->at(i)) / _steps;  
  14.             vertices->at(i) += delta;  
  15.         }  
  16.         vertices->dirty();  
  17.     }     
  18. }  
在与键盘的交互中设置变换的几何体目标对象:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1)  
  2. {  
  3.     MorphUpdateCallback *muc = dynamic_cast<MorphUpdateCallback*>(srcMorphGeometry->getUpdateCallback());  
  4.     if (!muc)  
  5.         return false;  
  6.     muc->setDestGeometry(morphGeometry1);  
  7. }  
  8.   
  9. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2)  
  10. {  
  11.     MorphUpdateCallback *muc = dynamic_cast<MorphUpdateCallback*>(srcMorphGeometry->getUpdateCallback());  
  12.     if (!muc)  
  13.         return false;  
  14.     muc->setDestGeometry(morphGeometry2);  
  15. }  

通过设置几何体变换的开始形状(srcGeometry)和最终变换到的目标几何体(destGeometry),在回调中不断调整顶点位置完成动画效果。

编译运行程序:


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

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /************************************************************************\ 
  2.  * osgNeHe - Copyright (C) 2013-2014 Frank He 
  3.  * 
  4.  * This library is open source and may be redistributed and/or modified under 
  5.  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
  6.  * (at your option) any later version.  The full license is in LICENSE file 
  7.  * included with this distribution, and on the openscenegraph.org website. 
  8.  * 
  9.  * This library is distributed in the hope that it will be useful, 
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
  12. * 
  13. *   A HUGE thanks to NeHe for the OpenGL tutorials< http://nehe.gamedev.net > 
  14. * 
  15. *  If you've found this code useful, Please let me know. 
  16. *  My E-mail: < hzhxfrank@gmail.com > 
  17. *  My Blog: < http://blog.youkuaiyun.com/csxiaoshui > 
  18. * 
  19. \************************************************************************/  
  20.   
  21. #include "../osgNeHe.h"  
  22.   
  23. #include <QtCore/QTimer>  
  24. #include <QtGui/QApplication>  
  25. #include <QtGui/QVBoxLayout>  
  26.   
  27. #include <osgViewer/Viewer>  
  28. #include <osgDB/ReadFile>  
  29. #include <osgQt/GraphicsWindowQt>  
  30.   
  31. #include <osg/MatrixTransform>  
  32. #include <osg/Geometry>  
  33.                       
  34. GLfloat     cx,cy,cz = -15.0f;  
  35. int             step=0;  
  36. int                steps = 200;  
  37. bool                morph = false;  
  38.   
  39. osg::MatrixTransform *g_transMT = NULL;  
  40. osg::MatrixTransform    *g_rotateX = NULL;  
  41. osg::MatrixTransform    *g_rotateY = NULL;  
  42. osg::MatrixTransform    *g_rotateZ = NULL;  
  43.   
  44.   
  45. struct  VERTEX                                    
  46. {  
  47.     float   x, y, z;                                  
  48. };  
  49.   
  50. struct OBJECT  
  51. {                     
  52.     int             verts;  
  53.     VERTEX      *points;  
  54. } ;   
  55.   
  56.   
  57. OBJECT              morph1,morph2,morph3,morph4;  
  58.   
  59. osg::Geometry     *morphGeometry1, *morphGeometry2, *morphGeometry3, *morphGeometry4;  
  60. osg::Geometry       *srcMorphGeometry, *destMorphGeometry;  
  61.   
  62.   
  63. void objallocate(OBJECT *k,int n)         
  64. {  
  65.     k->points=(VERTEX*)malloc(sizeof(VERTEX)*n);  
  66. }  
  67.   
  68. void objfree(OBJECT *k)                           
  69. {  
  70.     free(k->points);                       
  71. }  
  72.   
  73. void readstr(FILE *f,char *string)                    
  74. {  
  75.     do                                                
  76.     {  
  77.         fgets(string, 255, f);                            
  78.     } while ((string[0] == '/') || (string[0] == '\n'));  
  79.     return;  
  80. }  
  81.   
  82. void objload(char *name,OBJECT *k)    
  83. {  
  84.     int     ver;      
  85.     float       rx,ry,rz;  
  86.     FILE    *filein;      
  87.     char         oneline[255];  
  88.   
  89.     filein = fopen(name, "rt");  
  90.     readstr(filein,oneline);      
  91.     sscanf(oneline, "Vertices: %d\n", &ver);      
  92.     k->verts=ver;      
  93.     objallocate(k,ver);  
  94.   
  95.     for (int i=0;i<ver;i++)  
  96.     {  
  97.         readstr(filein,oneline);      
  98.         sscanf(oneline, "%f %f %f", &rx, &ry, &rz);  
  99.         k->points[i].x = rx;  
  100.         k->points[i].y = ry;  
  101.         k->points[i].z = rz;  
  102.     }  
  103.     fclose(filein);  
  104. }  
  105.   
  106.   
  107. //  
  108.   
  109. class MorphUpdateCallback : public osg::Drawable::UpdateCallback  
  110. {  
  111. public:  
  112.     MorphUpdateCallback(osg::Geometry *dest, int steps) : _destGeometry(dest), _steps(steps)  
  113.     {  
  114.     }  
  115.   
  116.     void setDestGeometry(osg::Geometry *destGeometry)  
  117.     {  
  118.         _destGeometry = destGeometry;  
  119.     }  
  120.   
  121.     virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  122.     {  
  123.         osg::Geometry *geom = dynamic_cast<osg::Geometry*>(drawable);  
  124.         if (!geom)  
  125.             return;  
  126.           
  127.         osg::Vec3Array *vertices = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());  
  128.         osg::Vec3Array *destVertices = dynamic_cast<osg::Vec3Array*>(_destGeometry->getVertexArray());   
  129.         if (vertices && destVertices)  
  130.         {  
  131.             for (unsigned i = 0; i < vertices->size(); ++i)  
  132.             {  
  133.                 osg::Vec3 delta = (destVertices->at(i) - vertices->at(i)) / _steps;  
  134.                 vertices->at(i) += delta;  
  135.             }  
  136.             vertices->dirty();  
  137.         }     
  138.     }  
  139.   
  140.     int                         _steps;  
  141.     osg::Geometry*      _destGeometry;  
  142. };  
  143.   
  144.   
  145. void initMorphObject()  
  146. {  
  147.     objload("Data/sphere.txt",&morph1);  
  148.     objload("Data/torus.txt",&morph2);  
  149.     objload("Data/tube.txt",&morph3);  
  150.   
  151.     objallocate(&morph4,486);     
  152.     morph4.verts = 486;  
  153.     for(int i=0;i<486;i++)  
  154.     {  
  155.         morph4.points[i].x=((float)(rand()%14000)/1000)-7;  
  156.         morph4.points[i].y=((float)(rand()%14000)/1000)-7;  
  157.         morph4.points[i].z=((float)(rand()%14000)/1000)-7;    
  158.     }  
  159.       
  160.     morphGeometry1 = new osg::Geometry;  
  161.     osg::Vec3Array *vertexArray1 = new osg::Vec3Array;  
  162.     for (unsigned i = 0; i < morph1.verts; ++i)  
  163.     {  
  164.         vertexArray1->push_back(osg::Vec3(morph1.points[i].x, morph1.points[i].y, morph1.points[i].z));  
  165.     }  
  166.     morphGeometry1->setVertexArray(vertexArray1);  
  167.     morphGeometry1->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 486));  
  168.     morphGeometry1->setUseDisplayList(false);  
  169.     srcMorphGeometry = dynamic_cast<osg::Geometry*>(morphGeometry1->clone(osg::CopyOp::DEEP_COPY_ALL));  
  170.     destMorphGeometry = morphGeometry1;  
  171.       
  172.     morphGeometry2 = new osg::Geometry;  
  173.     osg::Vec3Array *vertexArray2 = new osg::Vec3Array;  
  174.     for (unsigned i = 0; i < morph2.verts; ++i)  
  175.     {  
  176.         vertexArray2->push_back(osg::Vec3(morph2.points[i].x, morph2.points[i].y, morph2.points[i].z));  
  177.     }  
  178.     morphGeometry2->setVertexArray(vertexArray2);  
  179.     morphGeometry2->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 486));  
  180.     morphGeometry2->setUseDisplayList(false);  
  181.   
  182.     morphGeometry3 = new osg::Geometry;  
  183.     osg::Vec3Array *vertexArray3 = new osg::Vec3Array;  
  184.     for (unsigned i = 0; i < morph3.verts; ++i)  
  185.     {  
  186.         vertexArray3->push_back(osg::Vec3(morph3.points[i].x, morph3.points[i].y, morph3.points[i].z));  
  187.     }  
  188.     morphGeometry3->setVertexArray(vertexArray3);  
  189.     morphGeometry3->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 486));  
  190.     morphGeometry3->setUseDisplayList(false);  
  191.       
  192.     morphGeometry4 = new osg::Geometry;  
  193.     osg::Vec3Array *vertexArray4 = new osg::Vec3Array;  
  194.     for (unsigned i = 0; i < morph4.verts; ++i)  
  195.     {  
  196.         vertexArray4->push_back(osg::Vec3(morph4.points[i].x, morph4.points[i].y, morph4.points[i].z));  
  197.     }  
  198.     morphGeometry4->setVertexArray(vertexArray4);  
  199.     morphGeometry4->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, 486));  
  200.     morphGeometry4->setUseDisplayList(false);  
  201. }  
  202.   
  203.   
  204. //  
  205. class RotAxisCallback : public osg::NodeCallback  
  206. {  
  207. public:  
  208.     RotAxisCallback(const osg::Vec3& axis, double rotSpeed = 0.0, double currentAngle = 0.0)  
  209.         : _rotAxis(axis), _rotSpeed(rotSpeed), _currentAngle(currentAngle){ }  
  210.   
  211.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  212.     {  
  213.         osg::MatrixTransform *rotMT = dynamic_cast<osg::MatrixTransform*>(node);  
  214.         if (!rotMT)  
  215.             return;  
  216.         rotMT->setMatrix(osg::Matrix::rotate(_currentAngle, _rotAxis));  
  217.         _currentAngle += _rotSpeed;  
  218.   
  219.         traverse(node, nv);  
  220.     }  
  221.   
  222.     void setRotateSpeed(double speed)  
  223.     {  
  224.         _rotSpeed = speed;  
  225.     }  
  226.   
  227.     double getRotateSpeed() const  
  228.     {  
  229.         return _rotSpeed;  
  230.     }  
  231.   
  232.   
  233. private:  
  234.     osg::Vec3       _rotAxis;  
  235.     double          _currentAngle;  
  236.     double          _rotSpeed;  
  237. };  
  238.   
  239.   
  240. //  
  241. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  242. {  
  243. public:  
  244.     ManipulatorSceneHandler()  
  245.     {  
  246.     }  
  247.   
  248.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  249.     {  
  250.         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);  
  251.         if (!viewer)  
  252.             return false;  
  253.         if (!viewer->getSceneData())  
  254.             return false;  
  255.         if (ea.getHandled())   
  256.             return false;  
  257.   
  258.         osg::Group *root = viewer->getSceneData()->asGroup();  
  259.   
  260.         switch(ea.getEventType())  
  261.         {  
  262.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  263.             {  
  264.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)  
  265.                 {  
  266.                     if (!g_rotateX)  
  267.                         return false;  
  268.   
  269.                     RotAxisCallback *rotCallback = dynamic_cast<RotAxisCallback*>(g_rotateX->getUpdateCallback());  
  270.                     if (!rotCallback)  
  271.                         return false;  
  272.   
  273.                     double speed = rotCallback->getRotateSpeed();  
  274.                     speed -= 0.02;  
  275.                     rotCallback->setRotateSpeed(speed);  
  276.                 }  
  277.   
  278.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)  
  279.                 {  
  280.                     if (!g_rotateX)  
  281.                         return false;  
  282.   
  283.                     RotAxisCallback *rotCallback = dynamic_cast<RotAxisCallback*>(g_rotateX->getUpdateCallback());  
  284.                     if (!rotCallback)  
  285.                         return false;  
  286.   
  287.                     double speed = rotCallback->getRotateSpeed();  
  288.                     speed += 0.02;  
  289.                     rotCallback->setRotateSpeed(speed);  
  290.                 }  
  291.   
  292.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)  
  293.                 {  
  294.                     if (!g_rotateY)  
  295.                         return false;  
  296.   
  297.                     RotAxisCallback *rotCallback = dynamic_cast<RotAxisCallback*>(g_rotateY->getUpdateCallback());  
  298.                     if (!rotCallback)  
  299.                         return false;  
  300.   
  301.                     double speed = rotCallback->getRotateSpeed();  
  302.                     speed -= 0.02;  
  303.                     rotCallback->setRotateSpeed(speed);  
  304.                 }  
  305.   
  306.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Down)  
  307.                 {  
  308.                     if (!g_rotateY)  
  309.                         return false;  
  310.   
  311.                     RotAxisCallback *rotCallback = dynamic_cast<RotAxisCallback*>(g_rotateY->getUpdateCallback());  
  312.                     if (!rotCallback)  
  313.                         return false;  
  314.   
  315.                     double speed = rotCallback->getRotateSpeed();  
  316.                     speed += 0.02;  
  317.                     rotCallback->setRotateSpeed(speed);  
  318.                 }  
  319.   
  320.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Up)  
  321.                 {     
  322.                     if (!g_rotateZ)  
  323.                         return false;  
  324.   
  325.                     RotAxisCallback *rotCallback = dynamic_cast<RotAxisCallback*>(g_rotateZ->getUpdateCallback());  
  326.                     if (!rotCallback)  
  327.                         return false;  
  328.   
  329.                     double speed = rotCallback->getRotateSpeed();  
  330.                     speed -= 0.02;  
  331.                     rotCallback->setRotateSpeed(speed);  
  332.                 }  
  333.   
  334.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Down)  
  335.                 {  
  336.                     if (!g_rotateZ)  
  337.                         return false;  
  338.   
  339.                     RotAxisCallback *rotCallback = dynamic_cast<RotAxisCallback*>(g_rotateZ->getUpdateCallback());  
  340.                     if (!rotCallback)  
  341.                         return false;  
  342.   
  343.                     double speed = rotCallback->getRotateSpeed();  
  344.                     speed += 0.02;  
  345.                     rotCallback->setRotateSpeed(speed);  
  346.                 }  
  347.   
  348.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_A)  
  349.                 {  
  350.                     if (!g_transMT)  
  351.                         return false;  
  352.   
  353.                     osg::Matrix transMatrix = g_transMT->getMatrix();  
  354.                     transMatrix.setTrans(transMatrix.getTrans() + osg::Vec3(-0.1, 0, 0));  
  355.                     g_transMT->setMatrix(transMatrix);  
  356.                 }  
  357.   
  358.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_D)  
  359.                 {  
  360.                     if (!g_transMT)  
  361.                         return false;  
  362.   
  363.                     osg::Matrix transMatrix = g_transMT->getMatrix();  
  364.                     transMatrix.setTrans(transMatrix.getTrans() + osg::Vec3(0.1, 0, 0));  
  365.                     g_transMT->setMatrix(transMatrix);  
  366.                 }  
  367.   
  368.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_W)  
  369.                 {  
  370.                     if (!g_transMT)  
  371.                         return false;  
  372.   
  373.                     osg::Matrix transMatrix = g_transMT->getMatrix();  
  374.                     transMatrix.setTrans(transMatrix.getTrans() + osg::Vec3(0, 0.1, 0));  
  375.                     g_transMT->setMatrix(transMatrix);  
  376.                 }  
  377.   
  378.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_S)  
  379.                 {  
  380.                     if (!g_transMT)  
  381.                         return false;  
  382.   
  383.                     osg::Matrix transMatrix = g_transMT->getMatrix();  
  384.                     transMatrix.setTrans(transMatrix.getTrans() + osg::Vec3(0, -0.1, 0));  
  385.                     g_transMT->setMatrix(transMatrix);  
  386.                 }  
  387.   
  388.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Q)  
  389.                 {  
  390.                     if (!g_transMT)  
  391.                         return false;  
  392.   
  393.                     osg::Matrix transMatrix = g_transMT->getMatrix();  
  394.                     transMatrix.setTrans(transMatrix.getTrans() + osg::Vec3(0, 0, -0.1));  
  395.                     g_transMT->setMatrix(transMatrix);  
  396.                 }  
  397.   
  398.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Z)  
  399.                 {  
  400.                     if (!g_transMT)  
  401.                         return false;  
  402.   
  403.                     osg::Matrix transMatrix = g_transMT->getMatrix();  
  404.                     transMatrix.setTrans(transMatrix.getTrans() + osg::Vec3(0, 0, 0.1));  
  405.                     g_transMT->setMatrix(transMatrix);  
  406.                 }  
  407.   
  408.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_1)  
  409.                 {  
  410.                     MorphUpdateCallback *muc = dynamic_cast<MorphUpdateCallback*>(srcMorphGeometry->getUpdateCallback());  
  411.                     if (!muc)  
  412.                         return false;  
  413.                     muc->setDestGeometry(morphGeometry1);  
  414.                 }  
  415.   
  416.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_2)  
  417.                 {  
  418.                     MorphUpdateCallback *muc = dynamic_cast<MorphUpdateCallback*>(srcMorphGeometry->getUpdateCallback());  
  419.                     if (!muc)  
  420.                         return false;  
  421.                     muc->setDestGeometry(morphGeometry2);  
  422.                 }  
  423.   
  424.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_3)  
  425.                 {  
  426.                     MorphUpdateCallback *muc = dynamic_cast<MorphUpdateCallback*>(srcMorphGeometry->getUpdateCallback());  
  427.                     if (!muc)  
  428.                         return false;  
  429.                     muc->setDestGeometry(morphGeometry3);  
  430.                 }  
  431.   
  432.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_4)  
  433.                 {  
  434.                     MorphUpdateCallback *muc = dynamic_cast<MorphUpdateCallback*>(srcMorphGeometry->getUpdateCallback());  
  435.                     if (!muc)  
  436.                         return false;  
  437.                     muc->setDestGeometry(morphGeometry4);  
  438.                 }  
  439.   
  440.             }  
  441.         defaultbreak;  
  442.         }  
  443.         return false;  
  444.     }  
  445. };  
  446.   
  447.   
  448.   
  449. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  450. {  
  451. public:  
  452.     ViewerWidget(osg::Node *scene = NULL)  
  453.     {  
  454.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,640,480), scene);  
  455.   
  456.         QVBoxLayout* layout = new QVBoxLayout;  
  457.         layout->addWidget(renderWidget);  
  458.         layout->setContentsMargins(0, 0, 0, 1);  
  459.         setLayout( layout );  
  460.   
  461.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  462.         _timer.start( 10 );  
  463.     }  
  464.   
  465.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  466.     {  
  467.         osg::Camera* camera = this->getCamera();  
  468.         camera->setGraphicsContext( gw );  
  469.   
  470.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  471.   
  472.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  473.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  474.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  475.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  476.   
  477.         this->setSceneData( scene );  
  478.         this->addEventHandler(new ManipulatorSceneHandler);  
  479.         return gw->getGLWidget();  
  480.     }  
  481.   
  482.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  483.     {  
  484.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  485.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  486.         traits->windowName = name;  
  487.         traits->windowDecoration = windowDecoration;  
  488.         traits->x = x;  
  489.         traits->y = y;  
  490.         traits->width = w;  
  491.         traits->height = h;  
  492.         traits->doubleBuffer = true;  
  493.         traits->alpha = ds->getMinimumNumAlphaBits();  
  494.         traits->stencil = ds->getMinimumNumStencilBits();  
  495.         traits->sampleBuffers = ds->getMultiSamples();  
  496.         traits->samples = ds->getNumMultiSamples();  
  497.   
  498.         return new osgQt::GraphicsWindowQt(traits.get());  
  499.     }  
  500.   
  501.     virtual void paintEvent( QPaintEvent* event )  
  502.     {   
  503.         frame();   
  504.     }  
  505.   
  506. protected:  
  507.   
  508.     QTimer _timer;  
  509. };  
  510.   
  511.   
  512. osg::Node*  buildScene()  
  513. {  
  514.     initMorphObject();  
  515.   
  516.     osg::Group *root = new osg::Group;  
  517.     root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);  
  518.   
  519.     osg::MatrixTransform *mt = new osg::MatrixTransform;  
  520.     g_transMT = mt;  
  521.     mt->setMatrix(osg::Matrix::translate(0, 0, cz));  
  522.   
  523.     osg::MatrixTransform *rotX = new osg::MatrixTransform;  
  524.     g_rotateX = rotX;  
  525.     rotX->addUpdateCallback(new RotAxisCallback(osg::X_AXIS));  
  526.     osg::MatrixTransform *rotY = new osg::MatrixTransform;  
  527.     g_rotateY = rotY;  
  528.     rotY->addUpdateCallback(new RotAxisCallback(osg::Y_AXIS));  
  529.     osg::MatrixTransform *rotZ = new osg::MatrixTransform;  
  530.     g_rotateZ = rotZ;  
  531.     rotZ->addUpdateCallback(new RotAxisCallback(osg::Z_AXIS));  
  532.       
  533.     osg::Geode *geode = new osg::Geode;  
  534.     geode->addDrawable(srcMorphGeometry);  
  535.     srcMorphGeometry->setUpdateCallback(new MorphUpdateCallback(destMorphGeometry,200));  
  536.       
  537.     root->addChild(mt);  
  538.     mt->addChild(rotX);  
  539.     rotX->addChild(rotY);  
  540.     rotY->addChild(rotZ);  
  541.     rotZ->addChild(geode);  
  542.       
  543.     return root;  
  544. }  
  545.   
  546.   
  547. int main( int argc, char** argv )  
  548. {  
  549.     QApplication app(argc, argv);  
  550.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  551.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  552.     viewWidget->show();  
  553.     return app.exec();  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值