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

  • 简介

这节课NeHe教我们怎样把图片作为资源嵌入到exe可执行文件中,这样当我们发布程序的时候就可以不需要附带上图片文件了。由于这部分的内容和OSG并没有关系,主要是使用Windows编程中资源的概念,我对这部分并不是很熟悉,因此本课只实现最后的效果。图片并未处理成NeHe中的这种方式。

  • 实现

首先创建我们需要的50只蝴蝶的模型,并且加载需要的纹理

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. void initialize()  
  2. {  
  3.     for (int loop=0; loop<50; loop++)  
  4.     {  
  5.         setObject(loop);  
  6.     }  
  7.   
  8.     g_Tex1 = new osg::Texture2D;  
  9.     g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  10.     g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  11.     g_Tex1->setImage(osgDB::readImageFile("Data/Butterfly1.bmp"));  
  12.   
  13.     g_Tex2 = new osg::Texture2D;  
  14.     g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  15.     g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  16.     g_Tex2->setImage(osgDB::readImageFile("Data/Butterfly2.bmp"));  
  17.   
  18.     g_Tex3 = new osg::Texture2D;  
  19.     g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  20.     g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  21.     g_Tex3->setImage(osgDB::readImageFile("Data/Butterfly3.bmp"));  
  22. }  
接下来把蝴蝶添加到组节点中,并设置每只蝴蝶的位置回调函数,更新它们的位置

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Group*     createButterflyGroup()  
在回调中写下蝴蝶的位置变化以及旋转变化等:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class ButterFlyGroupCallback : public osg::NodeCallback  
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. class TranslateUpdateCallback : public osg::NodeCallback  
这些内容前面的课程中已经重复很多次了,相信不难理解,具体代码参见后面的附录部分:

将所有这些部分添加到场景根节点下,编译运行程序:


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

[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/PolygonMode>  
  13. #include <osg/Texture2D>  
  14. #include <osg/BlendFunc>  
  15.   
  16. osg::Texture2D *g_Tex1, *g_Tex2, *g_Tex3;  
  17.   
  18. struct object  
  19. {  
  20.     int   tex;  
  21.     float x;  
  22.     float y;  
  23.     float z;  
  24.     float yi;  
  25.     float spinz;  
  26.     float spinzi;  
  27.     float flap;  
  28.     float fi;  
  29. };  
  30.   
  31. object obj[50];  
  32.   
  33. void setObject(int loop)  
  34. {  
  35.     obj[loop].tex=rand()%3;  
  36.     obj[loop].x=rand()%34-17.0f;  
  37.     obj[loop].y=18.0f;  
  38.     obj[loop].z=-((rand()%30000/1000.0f)+10.0f);  
  39.     obj[loop].spinzi=(rand()%10000)/5000.0f-1.0f;  
  40.     obj[loop].flap=0.0f;      
  41.     obj[loop].fi=0.05f+(rand()%100)/1000.0f;      
  42.     obj[loop].yi=0.001f+(rand()%1000)/10000.0f;  
  43. }  
  44.   
  45.   
  46. void initialize()  
  47. {  
  48.     for (int loop=0; loop<50; loop++)  
  49.     {  
  50.         setObject(loop);  
  51.     }  
  52.   
  53.     g_Tex1 = new osg::Texture2D;  
  54.     g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  55.     g_Tex1->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  56.     g_Tex1->setImage(osgDB::readImageFile("Data/Butterfly1.bmp"));  
  57.   
  58.     g_Tex2 = new osg::Texture2D;  
  59.     g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  60.     g_Tex2->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  61.     g_Tex2->setImage(osgDB::readImageFile("Data/Butterfly2.bmp"));  
  62.   
  63.     g_Tex3 = new osg::Texture2D;  
  64.     g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  65.     g_Tex3->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);  
  66.     g_Tex3->setImage(osgDB::readImageFile("Data/Butterfly3.bmp"));  
  67. }  
  68.   
  69.   
  70. class ButterflyUpdateCallback : public osg::Drawable::UpdateCallback  
  71. {  
  72. public:  
  73.     ButterflyUpdateCallback(int index, int texIndex) : _index(index), _texIndex(texIndex)  
  74.     {  
  75.         //NOP  
  76.     }  
  77.   
  78.     virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)  
  79.     {  
  80.         osg::Geometry *geometry = dynamic_cast<osg::Geometry*>(drawable);  
  81.         if(!geometry)  
  82.             return;  
  83.   
  84.         osg::Vec3Array *vertexArray = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());  
  85.         if (!vertexArray)  
  86.             return;  
  87.   
  88.         vertexArray->clear();  
  89.         vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));  
  90.         vertexArray->push_back(osg::Vec3(-1.0f, 1.0f, obj[_index].flap));  
  91.         vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));  
  92.         vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));  
  93.         vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));  
  94.         vertexArray->push_back(osg::Vec3(1.0f,-1.0f, obj[_index].flap));  
  95.         vertexArray->dirty();  
  96.         geometry->setVertexArray(vertexArray);  
  97.   
  98.         if (!geometry->getOrCreateStateSet()->getTextureAttribute(0, osg::StateAttribute::TEXTURE))  
  99.         {  
  100.             if (_texIndex == 0 )  
  101.             {  
  102.                 geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Tex1);  
  103.             }  
  104.             if (_texIndex == 1)  
  105.             {  
  106.                 geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Tex2);  
  107.             }  
  108.             if (_texIndex == 2)  
  109.             {  
  110.                 geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, g_Tex3);  
  111.             }  
  112.         }  
  113.     }  
  114.   
  115.     int _index;  
  116.     int _texIndex;  
  117. };  
  118.   
  119.   
  120. class RotateUpdateCallback : public osg::NodeCallback  
  121. {  
  122. public:  
  123.     RotateUpdateCallback(int index) : _index(index){ }  
  124.   
  125.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  126.     {  
  127.         osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);  
  128.         if (!mt)  
  129.             return;  
  130.         mt->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(obj[_index].spinz), osg::Z_AXIS));  
  131.   
  132.         traverse(node, nv);  
  133.     }  
  134.   
  135.     int _index;  
  136. };  
  137.   
  138.   
  139. class TranslateUpdateCallback : public osg::NodeCallback  
  140. {  
  141. public:  
  142.     TranslateUpdateCallback(int index) : _index(index){}  
  143.   
  144.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  145.     {  
  146.         osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);  
  147.         if (!mt)  
  148.             return;  
  149.         mt->setMatrix(osg::Matrix::translate(obj[_index].x,obj[_index].y,obj[_index].z));  
  150.   
  151.         traverse(node, nv);  
  152.     }  
  153.   
  154.     int _index;  
  155. };  
  156.   
  157.   
  158. class ButterFlyGroupCallback : public osg::NodeCallback  
  159. {  
  160. public:  
  161.     ButterFlyGroupCallback(){}  
  162.   
  163.     virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)  
  164.     {  
  165.         for (int loop = 0; loop < 50; ++loop)  
  166.         {  
  167.             obj[loop].y-=obj[loop].yi;  
  168.             obj[loop].spinz+=obj[loop].spinzi;  
  169.             obj[loop].flap+=obj[loop].fi;  
  170.   
  171.             if (obj[loop].y<-18.0f)  
  172.             {  
  173.                 setObject(loop);  
  174.             }  
  175.   
  176.             if ((obj[loop].flap>1.0f) || (obj[loop].flap<-1.0f))  
  177.             {  
  178.                 obj[loop].fi=-obj[loop].fi;  
  179.             }  
  180.         }  
  181.         traverse(node, nv);  
  182.     }  
  183. };  
  184.   
  185.   
  186.   
  187. osg::Group*     createButterflyGroup()  
  188. {  
  189.     osg::Group *butterflyGroup = new osg::Group;  
  190.     butterflyGroup->addUpdateCallback(new ButterFlyGroupCallback);  
  191.   
  192.     for (int loop = 0; loop < 50; ++loop)  
  193.     {  
  194.         osg::MatrixTransform *zoomMT = new osg::MatrixTransform;  
  195.         zoomMT->setMatrix(osg::Matrix::translate(obj[loop].x,obj[loop].y,obj[loop].z));  
  196.         zoomMT->addUpdateCallback(new TranslateUpdateCallback(loop));  
  197.         osg::MatrixTransform *rotateX = new osg::MatrixTransform;  
  198.         rotateX->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(45.0), osg::X_AXIS));  
  199.         osg::MatrixTransform *rotateZ = new osg::MatrixTransform;  
  200.         rotateZ->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(obj[loop].spinz), osg::Z_AXIS));  
  201.         rotateZ->addUpdateCallback(new RotateUpdateCallback(loop));  
  202.   
  203.         osg::Geode *butterflyGeode = new osg::Geode;  
  204.         osg::Geometry *butterGeometry = new osg::Geometry;  
  205.         butterGeometry->setUpdateCallback(new ButterflyUpdateCallback(loop, obj[loop].tex));  
  206.         osg::Vec3Array *vertexArray = new osg::Vec3Array;  
  207.         osg::Vec2Array *texArray = new osg::Vec2Array;  
  208.   
  209.         vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));  
  210.         vertexArray->push_back(osg::Vec3(-1.0f, 1.0f, obj[loop].flap));  
  211.         vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));  
  212.         vertexArray->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));  
  213.         vertexArray->push_back(osg::Vec3(-1.0f,-1.0f, 0.0f));  
  214.         vertexArray->push_back(osg::Vec3(1.0f,-1.0f, obj[loop].flap));  
  215.   
  216.         texArray->push_back(osg::Vec2(1.0f,1.0f));  
  217.         texArray->push_back(osg::Vec2(0.0f,1.0f));  
  218.         texArray->push_back(osg::Vec2(0.0f,0.0f));  
  219.         texArray->push_back(osg::Vec2(1.0f,1.0f));  
  220.         texArray->push_back(osg::Vec2(0.0f, 0.0f));  
  221.         texArray->push_back(osg::Vec2(1.0f,0.0f));  
  222.   
  223.         butterGeometry->setVertexArray(vertexArray);  
  224.         butterGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertexArray->size()));  
  225.         butterGeometry->setTexCoordArray(0, texArray, osg::Array::BIND_PER_VERTEX);  
  226.         butterGeometry->getOrCreateStateSet()->setMode(GL_LIGHTING, false);  
  227.         osg::BlendFunc *blendFunc = new osg::BlendFunc(osg::BlendFunc::ONE, osg::BlendFunc::SRC_ALPHA);  
  228.         butterGeometry->getOrCreateStateSet()->setAttributeAndModes(blendFunc);  
  229.         butterGeometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, false);  
  230.   
  231.         butterflyGeode->addDrawable(butterGeometry);  
  232.         butterflyGroup->addChild(zoomMT);  
  233.         zoomMT->addChild(rotateX);  
  234.         rotateX->addChild(rotateZ);  
  235.         rotateZ->addChild(butterflyGeode);  
  236.     }  
  237.       
  238.     return butterflyGroup;  
  239. }  
  240.   
  241.   
  242.   
  243. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  244. {  
  245. public:  
  246.     ViewerWidget(osg::Node *scene = NULL)  
  247.     {  
  248.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,640,480), scene);  
  249.   
  250.         QVBoxLayout* layout = new QVBoxLayout;  
  251.         layout->addWidget(renderWidget);  
  252.         layout->setContentsMargins(0, 0, 0, 1);  
  253.         setLayout( layout );  
  254.   
  255.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  256.         _timer.start( 10 );  
  257.     }  
  258.   
  259.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  260.     {  
  261.         osg::Camera* camera = this->getCamera();  
  262.         camera->setGraphicsContext( gw );  
  263.   
  264.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  265.   
  266.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 0.5) );  
  267.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  268.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );          
  269.         camera->setViewMatrixAsLookAt(osg::Vec3d(0.0f, 25.0f, -45.0f), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  270.   
  271.         this->setSceneData( scene );  
  272.   
  273.         return gw->getGLWidget();  
  274.     }  
  275.   
  276.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  277.     {  
  278.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  279.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  280.         traits->windowName = name;  
  281.         traits->windowDecoration = windowDecoration;  
  282.         traits->x = x;  
  283.         traits->y = y;  
  284.         traits->width = w;  
  285.         traits->height = h;  
  286.         traits->doubleBuffer = true;  
  287.         traits->alpha = ds->getMinimumNumAlphaBits();  
  288.         traits->stencil = ds->getMinimumNumStencilBits();  
  289.         traits->sampleBuffers = ds->getMultiSamples();  
  290.         traits->samples = ds->getNumMultiSamples();  
  291.   
  292.         return new osgQt::GraphicsWindowQt(traits.get());  
  293.     }  
  294.   
  295.     virtual void paintEvent( QPaintEvent* event )  
  296.     {   
  297.         frame();   
  298.     }  
  299.   
  300. protected:  
  301.   
  302.     QTimer _timer;  
  303. };  
  304.   
  305.   
  306.   
  307. osg::Node*  buildScene()  
  308. {  
  309.     initialize();  
  310.   
  311.     osg::Group *root = new osg::Group;  
  312.     root->addChild(createButterflyGroup());  
  313.     return root;  
  314. }  
  315.   
  316.   
  317.   
  318. int main( int argc, char** argv )  
  319. {  
  320.     QApplication app(argc, argv);  
  321.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  322.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  323.     viewWidget->show();  
  324.     return app.exec();  
  325. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值