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

  • 简介

这节课我们将学习使用环境纹理映射。这种映射方式可以让物体表面看上去像镜子一样反射周围的环境。这节课的代码是在前面第十八节课程的基础上修改的。

  • 实现

本课的实现过程十分的简单,在几何体的生成中添加一个环境纹理osg::TexGen属性即可。

首先创建背景几何体

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Group* createBackGroup()  
  2. {  
  3.     osg::Group *backGroup = new osg::Group;  
  4.     osg::Geode* bgGeode = new osg::Geode;  
  5.     osg::Geometry *bgGeometry = new osg::Geometry;  
  6.   
  7.     osg::Vec3Array *verticesArray = new osg::Vec3Array;  
  8.     verticesArray->push_back(osg::Vec3(-13.3f, -10.0f,  10.0f));  
  9.     verticesArray->push_back(osg::Vec3(13.3f, -10.0f,  10.0f));  
  10.     verticesArray->push_back(osg::Vec3(13.3f,  10.0f,  10.0f));  
  11.     verticesArray->push_back(osg::Vec3(-13.3f,  10.0f,  10.0f));  
  12.     osg::Vec3Array *verticesNormal = new osg::Vec3Array;  
  13.     verticesNormal->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));  
  14.     osg::Vec2Array *texArray = new osg::Vec2Array;  
  15.     texArray->push_back(osg::Vec2(0.0f, 0.0f));  
  16.     texArray->push_back(osg::Vec2(1.0f, 0.0f));  
  17.     texArray->push_back(osg::Vec2(1.0f, 1.0f));  
  18.     texArray->push_back(osg::Vec2(0.0f, 1.0f));  
  19.   
  20.     osg::Texture2D *texture = new osg::Texture2D;  
  21.     texture->setImage(osgDB::readImageFile("Data/BG.bmp"));  
  22.     texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  23.     texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  24.   
  25.     bgGeometry->setVertexArray(verticesArray);  
  26.     bgGeometry->setNormalArray(verticesNormal, osg::Array::BIND_OVERALL);  
  27.     bgGeometry->setTexCoordArray(0, texArray);  
  28.     bgGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  29.     bgGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);  
  30.   
  31.     bgGeode->addDrawable(bgGeometry);  
  32.   
  33.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  34.     zoomMT->setMatrix(osg::Matrix::translate(0, 0, -24));  
  35.   
  36.     backGroup->addChild(zoomMT);  
  37.     zoomMT->addChild(bgGeode);  
  38.   
  39.     return backGroup;  
  40. }  
接着给几何体添加TexGen的属性,按照NeHe课程中的设置:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::TexGen *texGen = new osg::TexGen;  
  2. texGen->setMode(osg::TexGen::SPHERE_MAP);  
  3. g_Switch->getOrCreateStateSet()->setTextureAttributeAndModes(0, texGen);  

这里我们将节点的属性设置给它的父节点,默认情况下子节点会继承父节点的属性,我们也可以强制使用osg::StateAttribute::OVERRIDE设置。

接下来将两个节点添加到场景中:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. quadYRotMT->addChild(g_Switch);  
  2. quadXRotMT->addChild(quadYRotMT);  
  3. quadMT->addChild(quadXRotMT);  
  4.   
  5. root->addChild(quadMT);  
  6. root->addChild(createBackGroup());  
编译运行程序:


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

[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/NodeVisitor>  
  13. #include <osg/Texture2D>  
  14.   
  15. #include <osgGA/GUIEventAdapter>  
  16.   
  17. #include <osg/Light>  
  18. #include <osg/LightModel>  
  19. #include <osg/LightSource>  
  20.   
  21. #include <osg/ShapeDrawable>  
  22. #include <osg/Switch>  
  23.   
  24. #include <osg/TexGen>  
  25.   
  26.   
  27. //  
  28. //开关节点  
  29. osg::Switch     *g_Switch;  
  30.   
  31. //  
  32. //FindFirstNamedNodeVisitor用来遍历寻找与指定名称相同的节点  
  33.   
  34. class FindFirstNamedNodeVisitor : public osg::NodeVisitor  
  35. {  
  36. public:  
  37.     FindFirstNamedNodeVisitor(const std::string& name):  
  38.       osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),  
  39.           _name(name), _foundNode(NULL) {}  
  40.   
  41.       virtual void apply(osg::Node& node)  
  42.       {  
  43.           if (node.getName()==_name)  
  44.           {  
  45.               _foundNode = &node;  
  46.               return;  
  47.           }  
  48.           traverse(node);  
  49.       }  
  50.   
  51.       std::string _name;  
  52.       osg::Node *_foundNode;  
  53. };  
  54.   
  55. //  
  56. //RotateCallback  
  57.   
  58. class RotateCallback : public osg::NodeCallback  
  59. {  
  60.   
  61. public:  
  62.     RotateCallback(osg::Vec3d rotateAxis, double rotateSpeed) :   
  63.       osg::NodeCallback(),  
  64.           _rotateAxis(rotateAxis),   
  65.           _rotateSpeed(rotateSpeed),  
  66.           _rotateAngle(0.0)  
  67.       {  
  68.           //Nop  
  69.       }  
  70.   
  71.       void setRotateSpeed(double speed)  
  72.       {  
  73.           _rotateSpeed = speed;  
  74.       }  
  75.   
  76.       double getRotateSpeed() const  
  77.       {  
  78.           return _rotateSpeed;  
  79.       }  
  80.   
  81.       virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  82.       {  
  83.           osg::MatrixTransform *currentMT = dynamic_cast<osg::MatrixTransform*>(node);  
  84.           if (currentMT)  
  85.           {  
  86.               //获取当前的平移位置  
  87.               osg::Vec3d currentTranslate = currentMT->getMatrix().getTrans();  
  88.               osg::Matrix newMatrix = osg::Matrix::rotate(_rotateAngle, _rotateAxis) * osg::Matrix::translate(currentTranslate);  
  89.               currentMT->setMatrix(newMatrix);  
  90.               _rotateAngle += _rotateSpeed;  
  91.           }  
  92.   
  93.           traverse(node, nv);  
  94.       }  
  95.   
  96.   
  97. private:  
  98.     osg::Vec3d _rotateAxis;         //旋转轴  
  99.     double        _rotateSpeed;     //旋转速度  
  100.     double        _rotateAngle;     //当前旋转的角度  
  101. };  
  102.   
  103.   
  104.   
  105.   
  106. //  
  107.   
  108. class ManipulatorSceneHandler : public osgGA::GUIEventHandler  
  109. {  
  110. public:  
  111.     ManipulatorSceneHandler()  
  112.     {  
  113.     }  
  114.   
  115.     virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)  
  116.     {  
  117.         osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);  
  118.         if (!viewer)  
  119.             return false;  
  120.         if (!viewer->getSceneData())  
  121.             return false;  
  122.         if (ea.getHandled())   
  123.             return false;  
  124.   
  125.         osg::Group *root = viewer->getSceneData()->asGroup();  
  126.   
  127.         switch(ea.getEventType())  
  128.         {  
  129.         case(osgGA::GUIEventAdapter::KEYDOWN):  
  130.             {  
  131.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)  
  132.                 {  
  133.                     FindFirstNamedNodeVisitor fnv("yRotMT");  
  134.                     root->accept(fnv);  
  135.   
  136.                     osg::Node *mtNode = fnv._foundNode;  
  137.                     osg::MatrixTransform *yRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  138.                     if (!yRotMT)  
  139.                         return false;  
  140.   
  141.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(yRotMT->getUpdateCallback());  
  142.   
  143.                     if (!rotCallback)  
  144.                         return false;  
  145.   
  146.                     double speed = rotCallback->getRotateSpeed();  
  147.                     speed += 0.02;  
  148.                     rotCallback->setRotateSpeed(speed);  
  149.   
  150.                 }  
  151.   
  152.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)  
  153.                 {  
  154.                     FindFirstNamedNodeVisitor fnv("yRotMT");  
  155.                     root->accept(fnv);  
  156.   
  157.                     osg::Node *mtNode = fnv._foundNode;  
  158.                     osg::MatrixTransform *yRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  159.                     if (!yRotMT)  
  160.                         return false;  
  161.   
  162.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(yRotMT->getUpdateCallback());  
  163.   
  164.                     if (!rotCallback)  
  165.                         return false;  
  166.   
  167.                     double speed = rotCallback->getRotateSpeed();  
  168.                     speed -= 0.02;  
  169.                     rotCallback->setRotateSpeed(speed);  
  170.                 }  
  171.   
  172.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)  
  173.                 {  
  174.                     FindFirstNamedNodeVisitor fnv("xRotMT");  
  175.                     root->accept(fnv);  
  176.   
  177.                     osg::Node *mtNode = fnv._foundNode;  
  178.                     osg::MatrixTransform *xRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  179.                     if (!xRotMT)  
  180.                         return false;  
  181.   
  182.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(xRotMT->getUpdateCallback());  
  183.   
  184.                     if (!rotCallback)  
  185.                         return false;  
  186.   
  187.                     double speed = rotCallback->getRotateSpeed();  
  188.                     speed += 0.02;  
  189.                     rotCallback->setRotateSpeed(speed);  
  190.                 }  
  191.   
  192.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Down)  
  193.                 {  
  194.                     FindFirstNamedNodeVisitor fnv("xRotMT");  
  195.                     root->accept(fnv);  
  196.   
  197.                     osg::Node *mtNode = fnv._foundNode;  
  198.                     osg::MatrixTransform *xRotMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  199.                     if (!xRotMT)  
  200.                         return false;  
  201.   
  202.                     RotateCallback *rotCallback = dynamic_cast<RotateCallback*>(xRotMT->getUpdateCallback());  
  203.   
  204.                     if (!rotCallback)  
  205.                         return false;  
  206.   
  207.                     double speed = rotCallback->getRotateSpeed();  
  208.                     speed -= 0.02;  
  209.                     rotCallback->setRotateSpeed(speed);  
  210.                 }  
  211.   
  212.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Up)  
  213.                 {     
  214.                     FindFirstNamedNodeVisitor fnv("zoomMT");  
  215.                     root->accept(fnv);  
  216.   
  217.                     osg::Node *mtNode = fnv._foundNode;  
  218.                     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  219.                     if (!zoomMT)  
  220.                         return false;  
  221.   
  222.                     osg::Vec3 trans = zoomMT->getMatrix().getTrans();  
  223.                     trans.set(trans.x(), trans.y(), trans.z() + 0.2);  
  224.                     zoomMT->setMatrix(osg::Matrix::translate(trans));  
  225.                 }  
  226.   
  227.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_Page_Down)  
  228.                 {  
  229.                     FindFirstNamedNodeVisitor fnv("zoomMT");  
  230.                     root->accept(fnv);  
  231.   
  232.                     osg::Node *mtNode = fnv._foundNode;  
  233.                     osg::MatrixTransform *zoomMT = dynamic_cast<osg::MatrixTransform*>(mtNode);  
  234.                     if (!zoomMT)  
  235.                         return false;  
  236.   
  237.                     osg::Vec3 trans = zoomMT->getMatrix().getTrans();  
  238.                     trans.set(trans.x(), trans.y(), trans.z() - 0.2);  
  239.                     zoomMT->setMatrix(osg::Matrix::translate(trans));  
  240.                 }  
  241.   
  242.                 if (ea.getKey()== osgGA::GUIEventAdapter::KEY_L)  
  243.                 {  
  244.                     static int i = 0;  
  245.                     if (i % 2 == 0) {  
  246.                         root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  247.                     } else {  
  248.                         root->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON);  
  249.                     }  
  250.                     ++i;  
  251.                 }  
  252.                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)  
  253.                 {  
  254.                     static int index = 0;  
  255.                     g_Switch->setSingleChildOn(++index % 4);  
  256.                 }  
  257.   
  258.             }  
  259.         defaultbreak;  
  260.         }  
  261.         return false;  
  262.     }  
  263. };  
  264.   
  265. //  
  266.   
  267. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  268. {  
  269. public:  
  270.     ViewerWidget(osg::Node *scene = NULL)  
  271.     {  
  272.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  273.   
  274.         QVBoxLayout* layout = new QVBoxLayout;  
  275.         layout->addWidget(renderWidget);  
  276.         layout->setContentsMargins(0, 0, 0, 1);  
  277.         setLayout( layout );  
  278.   
  279.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  280.         _timer.start( 10 );  
  281.     }  
  282.   
  283.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  284.     {  
  285.         osg::Camera* camera = this->getCamera();  
  286.         camera->setGraphicsContext( gw );  
  287.   
  288.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  289.   
  290.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  291.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  292.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  293.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  294.   
  295.         osg::StateSet* globalStateset = camera->getStateSet();  
  296.         if (globalStateset)  
  297.         {  
  298.             osg::LightModel* lightModel = new osg::LightModel;  
  299.             lightModel->setAmbientIntensity(osg::Vec4(0,0,0,0));  
  300.             globalStateset->setAttributeAndModes(lightModel, osg::StateAttribute::ON);  
  301.         }  
  302.   
  303.         this->setSceneData( scene );  
  304.         this->addEventHandler(new ManipulatorSceneHandler());  
  305.   
  306.         return gw->getGLWidget();  
  307.     }  
  308.   
  309.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  310.     {  
  311.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  312.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  313.         traits->windowName = name;  
  314.         traits->windowDecoration = windowDecoration;  
  315.         traits->x = x;  
  316.         traits->y = y;  
  317.         traits->width = w;  
  318.         traits->height = h;  
  319.         traits->doubleBuffer = true;  
  320.         traits->alpha = ds->getMinimumNumAlphaBits();  
  321.         traits->stencil = ds->getMinimumNumStencilBits();  
  322.         traits->sampleBuffers = ds->getMultiSamples();  
  323.         traits->samples = ds->getNumMultiSamples();  
  324.   
  325.         return new osgQt::GraphicsWindowQt(traits.get());  
  326.     }  
  327.   
  328.     virtual void paintEvent( QPaintEvent* event )  
  329.     {   
  330.         frame();   
  331.     }  
  332.   
  333. protected:  
  334.   
  335.     QTimer _timer;  
  336. };  
  337.   
  338. osg::Group* createBackGroup()  
  339. {  
  340.     osg::Group *backGroup = new osg::Group;  
  341.     osg::Geode* bgGeode = new osg::Geode;  
  342.     osg::Geometry *bgGeometry = new osg::Geometry;  
  343.   
  344.     osg::Vec3Array *verticesArray = new osg::Vec3Array;  
  345.     verticesArray->push_back(osg::Vec3(-13.3f, -10.0f,  10.0f));  
  346.     verticesArray->push_back(osg::Vec3(13.3f, -10.0f,  10.0f));  
  347.     verticesArray->push_back(osg::Vec3(13.3f,  10.0f,  10.0f));  
  348.     verticesArray->push_back(osg::Vec3(-13.3f,  10.0f,  10.0f));  
  349.     osg::Vec3Array *verticesNormal = new osg::Vec3Array;  
  350.     verticesNormal->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));  
  351.     osg::Vec2Array *texArray = new osg::Vec2Array;  
  352.     texArray->push_back(osg::Vec2(0.0f, 0.0f));  
  353.     texArray->push_back(osg::Vec2(1.0f, 0.0f));  
  354.     texArray->push_back(osg::Vec2(1.0f, 1.0f));  
  355.     texArray->push_back(osg::Vec2(0.0f, 1.0f));  
  356.   
  357.     osg::Texture2D *texture = new osg::Texture2D;  
  358.     texture->setImage(osgDB::readImageFile("Data/BG.bmp"));  
  359.     texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  360.     texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);  
  361.   
  362.     bgGeometry->setVertexArray(verticesArray);  
  363.     bgGeometry->setNormalArray(verticesNormal, osg::Array::BIND_OVERALL);  
  364.     bgGeometry->setTexCoordArray(0, texArray);  
  365.     bgGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));  
  366.     bgGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);  
  367.   
  368.     bgGeode->addDrawable(bgGeometry);  
  369.   
  370.     osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  371.     zoomMT->setMatrix(osg::Matrix::translate(0, 0, -24));  
  372.   
  373.     backGroup->addChild(zoomMT);  
  374.     zoomMT->addChild(bgGeode);  
  375.   
  376.     return backGroup;  
  377. }  
  378.   
  379. osg::Node*  buildScene()  
  380. {  
  381.     osg::Group *root = new osg::Group;  
  382.   
  383.     osg::Light* light = new osg::Light();  
  384.     light->setLightNum(0);  
  385.     light->setAmbient(osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f));  
  386.     light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));  
  387.     light->setPosition(osg::Vec4(0.0f, 0.0f, 2.0f, 1.0f));  
  388.     osg::LightSource* lightsource = new osg::LightSource();  
  389.     lightsource->setLight (light);  
  390.     root->addChild (lightsource);   
  391.   
  392.     osg::MatrixTransform *quadMT = new osg::MatrixTransform;  
  393.     quadMT->setName("zoomMT");  
  394.     quadMT->setMatrix(osg::Matrix::translate(0.0, 0.0, -5.0));  
  395.   
  396.     osg::MatrixTransform *quadXRotMT = new osg::MatrixTransform;  
  397.     quadXRotMT->setName("xRotMT");  
  398.     RotateCallback *xRotCallback = new RotateCallback(osg::X_AXIS, 0.0);  
  399.     quadXRotMT->setUpdateCallback(xRotCallback);  
  400.   
  401.   
  402.     osg::MatrixTransform *quadYRotMT = new osg::MatrixTransform;  
  403.     quadYRotMT->setName("yRotMT");  
  404.     RotateCallback *yRotCallback = new RotateCallback(osg::Y_AXIS, 0.0);  
  405.     quadYRotMT->setUpdateCallback(yRotCallback);  
  406.   
  407.     //  
  408.     //新增代码,使用开关节点管理  
  409.     g_Switch = new osg::Switch;  
  410.   
  411.     //添加立方体  
  412.     osg::Geode *box = new osg::Geode;  
  413.     osg::ShapeDrawable *boxDrawable = new osg::ShapeDrawable;  
  414.     osg::Box *boxShape = new osg::Box(osg::Vec3(0, 0,0), 2);  
  415.     boxDrawable->setShape(boxShape);  
  416.     box->addDrawable(boxDrawable);  
  417.     g_Switch->addChild(box);  
  418.   
  419.     //添加圆柱体  
  420.     osg::Geode *cylinder = new osg::Geode;  
  421.     osg::ShapeDrawable *cylinderDrawable = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0,0,0), 0.5, 2.0));  
  422.     cylinder->addDrawable(cylinderDrawable);  
  423.     g_Switch->addChild(cylinder);  
  424.   
  425.     //添加圆球  
  426.     osg::Geode *sphere = new osg::Geode;  
  427.     osg::ShapeDrawable *sphereDrawable = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0,0,0), 1.3));  
  428.     sphere->addDrawable(sphereDrawable);  
  429.     g_Switch->addChild(sphere);  
  430.   
  431.     //添加圆锥  
  432.     osg::Geode *cone = new osg::Geode;  
  433.     osg::ShapeDrawable *coneDrawable = new osg::ShapeDrawable(new osg::Cone(osg::Vec3(0,0,0), 0.5, 2));  
  434.     cone->addDrawable(coneDrawable);  
  435.     g_Switch->addChild(cone);  
  436.   
  437.     g_Switch->setSingleChildOn(0);  
  438.     //  
  439.   
  440.     osg::Image *textureImage = osgDB::readImageFile("Data/Reflect.bmp");  
  441.     osg::Texture2D *texture2D = new osg::Texture2D;  
  442.     texture2D->setImage(textureImage);  
  443.     texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);  
  444.     texture2D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);  
  445.     g_Switch->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D);  
  446.   
  447.     osg::TexGen *texGen = new osg::TexGen;  
  448.     texGen->setMode(osg::TexGen::SPHERE_MAP);  
  449.     g_Switch->getOrCreateStateSet()->setTextureAttributeAndModes(0, texGen);  
  450.   
  451.     quadYRotMT->addChild(g_Switch);  
  452.     quadXRotMT->addChild(quadYRotMT);  
  453.     quadMT->addChild(quadXRotMT);  
  454.   
  455.     root->addChild(quadMT);  
  456.     root->addChild(createBackGroup());  
  457.   
  458.     return root;  
  459. }  
  460.   
  461.   
  462. int main( int argc, char** argv )  
  463. {  
  464.     QApplication app(argc, argv);  
  465.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  466.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  467.     viewWidget->show();  
  468.     return app.exec();  
  469. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值