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

来源:互联网 发布:淘宝商品详情图片 编辑:程序博客网 时间:2024/06/05 12:01
  • 简介

这节课NeHe课程向我们介绍了如何读取帧缓存中的像素值,并把 它作为场景中的纹理加载到几何体上。也就是我们常说的渲染到纹理(Render To Texture)功能,也称纹理烘培。这一功能主要有两个作用:第一是实现场景离屏渲染之后的后置处理;第二是实现多种不同场景的融合显示效果。

  • 实现

首先创建我们场景中需要显示的Helix模型,代码如下:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. osg::Geode* createHelix()  

接下来我们需要将这个模型加载的场景写到纹理中去,在OSG中可以通过创建渲染到纹理的相机完成这样的操作:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. osg::Camera*    createRenderToTextureCamera(int w, int h)  
  2. {  
  3.     osg::Camera *rtt = new osg::Camera;  
  4.     rtt->setClearColor(osg::Vec4(0.0f, 0.0f, 0.5f, 0.5));      
  5.     rtt->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  6.     rtt->setReferenceFrame(osg::Transform::ABSOLUTE_RF);  
  7.     rtt->setViewport(0, 0, w, h);  
  8.     rtt->setRenderOrder(osg::Camera::PRE_RENDER);  
  9.     rtt->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);  
  10.     rtt->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(640)/static_cast<double>(480), 0.1f, 100.0f );  
  11.     rtt->setViewMatrixAsLookAt(osg::Vec3d(0, 5, 50), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  12.   
  13.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  14.     zoomMT->setMatrix(osg::Matrix::translate(0,0,-50));  
  15.     osg::MatrixTransform *xRotMT = new osg::MatrixTransform;  
  16.     xRotMT->addUpdateCallback(new RotAxisCallback(osg::X_AXIS, 0.02));  
  17.     osg::MatrixTransform *yRotMT = new osg::MatrixTransform;  
  18.     yRotMT->addUpdateCallback(new RotAxisCallback(osg::Y_AXIS, 0.01));  
  19.   
  20.     zoomMT->addChild(xRotMT);  
  21.     xRotMT->addChild(yRotMT);  
  22.     yRotMT->addChild(createHelix());  
  23.   
  24.     rtt->addChild(zoomMT);  
  25.       
  26.     return rtt;  
  27. }  
通过设置相机渲染方式是PRE_RENDER可以保证在渲染其他场景之前先渲染这个相机中的场景,并通过下面的操作将其保存到纹理之中:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. g_Texture = createTexture(128,128);  
  2. osg::Camera *rttCamera = createRenderToTextureCamera(128, 128);  
  3. rttCamera->attach(osg::Camera::COLOR_BUFFER, g_Texture);  
这样我们需要的纹理就创建好了。

接下来加载使用纹理的几何体:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. osg::Node*  createBlur(int times, float inc)  
同时在几何体的更新中不断修改纹理坐标的位置,实现微小的偏移,整个场景看起来像一种运动模糊的效果:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. class BlurGeometryUpdateCallback : public osg::Drawable::UpdateCallback  

最后把所有这些部分添加到场景根节点中,编译运行程序:


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

[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/AnimationPath>  
  13.   
  14. #include <osg/Material>  
  15. #include <osg/LightSource>  
  16.   
  17. #include <osg/BlendFunc>  
  18. #include <osg/Texture2D>  
  19. #include <osg/State>  
  20.   
  21.   
  22. float       angle;  
  23. float     vertexes[4][3];  
  24. float     normal[3];  
  25. osg::Texture2D  *g_Texture;  
  26.   
  27. //////////////////////////////////////////////////////////////////////////  
  28. //////////////////////////////////////////////////////////////////////////  
  29. //////////////////////////////////////////////////////////////////////////  
  30.   
  31. void ReduceToUnit(float vector[3])                              // Reduces A Normal Vector (3 Coordinates)  
  32. {                                                               // To A Unit Normal Vector With A Length Of One.  
  33.     float length;                                               // Holds Unit Length  
  34.     // Calculates The Length Of The Vector  
  35.     length = (float)sqrt((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2]));  
  36.   
  37.     if(length == 0.0f)                                          // Prevents Divide By 0 Error By Providing  
  38.         length = 1.0f;                                          // An Acceptable Value For Vectors To Close To 0.  
  39.   
  40.     vector[0] /= length;                                        // Dividing Each Element By  
  41.     vector[1] /= length;                                        // The Length Results In A  
  42.     vector[2] /= length;                                        // Unit Normal Vector.  
  43. }  
  44.   
  45. void calcNormal(float v[3][3], float out[3])                    // Calculates Normal For A Quad Using 3 Points  
  46. {  
  47.     float v1[3],v2[3];                                          // Vector 1 (x,y,z) & Vector 2 (x,y,z)  
  48.     static const int x = 0;                                     // Define X Coord  
  49.     static const int y = 1;                                     // Define Y Coord  
  50.     static const int z = 2;                                     // Define Z Coord  
  51.   
  52.     // Finds The Vector Between 2 Points By Subtracting  
  53.     // The x,y,z Coordinates From One Point To Another.  
  54.   
  55.     // Calculate The Vector From Point 1 To Point 0  
  56.     v1[x] = v[0][x] - v[1][x];                                  // Vector 1.x=Vertex[0].x-Vertex[1].x  
  57.     v1[y] = v[0][y] - v[1][y];                                  // Vector 1.y=Vertex[0].y-Vertex[1].y  
  58.     v1[z] = v[0][z] - v[1][z];                                  // Vector 1.z=Vertex[0].y-Vertex[1].z  
  59.     // Calculate The Vector From Point 2 To Point 1  
  60.     v2[x] = v[1][x] - v[2][x];                                  // Vector 2.x=Vertex[0].x-Vertex[1].x  
  61.     v2[y] = v[1][y] - v[2][y];                                  // Vector 2.y=Vertex[0].y-Vertex[1].y  
  62.     v2[z] = v[1][z] - v[2][z];                                  // Vector 2.z=Vertex[0].z-Vertex[1].z  
  63.     // Compute The Cross Product To Give Us A Surface Normal  
  64.     out[x] = v1[y]*v2[z] - v1[z]*v2[y];                         // Cross Product For Y - Z  
  65.     out[y] = v1[z]*v2[x] - v1[x]*v2[z];                         // Cross Product For X - Z  
  66.     out[z] = v1[x]*v2[y] - v1[y]*v2[x];                         // Cross Product For X - Y  
  67.   
  68.     ReduceToUnit(out);                                          // Normalize The Vectors  
  69. }  
  70.   
  71.   
  72.   
  73.   
  74. class RotAxisCallback : public osg::NodeCallback  
  75. {  
  76. public:  
  77.     RotAxisCallback(const osg::Vec3& axis, double rotSpeed = 0.0, double currentAngle = 0.0)  
  78.         : _rotAxis(axis), _rotSpeed(rotSpeed), _currentAngle(currentAngle){ }  
  79.   
  80.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  81.     {  
  82.         osg::MatrixTransform *rotMT = dynamic_cast<osg::MatrixTransform*>(node);  
  83.         if (!rotMT)  
  84.             return;  
  85.         _currentAngle += _rotSpeed;  
  86.         rotMT->setMatrix(osg::Matrix::rotate(_currentAngle, _rotAxis));  
  87.           
  88.         traverse(node, nv);  
  89.     }  
  90.   
  91.     void setRotateSpeed(double speed)  
  92.     {  
  93.         _rotSpeed = speed;  
  94.     }  
  95.   
  96.     double getRotateSpeed() const  
  97.     {  
  98.         return _rotSpeed;  
  99.     }  
  100.   
  101.     double getCurrentAngle() const  
  102.     {  
  103.         return _currentAngle;  
  104.     }  
  105.   
  106.   
  107. private:  
  108.     osg::Vec3       _rotAxis;  
  109.     double          _currentAngle;  
  110.     double          _rotSpeed;  
  111. };  
  112.   
  113. osg::Geode* createHelix()  
  114. {  
  115.     GLfloat x;                                  // Helix x Coordinate  
  116.     GLfloat y;                                  // Helix y Coordinate  
  117.     GLfloat z;                                      // Helix z Coordinate  
  118.     GLfloat phi;                                    // Angle  
  119.     GLfloat theta;                              // Angle  
  120.     GLfloat v,u;                                    // Angles  
  121.     GLfloat r = 1.5f;                           // Radius Of Twist  
  122.     int twists = 5;                             // 5 Twists  
  123.       
  124.     osg::Geode *geode = new osg::Geode;  
  125.     osg::Geometry *geometry = new osg::Geometry;  
  126.     osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  127.     osg::Vec3Array *normalArray = new osg::Vec3Array;  
  128.   
  129. //////////////////////////////////////////////////////////////////////////  
  130.     for(int phi=0; phi <= 360; phi+=20.0)                            // 360 Degrees In Steps Of 20  
  131.     {  
  132.         for(int theta=0; theta<=360*twists; theta+=20.0)         // 360 Degrees * Number Of Twists In Steps Of 20  
  133.         {  
  134.             v=(phi/180.0f*3.142f);                              // Calculate Angle Of First Point   (  0 )  
  135.             u=(theta/180.0f*3.142f);                            // Calculate Angle Of First Point   (  0 )  
  136.   
  137.             x=float(cos(u)*(2.0f+cos(v) ))*r;                   // Calculate x Position (1st Point)  
  138.             y=float(sin(u)*(2.0f+cos(v) ))*r;                   // Calculate y Position (1st Point)  
  139.             z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);        // Calculate z Position (1st Point)  
  140.   
  141.             vertexes[0][0]=x;                                   // Set x Value Of First Vertex  
  142.             vertexes[0][1]=y;                                   // Set y Value Of First Vertex  
  143.             vertexes[0][2]=z;                                   // Set z Value Of First Vertex  
  144.   
  145.             v=(phi/180.0f*3.142f);                              // Calculate Angle Of Second Point  (  0 )  
  146.             u=((theta+20)/180.0f*3.142f);                       // Calculate Angle Of Second Point  ( 20 )  
  147.   
  148.             x=float(cos(u)*(2.0f+cos(v) ))*r;                   // Calculate x Position (2nd Point)  
  149.             y=float(sin(u)*(2.0f+cos(v) ))*r;                   // Calculate y Position (2nd Point)  
  150.             z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);        // Calculate z Position (2nd Point)  
  151.   
  152.             vertexes[1][0]=x;                                   // Set x Value Of Second Vertex  
  153.             vertexes[1][1]=y;                                   // Set y Value Of Second Vertex  
  154.             vertexes[1][2]=z;                                   // Set z Value Of Second Vertex  
  155.   
  156.             v=((phi+20)/180.0f*3.142f);                         // Calculate Angle Of Third Point   ( 20 )  
  157.             u=((theta+20)/180.0f*3.142f);                       // Calculate Angle Of Third Point   ( 20 )  
  158.   
  159.             x=float(cos(u)*(2.0f+cos(v) ))*r;                   // Calculate x Position (3rd Point)  
  160.             y=float(sin(u)*(2.0f+cos(v) ))*r;                   // Calculate y Position (3rd Point)  
  161.             z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);        // Calculate z Position (3rd Point)  
  162.   
  163.             vertexes[2][0]=x;                                   // Set x Value Of Third Vertex  
  164.             vertexes[2][1]=y;                                   // Set y Value Of Third Vertex  
  165.             vertexes[2][2]=z;                                   // Set z Value Of Third Vertex  
  166.   
  167.             v=((phi+20)/180.0f*3.142f);                         // Calculate Angle Of Fourth Point  ( 20 )  
  168.             u=((theta)/180.0f*3.142f);                          // Calculate Angle Of Fourth Point  (  0 )  
  169.   
  170.             x=float(cos(u)*(2.0f+cos(v) ))*r;                   // Calculate x Position (4th Point)  
  171.             y=float(sin(u)*(2.0f+cos(v) ))*r;                   // Calculate y Position (4th Point)  
  172.             z=float((( u-(2.0f*3.142f)) + sin(v) ) * r);        // Calculate z Position (4th Point)  
  173.   
  174.             vertexes[3][0]=x;                                   // Set x Value Of Fourth Vertex  
  175.             vertexes[3][1]=y;                                   // Set y Value Of Fourth Vertex  
  176.             vertexes[3][2]=z;                                   // Set z Value Of Fourth Vertex  
  177.   
  178.             calcNormal(vertexes,normal);                        // Calculate The Quad Normal  
  179.   
  180.             normalArray->push_back(osg::Vec3(normal[0],normal[1],normal[2]));  
  181.             normalArray->push_back(osg::Vec3(normal[0],normal[1],normal[2]));  
  182.             normalArray->push_back(osg::Vec3(normal[0],normal[1],normal[2]));  
  183.             normalArray->push_back(osg::Vec3(normal[0],normal[1],normal[2]));  
  184.   
  185.             // Render The Quad  
  186.             vertexArray->push_back(osg::Vec3(vertexes[0][0],vertexes[0][1],vertexes[0][2]));  
  187.             vertexArray->push_back(osg::Vec3(vertexes[1][0],vertexes[1][1],vertexes[1][2]));  
  188.             vertexArray->push_back(osg::Vec3(vertexes[2][0],vertexes[2][1],vertexes[2][2]));  
  189.             vertexArray->push_back(osg::Vec3(vertexes[3][0],vertexes[3][1],vertexes[3][2]));  
  190.         }  
  191.     }  
  192. //////////////////////////////////////////////////////////////////////////  
  193.   
  194.     geometry->setVertexArray(vertexArray);  
  195.     geometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX);  
  196.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  197.   
  198.     osg::Material *helixMat = new osg::Material;  
  199.     helixMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0.4f,0.2f,0.8f,1.0f));  
  200.     helixMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0.4f,0.2f,0.8f,1.0f));  
  201.     helixMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(1.0f,1.0f,1.0f,1.0f));  
  202.     helixMat->setShininess(osg::Material::FRONT, 128.0f);  
  203.   
  204.     geometry->getOrCreateStateSet()->setAttributeAndModes(helixMat);  
  205.     geometry->getOrCreateStateSet()->setMode(GL_LIGHT0, osg::StateAttribute::ON);  
  206.   
  207.     geode->addDrawable(geometry);  
  208.   
  209.     return geode;  
  210. }  
  211.   
  212.   
  213. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  214. {  
  215. public:  
  216.     ViewerWidget(osg::Node *scene = NULL)  
  217.     {  
  218.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,640,480), scene);  
  219.   
  220.         QVBoxLayout* layout = new QVBoxLayout;  
  221.         layout->addWidget(renderWidget);  
  222.         layout->setContentsMargins(0, 0, 0, 1);  
  223.         setLayout( layout );  
  224.   
  225.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  226.         _timer.start( 10 );  
  227.     }  
  228.   
  229.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  230.     {  
  231.         osg::Camera* camera = this->getCamera();  
  232.         camera->setGraphicsContext( gw );  
  233.   
  234.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  235.   
  236.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 0.5) );  
  237.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  238.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  239.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 5, 50), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  240.   
  241.         this->setSceneData( scene );  
  242.         return gw->getGLWidget();  
  243.     }  
  244.   
  245.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  246.     {  
  247.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  248.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  249.         traits->windowName = name;  
  250.         traits->windowDecoration = windowDecoration;  
  251.         traits->x = x;  
  252.         traits->y = y;  
  253.         traits->width = w;  
  254.         traits->height = h;  
  255.         traits->doubleBuffer = true;  
  256.         traits->alpha = ds->getMinimumNumAlphaBits();  
  257.         traits->stencil = ds->getMinimumNumStencilBits();  
  258.         traits->sampleBuffers = ds->getMultiSamples();  
  259.         traits->samples = ds->getNumMultiSamples();  
  260.   
  261.         return new osgQt::GraphicsWindowQt(traits.get());  
  262.     }  
  263.   
  264.     virtual void paintEvent( QPaintEvent* event )  
  265.     {   
  266.         frame();   
  267.     }  
  268.   
  269. protected:  
  270.   
  271.     QTimer _timer;  
  272. };  
  273.   
  274.   
  275.   
  276. class BlurGeometryUpdateCallback : public osg::Drawable::UpdateCallback  
  277. {  
  278. public:  
  279.     BlurGeometryUpdateCallback(int renderTimes, float inc) : _times(renderTimes), _inc(inc){ }  
  280.   
  281.     void update(osg::NodeVisitor*, osg::Drawable* d)  
  282.     {  
  283.         osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(d);  
  284.         if (!geometry)  
  285.             return;  
  286.           
  287.         osg::Vec2Array *texArray = dynamic_cast<osg::Vec2Array*>(geometry->getTexCoordArray(0));  
  288.         if(!texArray)  
  289.             return;  
  290.           
  291.         osg::Vec4Array *colorArray = dynamic_cast<osg::Vec4Array*>(geometry->getColorArray());  
  292.         if(!colorArray)  
  293.             return;  
  294.   
  295.         float spost = 0.0f;   
  296.         float alphainc = 0.9f / _times;  
  297.         float alpha = 0.2f;  
  298.         alphainc = alpha / _times;  
  299.   
  300.         texArray->clear();  
  301.         colorArray->clear();  
  302.           
  303.         for (int num = 0;num < _times;num++)  
  304.         {  
  305.             colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  306.             texArray->push_back(osg::Vec2(0+spost,1-spost));  
  307.   
  308.             colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  309.             texArray->push_back(osg::Vec2(0+spost,0+spost));  
  310.   
  311.             colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  312.             texArray->push_back(osg::Vec2(1-spost,0+spost));  
  313.   
  314.             colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  315.             texArray->push_back(osg::Vec2(1-spost,1-spost));  
  316.   
  317.             spost += _inc;                    
  318.             alpha = alpha - alphainc;     
  319.         }  
  320.   
  321.         texArray->dirty();  
  322.         colorArray->dirty();  
  323.     }  
  324.   
  325.     int _times;  
  326.     float _inc;  
  327. };  
  328.   
  329.   
  330. osg::Node*  createBlur(int times, float inc)  
  331. {  
  332.     float spost = 0.0f;  
  333.     float alphainc = 0.9f / times;  
  334.     float alpha = 0.2f;  
  335.     alphainc = alpha / times;  
  336.   
  337.     osg::BlendFunc *blendFunc = new osg::BlendFunc(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE);  
  338.     osg::Geode *geode = new osg::Geode;  
  339.     osg::Geometry *geometry = new osg::Geometry;  
  340.     geometry->setUpdateCallback(new BlurGeometryUpdateCallback(times, inc));  
  341.     osg::Vec2Array *vertexArray = new osg::Vec2Array;  
  342.     osg::Vec2Array *texArray = new osg::Vec2Array;  
  343.     osg::Vec4Array *colorArray = new osg::Vec4Array;  
  344.   
  345.     for (int num = 0;num < times;num++)  
  346.     {  
  347.         colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  348.         vertexArray->push_back(osg::Vec2(0,0));  
  349.         texArray->push_back(osg::Vec2(0+spost,1-spost));  
  350.   
  351.         colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  352.         vertexArray->push_back(osg::Vec2(0,480));  
  353.         texArray->push_back(osg::Vec2(0+spost,0+spost));  
  354.   
  355.         colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  356.         vertexArray->push_back(osg::Vec2(640,480));  
  357.         texArray->push_back(osg::Vec2(1-spost,0+spost));  
  358.   
  359.         colorArray->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, alpha));  
  360.         vertexArray->push_back(osg::Vec2(640,0));  
  361.         texArray->push_back(osg::Vec2(1-spost,1-spost));  
  362.     }  
  363.   
  364.     geometry->setVertexArray(vertexArray);  
  365.     geometry->setTexCoordArray(0, texArray, osg::Array::BIND_PER_VERTEX);  
  366.     geometry->setColorArray(colorArray, osg::Array::BIND_PER_VERTEX);  
  367.     geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));  
  368.     geometry->getOrCreateStateSet()->setAttributeAndModes(blendFunc);  
  369.     geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Texture);  
  370.     geometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);  
  371.     geometry->getOrCreateStateSet()->setMode(GL_LIGHT0, osg::StateAttribute::ON);  
  372.     geode->addDrawable(geometry);  
  373.   
  374.     return geode;  
  375. }  
  376.   
  377.   
  378. osg::Camera* createBlurHUD()  
  379. {  
  380.     osg::Camera* camera = new osg::Camera;  
  381.     camera->setProjectionMatrix(osg::Matrix::ortho2D(0,640,0,480));  
  382.     camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);  
  383.     camera->setViewMatrix(osg::Matrix::identity());  
  384.     camera->setRenderOrder(osg::Camera::POST_RENDER);  
  385.     camera->setAllowEventFocus(false);  
  386.   
  387.     camera->addChild(createBlur(25, 0.02f));  
  388.   
  389.     return camera;  
  390. }  
  391.   
  392.   
  393. osg::Texture2D*  createTexture(int w, int h)  
  394. {  
  395.     osg::Texture2D *texture = new osg::Texture2D;  
  396.     texture->setInternalFormat(GL_RGBA);  
  397.     texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  398.     texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  399.     texture->setTextureSize(w,h);  
  400.     return texture;  
  401. }  
  402.   
  403.   
  404. osg::Camera*    createRenderToTextureCamera(int w, int h)  
  405. {  
  406.     osg::Camera *rtt = new osg::Camera;  
  407.     rtt->setClearColor(osg::Vec4(0.0f, 0.0f, 0.5f, 0.5));      
  408.     rtt->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  409.     rtt->setReferenceFrame(osg::Transform::ABSOLUTE_RF);  
  410.     rtt->setViewport(0, 0, w, h);  
  411.     rtt->setRenderOrder(osg::Camera::PRE_RENDER);  
  412.     rtt->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);  
  413.     rtt->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(640)/static_cast<double>(480), 0.1f, 100.0f );  
  414.     rtt->setViewMatrixAsLookAt(osg::Vec3d(0, 5, 50), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  415.   
  416.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  417.     zoomMT->setMatrix(osg::Matrix::translate(0,0,-50));  
  418.     osg::MatrixTransform *xRotMT = new osg::MatrixTransform;  
  419.     xRotMT->addUpdateCallback(new RotAxisCallback(osg::X_AXIS, 0.02));  
  420.     osg::MatrixTransform *yRotMT = new osg::MatrixTransform;  
  421.     yRotMT->addUpdateCallback(new RotAxisCallback(osg::Y_AXIS, 0.01));  
  422.   
  423.     zoomMT->addChild(xRotMT);  
  424.     xRotMT->addChild(yRotMT);  
  425.     yRotMT->addChild(createHelix());  
  426.   
  427.     rtt->addChild(zoomMT);  
  428.       
  429.     return rtt;  
  430. }  
  431.   
  432.   
  433.   
  434. osg::Node*  buildScene()  
  435. {  
  436.     GLfloat light0pos[4]=     {0.0f, 5.0f, 10.0f, 1.0f};  
  437.     GLfloat light0ambient[4]= {0.2f, 0.2f,  0.2f, 1.0f};  
  438.     GLfloat light0diffuse[4]= {0.3f, 0.3f,  0.3f, 1.0f};  
  439.     GLfloat light0specular[4]={0.8f, 0.8f,  0.8f, 1.0f};      
  440.   
  441.     osg::Group *root = new osg::Group;  
  442.       
  443.     osg::Light *light = new osg::Light;  
  444.     light->setLightNum(0);  
  445.     light->setAmbient(osg::Vec4(light0ambient[0],light0ambient[1],light0ambient[2],light0ambient[3]));  
  446.     light->setDiffuse(osg::Vec4(light0diffuse[0],light0diffuse[1],light0diffuse[2],light0diffuse[3]));  
  447.     light->setPosition(osg::Vec4(light0pos[0], light0pos[1],light0pos[2],light0pos[3]));  
  448.     light->setSpecular(osg::Vec4(light0specular[0],light0specular[1],light0specular[2],light0specular[3]));  
  449.     osg::LightSource *lightSource = new osg::LightSource;  
  450.     lightSource->setLight(light);  
  451.     root->addChild(lightSource);  
  452.   
  453.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  454.     zoomMT->setMatrix(osg::Matrix::translate(0,0,-50));  
  455.     osg::MatrixTransform *xRotMT = new osg::MatrixTransform;  
  456.     xRotMT->addUpdateCallback(new RotAxisCallback(osg::X_AXIS, 0.02));  
  457.     osg::MatrixTransform *yRotMT = new osg::MatrixTransform;  
  458.     yRotMT->addUpdateCallback(new RotAxisCallback(osg::Y_AXIS, 0.01));  
  459.       
  460.     zoomMT->addChild(xRotMT);  
  461.     xRotMT->addChild(yRotMT);  
  462.     yRotMT->addChild(createHelix());  
  463.   
  464.   
  465.     g_Texture = createTexture(128,128);  
  466.     osg::Camera *rttCamera = createRenderToTextureCamera(128, 128);  
  467.     rttCamera->attach(osg::Camera::COLOR_BUFFER, g_Texture);  
  468.     root->addChild(rttCamera);  
  469.     root->addChild(zoomMT);  
  470.     root->addChild(createBlurHUD());  
  471.       
  472.     return root;  
  473. }  
  474.   
  475.   
  476.   
  477. int main( int argc, char** argv )  
  478. {  
  479.     QApplication app(argc, argv);  
  480.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  481.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  482.     viewWidget->show();  
  483.     return app.exec();  
  484. }  
0 0
原创粉丝点击