• Learning OSG programing---osgShape


    本例示范了osg中Shape ---- 基本几何元素的绘制过程。参照osg官方文档,Shape 类包含以下子类:

    在示例程序中,函数createShapes函数用于生成需要绘制的几何形状。

     1 osg::Geode* createShapes(osg::ArgumentParser& arguments)
     2 {
     3     osg::Geode* geode = new osg::Geode();
     4 
     5 
     6     // ---------------------------------------
     7     // Set up a StateSet to texture the objects
     8     // ---------------------------------------
     9     osg::StateSet* stateset = new osg::StateSet();
    10   //设置材质图片
    11     osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile( "Images/lz.rgb" );
    12     if (image)
    13     {
    14         osg::Texture2D* texture = new osg::Texture2D;
    15         texture->setImage(image);
    16         texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
    17         stateset->setTextureAttributeAndModes(0,texture, osg::StateAttribute::ON);
    18     }
    19 
    20     stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);
    21 
    22     geode->setStateSet( stateset );
    23 
    24 
    25     float radius = 0.8f;
    26     float height = 1.0f;
    27 
    28     osg::TessellationHints* hints = new osg::TessellationHints;
    29     hints->setDetailRatio(0.5f);
    30   //建立各种几何实体
    31     geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius),hints));
    32     geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2.0f,0.0f,0.0f),2*radius),hints));
    33     geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height),hints));
    34     geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.0f,0.0f,0.0f),radius,height),hints));
    35     geode->addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(8.0f,0.0f,0.0f),radius,height),hints));
    36   //用于控制平面的高程起伏
    37     osg::HeightField* grid = new osg::HeightField;
    38     if (arguments.read("--large"))      //大范围
    39     {
    40         unsigned int numX = 512;
    41         unsigned int numY = 512;
    42         double sizeX = 10.0;
    43         double sizeY = 10.0;
    44         grid->allocate(numX,numY);
    45         grid->setXInterval(sizeX/float(numX));
    46         grid->setYInterval(sizeY/float(numY));
    47 
    48         for(unsigned int r=0;r<numY;++r)
    49         {
    50             for(unsigned int c=0;c<numX;++c)
    51             {
    52                 double rx = double(c)/double(numX-1);
    53                 double ry = double(r)/double(numY-1);
    54 
    55                 grid->setHeight(c, r, 2.0*sin(rx*ry*4.0*osg::PI));
    56             }
    57         }
    58     }
    59     else              //小范围
    60     {
    61         grid->allocate(38,39);
    62         grid->setXInterval(0.28f);
    63         grid->setYInterval(0.28f);
    64 
    65         for(unsigned int r=0;r<39;++r)
    66         {
    67             for(unsigned int c=0;c<38;++c)
    68             {
    69                 grid->setHeight(c,r,vertex[r+c*39][2]);
    70             }
    71         }
    72     }
    73 
    74     geode->addDrawable(new osg::ShapeDrawable(grid));
    75 
    76     return geode;
    77 }

    在以上代码中,首先建立了几何节点Geode,加载纹理图像,并将其设置为节点的材质。

    之后向节点中加入各种Shape模型,设置它们的集合参数。之后建立了高程域模型osg::HeightField* grid,根据运行程序时提供的命令行参数,设置其为不同的点密度。若运行命令中提供有--large选项,则建立高密度高程集,两层for循环中嵌套的语句,即为计算高程网格中各点的高程值方程。对于large情形,其在点(x,y)处的高程值为2*sin(x*y*4π)。而在普通情况下,点的高程值取决与vertex向量的第三个分量,因为在文件的开始,包含了地形坐标数据:

    #include "../osghangglide/terrain_coords.h"

    最后,将定义的地形平面添加到节点中去。

    在主函数中,调用上面定义的createShapes函数,在进行一些其他准备工作即可:

    int main(int argc, char **argv)
    {
        osg::ArgumentParser arguments(&argc,argv);
    
        // construct the viewer.
        osgViewer::Viewer viewer(arguments);
    
        // add model to viewer.
        viewer.setSceneData( createShapes(arguments) );
    
        // add the state manipulator
        viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
    
        return viewer.run();
    }

    按不同模式运行程序,得到不同的效果:

    --large模式:

    正常模式:

    由此程序受到启发,可利用osg高程域,建立DEM(数字高程模型)浏览或仿真、编辑工具,达到学以致用的目的。

    Enjoy!

  • 相关阅读:
    【转贴】判断sql server表是否存在的方法
    SQL SERVER 中将重复记录合并为一条记录
    数据清洗:将字段值全部为数字的记录置空
    【转贴】PLSQL不安装客户端连接远程oracle
    Datalength() 与 Len()的区别
    SQL SERVER 查询重复的记录的方法
    连接mysql利用jsp实现简单的登陆操作
    jsp包含文件的两种方法
    preparedStatment的用法
    request内置对象介绍和使用
  • 原文地址:https://www.cnblogs.com/SupremeGIS-Developer/p/10665574.html
Copyright © 2020-2023  润新知