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

  • 简介

这节课介绍了如何在三维场景中类似播放一段视频的效果。我们都知道视频实际上是由一帧帧的图片来构成的,因此我们将视频中的图片解析成图片格式,并将这些图片赋给几何体表面,让它们在很短的间隔内进行切换就实现了动态的效果。

  • 实现

本课中使用了Windows解析视频格式AVI文件的API,代码中这部分内容都来自NeHe课程中的相应代码,读者可以查阅MSDN了解这些内容:

首先创建播放AVI文件的几何体(类似于电影的大屏幕)

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Geode* createBackGroundGeode(osg::Texture2D *text)  
  2. {  
  3.     osg::Geode *geode = new osg::Geode;  
  4.     osg::Geometry *geometry = new osg::Geometry;  
  5.     geometry->setUpdateCallback(new DynamicTextureUpdateCallback);  
  6.  ...  
  7.     geometry->setVertexArray(vertexArray);  
  8.     geometry->setTexCoordArray(0, textureArray, osg::Array::BIND_PER_VERTEX);  
  9.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  10.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, text);  
  11.     geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false);  
  12.     geode->addDrawable(geometry);  
  13.   
  14.     return geode;  
  15. }  
动态的纹理回调DynamicTextureUpdateCallback实现了动态修改纹理:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class DynamicTextureUpdateCallback : public osg::Drawable::UpdateCallback  
  2. {  
  3. public:  
  4.     DynamicTextureUpdateCallback() : _lastUpdate(0), _frame(0), _passedTimeInMillSecond(0)  
  5.     {  
  6.         _startTime = osg::Timer::instance()->tick();   
  7.         _currentTime = _startTime;  
  8.     }  
  9.   
  10.     void update(osg::NodeVisitor* nv, osg::Drawable* drawable)  
  11.     {  
  12.         osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);  
  13.         if (!geometry)  
  14. ...  
  15.         }  
  16. };  
接着创建场景中的几何体:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Node*  createBox()  
  2. osg::Node*  createSphere()  
  3. osg::Node*  createCylinder()  
这部分内容与 第二十三课 的内容很类似

将上面所有的几何体添加到一个Switch开关节点中实现切换操作:

在与键盘的交互中实现切换纹理方式和切换节点的效果:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. case(osgGA::GUIEventAdapter::KEYDOWN):  
  2.     {  
  3.         if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)  
  4.         {  
  5.             if (!g_SwitchNode)  
  6.                 return false;  
  7.   
  8.             static int i = 0;  
  9.             ++i;  
  10.             if (i > 2)  
  11.                 i = 0;  
  12.             g_SwitchNode->setSingleChildOn(i);  
  13.         }  
  14.         if (ea.getKey() == osgGA::GUIEventAdapter::KEY_E)  
  15.         {  
  16.             static bool flag = true;  
  17.             if(flag){  
  18.                 g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_S, osg::StateAttribute::OFF);  
  19.                 g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_T, osg::StateAttribute::OFF);  
  20.             }else{  
  21.                 g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);  
  22.                 g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);  
  23.             }  
  24.             flag = !flag;  
  25.         }  
将以上所有内容添加到场景根节点下。编译运行程序:


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

[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. #include <osg/MatrixTransform>  
  11. #include <osg/Texture2D>  
  12. #include <osg/ShapeDrawable>  
  13.   
  14. #include <osg/Switch>  
  15. #include <osg/AnimationPath>  
  16.   
  17. #include <osg/TexGen>  
  18. #include <osg/TexGenNode>  
  19.   
  20. #include <vfw.h>  
  21.   
  22.   
  23. AVISTREAMINFO       psi;                      
  24. PAVISTREAM          pavi;                         
  25. PGETFRAME           pgf;                              
  26. BITMAPINFOHEADER    bmih;  
  27. long                lastframe;                                
  28. int                 width;                                
  29. int                 height;                               
  30. char                    *pdata;                               
  31. int                 mpf;                                      
  32.   
  33. HDRAWDIB hdd;                                     
  34. HBITMAP hBitmap;  
  35. HDC hdc = CreateCompatibleDC(0);          
  36. unsigned char* data = 0;                                  
  37.   
  38. osg::Texture2D *g_Texture2D = NULL;  
  39. osg::Image *g_TextureImage = NULL;  
  40. osg::Switch *g_SwitchNode = NULL;  
  41.   
  42. void flipIt(void* buffer)                                 
  43. {  
  44.     void* b = buffer;     
  45.     __asm                                                 
  46.     {  
  47.         mov ecx, 256*256  
  48.             mov ebx, b                            
  49. label:                                                
  50.         mov al,[ebx+0]                        
  51.         mov ah,[ebx+2]                        
  52.         mov [ebx+2],al                        
  53.             mov [ebx+0],ah                    
  54.   
  55.             add ebx,3                                 
  56.             dec ecx                                   
  57.             jnz label                                     
  58.     }  
  59. }  
  60.   
  61. void OpenAVI(LPCSTR szFile)  
  62. {  
  63.     TCHAR   title[100];  
  64.   
  65.     AVIFileInit();  
  66.     if (AVIStreamOpenFromFileA(&pavi, szFile, streamtypeVIDEO, 0, OF_READ, NULL) !=0)  
  67.     {  
  68.         return;  
  69.     }  
  70.   
  71.     AVIStreamInfo(pavi, &psi, sizeof(psi));  
  72.     width=psi.rcFrame.right-psi.rcFrame.left;  
  73.     height=psi.rcFrame.bottom-psi.rcFrame.top;  
  74.   
  75.     lastframe=AVIStreamLength(pavi);  
  76.   
  77.     mpf=AVIStreamSampleToTime(pavi,lastframe)/lastframe;  
  78.   
  79.     bmih.biSize = sizeof (BITMAPINFOHEADER);  
  80.     bmih.biPlanes = 1;  
  81.     bmih.biBitCount = 24;  
  82.     bmih.biWidth = 256;  
  83.     bmih.biHeight = 256;  
  84.     bmih.biCompression = BI_RGB;  
  85.   
  86.     hBitmap = CreateDIBSection (hdc, (BITMAPINFO*)(&bmih), DIB_RGB_COLORS, (void**)(&data), NULL, NULL);  
  87.     SelectObject (hdc, hBitmap);  
  88.   
  89.     pgf=AVIStreamGetFrameOpen(pavi, NULL);  
  90.     if (pgf==NULL)  
  91.     {  
  92.         return;  
  93.     }  
  94. }  
  95.   
  96.   
  97. void GrabAVIFrame(int frame)  
  98. {  
  99.     LPBITMAPINFOHEADER lpbi;  
  100.     lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, frame);  
  101.     pdata=(char *)lpbi+lpbi->biSize+lpbi->biClrUsed * sizeof(RGBQUAD);  
  102.   
  103.     DrawDibDraw (hdd, hdc, 0, 0, 256, 256, lpbi, pdata, 0, 0, width, height, 0);  
  104.     flipIt(data);  
  105.   
  106.     g_TextureImage->setImage(256, 256, 1, 3, GL_RGB, GL_UNSIGNED_BYTE, data, osg::Image::NO_DELETE);  
  107.     g_Texture2D->setImage(g_TextureImage);  
  108. }  
  109.   
  110.   
  111. void CloseAVI(void)  
  112. {  
  113.     DeleteObject(hBitmap);  
  114.     DrawDibClose(hdd);  
  115.     AVIStreamGetFrameClose(pgf);  
  116.     AVIStreamRelease(pavi);  
  117.     AVIFileExit();  
  118. }  
  119.   
  120.   
  121. void initialize()  
  122. {  
  123.     hdd = DrawDibOpen();  
  124.     g_Texture2D = new osg::Texture2D;  
  125.     g_Texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);  
  126.     g_Texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);  
  127.     g_TextureImage = new osg::Image;  
  128.     g_TextureImage->allocateImage(256, 256, 1, GL_RGB, GL_UNSIGNED_BYTE);  
  129.     OpenAVI("Data/face3.avi");  
  130. }  
  131.   
  132.   
  133. class DynamicTextureUpdateCallback : public osg::Drawable::UpdateCallback  
  134. {  
  135. public:  
  136.     DynamicTextureUpdateCallback() : _lastUpdate(0), _frame(0), _passedTimeInMillSecond(0)  
  137.     {  
  138.         _startTime = osg::Timer::instance()->tick();   
  139.         _currentTime = _startTime;  
  140.     }  
  141.   
  142.     void update(osg::NodeVisitor* nv, osg::Drawable* drawable)  
  143.     {  
  144.         osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);  
  145.         if (!geometry)  
  146.             return;  
  147.         osg::Texture2D *texture2D = dynamic_cast<osg::Texture2D *>(geometry->getOrCreateStateSet()->getTextureAttribute(  
  148.                                                                                                             0, osg::StateAttribute::TEXTURE));  
  149.         if (!texture2D)  
  150.             return;  
  151.   
  152.         if (nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR &&  
  153.             nv->getFrameStamp() &&  
  154.             nv->getFrameStamp()->getFrameNumber() != _lastUpdate)   
  155.         {  
  156.             _lastUpdate = nv->getFrameStamp()->getFrameNumber();  
  157.             _currentTime = osg::Timer::instance()->tick();  
  158.             float t = osg::Timer::instance()->delta_m(_startTime, _currentTime);  
  159.             _passedTimeInMillSecond += t;  
  160.               
  161.             if (_passedTimeInMillSecond >= mpf)  
  162.             {  
  163.                 GrabAVIFrame(_frame);  
  164.                 _frame++;  
  165.   
  166.                 if (_frame >= lastframe)  
  167.                 {  
  168.                     _frame = 0;  
  169.                 }  
  170.                 _passedTimeInMillSecond = 0;  
  171.             }  
  172.         }  
  173.     }  
  174.   
  175.     osg::Timer_t    _startTime;  
  176.     osg::Timer_t    _currentTime;  
  177.     unsigned int        _lastUpdate;  
  178.     unsigned int        _frame;  
  179.     int                 _passedTimeInMillSecond;  
  180. };  
  181.   
  182.   
  183. //  
  184. ///绘制几何体/  
  185. //  
  186. osg::Geode* createBackGroundGeode(osg::Texture2D *text)  
  187. {  
  188.     osg::Geode *geode = new osg::Geode;  
  189.     osg::Geometry *geometry = new osg::Geometry;  
  190.     geometry->setUpdateCallback(new DynamicTextureUpdateCallback);  
  191.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  192.     osg::Vec2Array *textureArray = new osg::Vec2Array;  
  193.   
  194.     vertexArray->push_back(osg::Vec3(11.0f,  8.3f, -20.0f));  
  195.     vertexArray->push_back(osg::Vec3(-11.0f,  8.3f, -20.0f));  
  196.     vertexArray->push_back(osg::Vec3(-11.0f, -8.3f, -20.0f));  
  197.     vertexArray->push_back(osg::Vec3(11.0f, -8.3f, -20.0f));  
  198.   
  199.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  200.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  201.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  202.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  203.   
  204.     geometry->setVertexArray(vertexArray);  
  205.     geometry->setTexCoordArray(0, textureArray, osg::Array::BIND_PER_VERTEX);  
  206.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  207.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, text);  
  208.     geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false);  
  209.     geode->addDrawable(geometry);  
  210.   
  211.     return geode;  
  212. }  
  213.   
  214. osg::Node*  createBox(/*osg::Texture2D *text*/)  
  215. {  
  216.     osg::MatrixTransform *mtX = new osg::MatrixTransform;  
  217.     mtX->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::X_AXIS, 1.5));  
  218.     osg::MatrixTransform *mtY = new osg::MatrixTransform;  
  219.     mtY->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Y_AXIS, 2.5));  
  220.     osg::MatrixTransform *mtZ = new osg::MatrixTransform;  
  221.     mtZ->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 3.5));  
  222.   
  223.     osg::Geode *geode = new osg::Geode;  
  224.     osg::Geometry *geometry = new osg::Geometry;  
  225.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  226.     osg::Vec2Array *textureArray = new osg::Vec2Array;  
  227.     osg::Vec3Array *normalArray = new osg::Vec3Array;  
  228.       
  229.     for (int i = 0; i < 4; ++i)  
  230.         normalArray->push_back(osg::Vec3(0.0f, 0.0f, 0.5f));  
  231.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  232.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  233.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  234.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  235.     vertexArray->push_back(osg::Vec3(-1.0f, -1.0f,  1.0f));  
  236.     vertexArray->push_back(osg::Vec3(1.0f, -1.0f,  1.0f));  
  237.     vertexArray->push_back(osg::Vec3(1.0f,  1.0f,  1.0f));  
  238.     vertexArray->push_back(osg::Vec3(-1.0f,  1.0f,  1.0f));  
  239.       
  240.     for (int i = 0; i < 4; ++i)  
  241.         normalArray->push_back(osg::Vec3(0.0f, 0.0f,-0.5f));  
  242.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  243.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  244.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  245.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  246.     vertexArray->push_back(osg::Vec3(-1.0f, -1.0f,  -1.0f));  
  247.     vertexArray->push_back(osg::Vec3(-1.0f, 1.0f,  -1.0f));  
  248.     vertexArray->push_back(osg::Vec3(1.0f,  1.0f, - 1.0f));  
  249.     vertexArray->push_back(osg::Vec3(1.0f,  -1.0f,  -1.0f));  
  250.   
  251.     for (int i = 0; i < 4; ++i)  
  252.         normalArray->push_back(osg::Vec3(0.0f, 0.5f,0.0f));  
  253.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  254.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  255.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  256.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  257.     vertexArray->push_back(osg::Vec3(-1.0f, 1.0f,  -1.0f));  
  258.     vertexArray->push_back(osg::Vec3(-1.0f, 1.0f,  1.0f));  
  259.     vertexArray->push_back(osg::Vec3(1.0f,  1.0f,  1.0f));  
  260.     vertexArray->push_back(osg::Vec3(1.0f,  1.0f,  -1.0f));  
  261.   
  262.     for (int i = 0; i < 4; ++i)  
  263.         normalArray->push_back(osg::Vec3(0.0f, -0.5f,0.0f));  
  264.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  265.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  266.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  267.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  268.     vertexArray->push_back(osg::Vec3(-1.0f, -1.0f,  -1.0f));  
  269.     vertexArray->push_back(osg::Vec3(1.0f, -1.0f,  -1.0f));  
  270.     vertexArray->push_back(osg::Vec3(1.0f,  -1.0f,  1.0f));  
  271.     vertexArray->push_back(osg::Vec3(-1.0f,  -1.0f,  1.0f));  
  272.   
  273.     for (int i = 0; i < 4; ++i)  
  274.         normalArray->push_back(osg::Vec3(0.5f, 0.0f,0.0f));  
  275.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  276.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  277.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  278.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  279.     vertexArray->push_back(osg::Vec3(1.0f, -1.0f,  -1.0f));  
  280.     vertexArray->push_back(osg::Vec3(1.0f, 1.0f,  -1.0f));  
  281.     vertexArray->push_back(osg::Vec3(1.0f,  1.0f,  1.0f));  
  282.     vertexArray->push_back(osg::Vec3(1.0f,  -1.0f,  1.0f));  
  283.   
  284.     for (int i = 0; i < 4; ++i)  
  285.         normalArray->push_back(osg::Vec3(-0.5f, 0.0f,0.0f));  
  286.     textureArray->push_back(osg::Vec2(0.0f, 0.0f));  
  287.     textureArray->push_back(osg::Vec2(1.0f, 0.0f));  
  288.     textureArray->push_back(osg::Vec2(1.0f, 1.0f));  
  289.     textureArray->push_back(osg::Vec2(0.0f, 1.0f));  
  290.     vertexArray->push_back(osg::Vec3(-1.0f, -1.0f,  -1.0f));  
  291.     vertexArray->push_back(osg::Vec3(-1.0f, -1.0f,  1.0f));  
  292.     vertexArray->push_back(osg::Vec3(-1.0f,  1.0f,  1.0f));  
  293.     vertexArray->push_back(osg::Vec3(-1.0f,  1.0f,  -1.0f));  
  294.   
  295.     geometry->setVertexArray(vertexArray);  
  296.     geometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX);  
  297.     geometry->setTexCoordArray(0, textureArray, osg::Array::BIND_PER_VERTEX);  
  298.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  299.     geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false);  
  300.     geode->addDrawable(geometry);  
  301.   
  302.     mtX->addChild(mtY);  
  303.     mtY->addChild(mtZ);  
  304.     mtZ->addChild(geode);  
  305.   
  306.     return mtX;  
  307. }  
  308.   
  309. osg::Node*  createSphere()  
  310. {  
  311.     osg::MatrixTransform *mtX = new osg::MatrixTransform;  
  312.     mtX->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::X_AXIS, 1.5));  
  313.     osg::MatrixTransform *mtY = new osg::MatrixTransform;  
  314.     mtY->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Y_AXIS, 2.5));  
  315.     osg::MatrixTransform *mtZ = new osg::MatrixTransform;  
  316.     mtZ->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 3.5));  
  317.   
  318.     osg::Geode *sphere = new osg::Geode;  
  319.     osg::ShapeDrawable *sphereDrawable = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0,0,0), 1.3));  
  320.     sphere->addDrawable(sphereDrawable);  
  321.   
  322.     mtX->addChild(mtY);  
  323.     mtY->addChild(mtZ);  
  324.     mtZ->addChild(sphere);  
  325.   
  326.     return mtX;  
  327. }  
  328.   
  329. osg::Node*  createCylinder()  
  330. {  
  331.     osg::MatrixTransform *mtX = new osg::MatrixTransform;  
  332.     mtX->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::X_AXIS, 1.5));  
  333.     osg::MatrixTransform *mtY = new osg::MatrixTransform;  
  334.     mtY->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Y_AXIS, 2.5));  
  335.     osg::MatrixTransform *mtZ = new osg::MatrixTransform;  
  336.     mtZ->addUpdateCallback(new osg::AnimationPathCallback(osg::Vec3(), osg::Z_AXIS, 3.5));  
  337.   
  338.     osg::Geode *cylinder = new osg::Geode;  
  339.     osg::ShapeDrawable *cylinderDrawable = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0,0,0), 0.5, 2.0));  
  340.     cylinder->addDrawable(cylinderDrawable);  
  341.   
  342.     mtX->addChild(mtY);  
  343.     mtY->addChild(mtZ);  
  344.     mtZ->addChild(cylinder);  
  345.   
  346.   
  347.     return mtX;  
  348. }  
  349.   
  350. //  
  351. /场景交互//  
  352. //  
  353. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  354. {  
  355. public:  
  356.     ManipulatorSceneHandler()  
  357.     {  
  358.     }  
  359.   
  360.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  361.     {  
  362.         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);  
  363.         if (!viewer)  
  364.             return false;  
  365.         if (!viewer->getSceneData())  
  366.             return false;  
  367.         if (ea.getHandled())   
  368.             return false;  
  369.   
  370.         switch(ea.getEventType())  
  371.         {  
  372.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  373.             {  
  374.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)  
  375.                 {  
  376.                     if (!g_SwitchNode)  
  377.                         return false;  
  378.   
  379.                     static int i = 0;  
  380.                     ++i;  
  381.                     if (i > 2)  
  382.                         i = 0;  
  383.                     g_SwitchNode->setSingleChildOn(i);  
  384.                 }  
  385.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_E)  
  386.                 {  
  387.                     static bool flag = true;  
  388.                     if(flag){  
  389.                         g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_S, osg::StateAttribute::OFF);  
  390.                         g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_T, osg::StateAttribute::OFF);  
  391.                     }else{  
  392.                         g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);  
  393.                         g_SwitchNode->getOrCreateStateSet()->setTextureMode(0, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);  
  394.                     }  
  395.                     flag = !flag;  
  396.                 }  
  397.             }  
  398.         defaultbreak;  
  399.         }  
  400.         return false;  
  401.     }  
  402. };  
  403. //  
  404.   
  405.   
  406.   
  407. //  
  408. //osgNeHe框架  
  409. //  
  410. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  411. {  
  412. public:  
  413.     ViewerWidget(osg::Node *scene = NULL)  
  414.     {  
  415.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  416.   
  417.         QVBoxLayout* layout = new QVBoxLayout;  
  418.         layout->addWidget(renderWidget);  
  419.         layout->setContentsMargins(0, 0, 0, 1);  
  420.         setLayout( layout );  
  421.   
  422.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  423.         _timer.start( 10 );  
  424.     }  
  425.   
  426.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  427.     {  
  428.         osg::Camera* camera = this->getCamera();  
  429.         camera->setGraphicsContext( gw );  
  430.   
  431.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  432.   
  433.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  434.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  435.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  436.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 0), osg::Vec3d(0, 0, -1), osg::Vec3d(0, 1, 0));  
  437.   
  438.         this->setSceneData( scene );  
  439.         this->addEventHandler(new ManipulatorSceneHandler);  
  440.   
  441.         return gw->getGLWidget();  
  442.     }  
  443.   
  444.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  445.     {  
  446.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  447.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  448.         traits->windowName = name;  
  449.         traits->windowDecoration = windowDecoration;  
  450.         traits->x = x;  
  451.         traits->y = y;  
  452.         traits->width = w;  
  453.         traits->height = h;  
  454.         traits->doubleBuffer = true;  
  455.         traits->alpha = ds->getMinimumNumAlphaBits();  
  456.         traits->stencil = ds->getMinimumNumStencilBits();  
  457.         traits->sampleBuffers = ds->getMultiSamples();  
  458.         traits->samples = ds->getNumMultiSamples();  
  459.   
  460.         return new osgQt::GraphicsWindowQt(traits.get());  
  461.     }  
  462.   
  463.     virtual void paintEvent( QPaintEvent* event )  
  464.     {   
  465.         frame();   
  466.     }  
  467.   
  468. protected:  
  469.   
  470.     QTimer _timer;  
  471. };  
  472.   
  473.   
  474.   
  475. osg::Node*  buildScene()  
  476. {  
  477.     initialize();  
  478.   
  479.     osg::Group *root = new osg::Group;  
  480.       
  481.     osg::Switch *switchNode = new osg::Switch;  
  482.     g_SwitchNode = switchNode;  
  483.     switchNode->addChild(createBox());  
  484.     switchNode->addChild(createCylinder());  
  485.     switchNode->addChild(createSphere());  
  486.     switchNode->setSingleChildOn(0);  
  487.   
  488.     osg::TexGen *texGen = new osg::TexGen;  
  489.     texGen->setMode(osg::TexGen::SPHERE_MAP);  
  490.     switchNode->getOrCreateStateSet()->setTextureAttributeAndModes(0, texGen);  
  491.     switchNode->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Texture2D);  
  492.   
  493.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  494.     zoomMT->setMatrix(osg::Matrix::translate(0.0f, 0.0f, -10.0f));  
  495.     zoomMT->addChild(switchNode);  
  496.   
  497.     root->addChild(createBackGroundGeode(g_Texture2D));  
  498.     root->addChild(zoomMT);  
  499.     return root;  
  500. }  
  501.   
  502. int main( int argc, char** argv )  
  503. {  
  504.     QApplication app(argc, argv);  
  505.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  506.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  507.     viewWidget->show();  
  508.     return app.exec();  
  509. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值