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

  • 简介

这节课将在第四课的基础上进行扩展,创建3D物体。我们将三角形变为3D的三棱锥形,把四边形变为立方体。同时三棱锥沿Y轴旋转,四边形沿着(1,1,1)方向旋转。

  • 实现

本课与第二课十分类似,只需要多绘制几个面即可,三棱锥的绘制代码如下

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Geometry *triangleGeometry = new osg::Geometry;  
  2. osg::Vec3Array *triangleVertexArray = new osg::Vec3Array;  
  3. for (unsigned i = 0; i < sizeof(TriangleVertices); ++i)  
  4. {  
  5.     triangleVertexArray->push_back(osg::Vec3(TriangleVertices[i][0], TriangleVertices[i][1], TriangleVertices[i][2]));  
  6. }  
  7. triangleGeometry->setVertexArray(triangleVertexArray);  
  8. osg::Vec4Array *triangleColorArray = new osg::Vec4Array;  
  9. for (unsigned i = 0; i < sizeof(TriangleColors); ++i)  
  10. {  
  11.     triangleColorArray->push_back(osg::Vec4(TriangleColors[i][0], TriangleColors[i][1], TriangleColors[i][2], 1.0f));  
  12. }  
  13. triangleGeometry->setColorArray(triangleColorArray);  
  14. triangleGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);  
  15. triangleGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, 12));  
在这里需要注意在DrawArrays类的构造函数需要将第三个参数修改为所有Vertex的总数,即12个

以下是立方体的绘制代码

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Geometry *quadGeometry = new osg::Geometry;  
  2. osg::Vec3Array *quadVertexArray = new osg::Vec3Array;  
  3. for (unsigned i = 0; i < sizeof(QuadVertices); ++i)  
  4. {  
  5.     quadVertexArray->push_back(osg::Vec3(QuadVertices[i][0], QuadVertices[i][1], QuadVertices[i][2]));  
  6. }  
  7. quadGeometry->setVertexArray(quadVertexArray);  
  8.   
  9. int first = 0;  
  10. for (unsigned i = 0; i < 6; ++i)  
  11. {  
  12.     osg::DrawArrays *vertexIndices = new osg::DrawArrays(osg::PrimitiveSet::QUADS, first, 4);  
  13.     first += 4;  
  14.     quadGeometry->addPrimitiveSet(vertexIndices);  
  15. }  
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. osg::Vec4Array *quadColorArray = new osg::Vec4Array;  
  2. for (unsigned i = 0; i < sizeof(QuadColors); ++i)  
  3. {  
  4.     quadColorArray->push_back(osg::Vec4(QuadColors[i][0], QuadColors[i][1], QuadColors[i][2], 1.0f));  
  5. }  
  6. quadGeometry->setColorArray(quadColorArray);  
  7. quadGeometry->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);  

注意到颜色绑定的方式是每个PrimitiveSet绑定一次,总共需要6个颜色值。

此处如果使用DrawArrayLengths那么绑定的方式不能设置为BIND_PER_PRIMITIVE_SET,因为它只是一个PrimitiveSet,只会绑定第一个颜色值。

编译运行程序


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

[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/AnimationPath>  
  14.   
  15.   
  16.  float TriangleVertices[][3] = {  {0.0f, 1.0f, 0.0f}, {-1.0f,-1.0f, 1.0f}, { 1.0f,-1.0f, 1.0f},  
  17. {0.0f, 1.0f, 0.0f}, {1.0f,-1.0f, 1.0f}, { 1.0f,-1.0f, -1.0f},   
  18. {0.0f, 1.0f, 0.0f},{1.0f,-1.0f, -1.0f},{ -1.0f,-1.0f, -1.0f},  
  19. {0.0f, 1.0f, 0.0f}, {-1.0f,-1.0f, -1.0f}, { -1.0f,-1.0f, 1.0f} };  
  20.   
  21.  float TriangleColors[][3] = {  { 1.0f, 0.0f, 0.0f}, { 0.0f,1.0f,0.0f}, { 0.0f,0.0f,1.0f},   
  22. { 1.0f, 0.0f, 0.0f}, { 0.0f,0.0f,1.0f}, { 0.0f,1.0f,0.0f},  
  23. { 1.0f, 0.0f, 0.0f}, { 0.0f,1.0f,0.0f}, { 0.0f,0.0f,1.0f},    
  24. { 1.0f,0.0f,0.0f}, { 0.0f,0.0f,1.0f},{ 0.0f,1.0f,0.0f} };  
  25.   
  26.   
  27.  float QuadVertices[][3] = {   
  28.      {1.0f, 1.0f,-1.0f},                    // Top Right Of The Quad (Top)  
  29.      {-1.0f, 1.0f,-1.0f},                   // Top Left Of The Quad (Top)  
  30.      {-1.0f, 1.0f, 1.0f},                   // Bottom Left Of The Quad (Top)  
  31.      { 1.0f, 1.0f, 1.0f},                   // Bottom Right Of The Quad (Top)};  
  32.      { 1.0f,-1.0f, 1.0f},               // Top Right Of The Quad {Bottom}  
  33.      {-1.0f,-1.0f, 1.0f},                   // Top Left Of The Quad {Bottom}  
  34.      {-1.0f,-1.0f,-1.0f},                   // Bottom Left Of The Quad {Bottom}  
  35.      { 1.0f,-1.0f,-1.0f},                   // Bottom Right Of The Quad {Bottom}  
  36.   
  37.      { 1.0f, 1.0f, 1.0f},                   // Top Right Of The Quad {Front}  
  38.      {-1.0f, 1.0f, 1.0f},                   // Top Left Of The Quad {Front}  
  39.      {-1.0f,-1.0f, 1.0f},                   // Bottom Left Of The Quad {Front}  
  40.      { 1.0f,-1.0f, 1.0f},                   // Bottom Right Of The Quad {Front}  
  41.   
  42.      { 1.0f,-1.0f,-1.0f},                   // Top Right Of The Quad {Back}  
  43.      {-1.0f,-1.0f,-1.0f},                   // Top Left Of The Quad {Back}  
  44.      {-1.0f, 1.0f,-1.0f},                   // Bottom Left Of The Quad {Back}  
  45.      { 1.0f, 1.0f,-1.0f},                   // Bottom Right Of The Quad {Back}  
  46.   
  47.      {-1.0f, 1.0f, 1.0f},                   // Top Right Of The Quad {Left}  
  48.      {-1.0f, 1.0f,-1.0f},                   // Top Left Of The Quad {Left}  
  49.      {-1.0f,-1.0f,-1.0f},                   // Bottom Left Of The Quad {Left}  
  50.      {-1.0f,-1.0f, 1.0f},                   // Bottom Right Of The Quad {Left}  
  51.   
  52.      { 1.0f, 1.0f,-1.0f},                   // Top Right Of The Quad {Right}  
  53.      { 1.0f, 1.0f, 1.0f},                   // Top Left Of The Quad {Right}  
  54.      { 1.0f,-1.0f, 1.0f},                   // Bottom Left Of The Quad {Right}  
  55.      { 1.0f,-1.0f,-1.0f}                    // Bottom Right Of The Quad {Right}  
  56.   
  57.  };  
  58.   
  59.  const float QuadColors[][3] ={{ 0.0f,1.0f,0.0f },{ 1.0f,0.5f,0.0f },{ 1.0f, 0.0f, 0.0f },  
  60.  { 1.0f, 1.0f, 0.0f },{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f } };  
  61.   
  62.   
  63. class ViewerWidget : public QWidget, public osgViewer::Viewer  
  64. {  
  65. public:  
  66.     ViewerWidget(osg::Node *scene = NULL)  
  67.     {  
  68.         QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);  
  69.   
  70.         QVBoxLayout* layout = new QVBoxLayout;  
  71.         layout->addWidget(renderWidget);  
  72.         layout->setContentsMargins(0, 0, 0, 1);  
  73.         setLayout( layout );  
  74.   
  75.         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );  
  76.         _timer.start( 10 );  
  77.     }  
  78.   
  79.     QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene )  
  80.     {  
  81.         osg::Camera* camera = this->getCamera();  
  82.         camera->setGraphicsContext( gw );  
  83.   
  84.         const osg::GraphicsContext::Traits* traits = gw->getTraits();  
  85.   
  86.         camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );  
  87.         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );  
  88.         camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );  
  89.         camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));  
  90.   
  91.         this->setSceneData( scene );  
  92.   
  93.         return gw->getGLWidget();  
  94.     }  
  95.   
  96.     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name=""bool windowDecoration=false )  
  97.     {  
  98.         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();  
  99.         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
  100.         traits->windowName = name;  
  101.         traits->windowDecoration = windowDecoration;  
  102.         traits->x = x;  
  103.         traits->y = y;  
  104.         traits->width = w;  
  105.         traits->height = h;  
  106.         traits->doubleBuffer = true;  
  107.         traits->alpha = ds->getMinimumNumAlphaBits();  
  108.         traits->stencil = ds->getMinimumNumStencilBits();  
  109.         traits->sampleBuffers = ds->getMultiSamples();  
  110.         traits->samples = ds->getNumMultiSamples();  
  111.   
  112.         return new osgQt::GraphicsWindowQt(traits.get());  
  113.     }  
  114.   
  115.     virtual void paintEvent( QPaintEvent* event )  
  116.     {   
  117.         frame();   
  118.     }  
  119.   
  120. protected:  
  121.   
  122.     QTimer _timer;  
  123. };  
  124.   
  125.   
  126.   
  127. //  
  128.   
  129.   
  130.   
  131. osg::Node*  buildScene()  
  132. {  
  133.     osg::Group *root = new osg::Group;  
  134.   
  135.     osg::MatrixTransform *triangleMT = new osg::MatrixTransform;  
  136.     triangleMT->setMatrix(osg::Matrix::translate(-1.5, 0.0, -6.0));  
  137.   
  138.     osg::AnimationPathCallback *triangleAnimationCallback =   
  139.         new osg::AnimationPathCallback(osg::Vec3d(0, 0, 0), osg::Y_AXIS, 2);  
  140.     osg::MatrixTransform *triangleRotMT = new osg::MatrixTransform;  
  141.     triangleRotMT->setUpdateCallback(triangleAnimationCallback);  
  142.   
  143.     osg::Geometry *triangleGeometry = new osg::Geometry;  
  144.     osg::Vec3Array *triangleVertexArray = new osg::Vec3Array;  
  145.     for (unsigned i = 0; i < sizeof(TriangleVertices); ++i)  
  146.     {  
  147.         triangleVertexArray->push_back(osg::Vec3(TriangleVertices[i][0], TriangleVertices[i][1], TriangleVertices[i][2]));  
  148.     }  
  149.     triangleGeometry->setVertexArray(triangleVertexArray);  
  150.     osg::Vec4Array *triangleColorArray = new osg::Vec4Array;  
  151.     for (unsigned i = 0; i < sizeof(TriangleColors); ++i)  
  152.     {  
  153.         triangleColorArray->push_back(osg::Vec4(TriangleColors[i][0], TriangleColors[i][1], TriangleColors[i][2], 1.0f));  
  154.     }  
  155.     triangleGeometry->setColorArray(triangleColorArray);  
  156.     triangleGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);  
  157.     triangleGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, 12));  
  158.     osg::Geode *triangleGeode = new osg::Geode;  
  159.   
  160.     triangleGeode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  161.     triangleGeode->addDrawable(triangleGeometry);  
  162.     triangleRotMT->addChild(triangleGeode);  
  163.     triangleMT->addChild(triangleRotMT);  
  164.   
  165.     //四边形部分  
  166.     osg::MatrixTransform *quadMT = new osg::MatrixTransform;  
  167.     quadMT->setMatrix(osg::Matrix::translate(1.5, 0.0, -6.0));  
  168.   
  169.     osg::AnimationPathCallback *quadAnimationCallback =   
  170.         new osg::AnimationPathCallback(osg::Vec3d(0, 0, 0), osg::Vec3(1, 1, 1), 2.5);  
  171.     osg::MatrixTransform *quadRotMT = new osg::MatrixTransform;  
  172.     quadRotMT->setUpdateCallback(quadAnimationCallback);  
  173.   
  174.     osg::Geometry *quadGeometry = new osg::Geometry;  
  175.     osg::Vec3Array *quadVertexArray = new osg::Vec3Array;  
  176.     for (unsigned i = 0; i < sizeof(QuadVertices); ++i)  
  177.     {  
  178.         quadVertexArray->push_back(osg::Vec3(QuadVertices[i][0], QuadVertices[i][1], QuadVertices[i][2]));  
  179.     }  
  180.     quadGeometry->setVertexArray(quadVertexArray);  
  181.   
  182.     int first = 0;  
  183.     for (unsigned i = 0; i < 6; ++i)  
  184.     {  
  185.         osg::DrawArrays *vertexIndices = new osg::DrawArrays(osg::PrimitiveSet::QUADS, first, 4);  
  186.         first += 4;  
  187.         quadGeometry->addPrimitiveSet(vertexIndices);  
  188.     }  
  189.     //  
  190.     //osg::DrawArrayLengths是一个PrimitiveSet,绑定颜色方式为BIND_PER_PRIMITIVE_SET  
  191.     //会出失败,只能显示为一种颜色  
  192.     //osg::DrawArrayLengths *v = new osg::DrawArrayLengths(osg::PrimitiveSet::QUADS, 0);  
  193.     //for (unsigned i = 0; i < 6; ++i)  
  194.     //{  
  195.     //  v->push_back(4);  
  196.     //}  
  197.     //quadGeometry->addPrimitiveSet(v);  
  198.       
  199.     osg::Vec4Array *quadColorArray = new osg::Vec4Array;  
  200.     for (unsigned i = 0; i < sizeof(QuadColors); ++i)  
  201.     {  
  202.         quadColorArray->push_back(osg::Vec4(QuadColors[i][0], QuadColors[i][1], QuadColors[i][2], 1.0f));  
  203.     }  
  204.     quadGeometry->setColorArray(quadColorArray);  
  205.     quadGeometry->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);  
  206.   
  207.     osg::Geode *quadGeode = new osg::Geode;  
  208.     quadGeode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);  
  209.     quadGeode->addDrawable(quadGeometry);  
  210.     quadRotMT->addChild(quadGeode);  
  211.     quadMT->addChild(quadRotMT);  
  212.   
  213.     root->addChild(triangleMT);  
  214.     root->addChild(quadMT);  
  215.   
  216.     return root;  
  217. }  
  218.   
  219.   
  220.   
  221. int main( int argc, char** argv )  
  222. {  
  223.     QApplication app(argc, argv);  
  224.     ViewerWidget* viewWidget = new ViewerWidget(buildScene());  
  225.     viewWidget->setGeometry( 100, 100, 640, 480 );  
  226.     viewWidget->show();  
  227.     return app.exec();  
  228. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值