zoukankan      html  css  js  c++  java
  • osglightpoint例子 [转]

    该例子演示了光点的效果,主要应用osgSim库中的LightPoint、LightPointNode、
    SequenceGroup、BlinkSequence,osgSim库属于仿真库,扩展库。应用osg核心库完成一些指定
    的效果。因此研究这个例子只需要指定以上这几个类的作用即可。
    LightPoint是光点类,有如下属性:
      bool                        _on;
           osg::Vec3               _position;
           osg::Vec4                _color;
           float                         _intensity;
           float                         _radius;
           osg::ref_ptr<Sector>      _sector;
            osg::ref_ptr<BlinkSequence> _blinkSequence;
            BlendingMode        _blendingMode;
    是否打开、位置、颜色、强度、半径、扇区、闪烁、模式
    从以上的属性可以指定,这个光点可以调整大小位置,可以运动可以变换颜色,闪烁效果。
    而LightPointNode是光点节点,里面保存了一个光点列表typedef std::vector< LightPoint > 
    LightPointList;
    SequenceGroup用于关联一组序列,内部只有一个基本时刻double      _baseTime;
    BlinkSequence闪烁序列,内部的属性:

      double                      _pulsePeriod;      
      double                      _phaseShift;
           PulseData            _pulseData;
            osg::ref_ptr<SequenceGroup> _sequenceGroup;从中可以看出可以添加很
    多脉冲,每个脉冲的间隔、停顿等。它属于LightPoint光点的一个属性,也就说一个光点可以以
    SequenceGroup定义的基本时间为基本仿真时间,根据BlinkSequence中设置的变换颜色和光点强
    度和脉冲。
    明白了以上几个类之间的关系,这个例子就很好理解了。
    在createLightPointsDatabase函数中创建了很多光点,设定了位置和颜色的变换范围,里面有
    一个:
    lpn->setPointSprite设置了光点添加纹理使用模糊的效果,必须指定0纹理单元(后面研究实现
    方法)。
    CreateBlinkSequenceLightNode函数创建了闪烁的光点,设置序列组,添加脉冲,设置强度位置
    等等。
    我们详细的研究一下LightPointNode,说是光点节点,但是它本身不发光,但可以通过其他方式
    模拟出发光的效果。这个节点很特别,在osg:Geode让他继承geode,然后adddrawable把光点的drawable添加
    进去进行渲染。
    而实际中LightPointNode并没有采用这种方法,而是继承Node,并且没有add任何的子节点。所
    有的的功能都是在traverse递归的时候实现的。
    这就涉及到了如何跳过场景树去绘制节点,答案是在剔除的时候去手动构建状态树,我们进入代
    码看看是怎么样手动构建的。
    首先 osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);用于判断只
    有在剔除遍历的时候才继续运行下面的代码,
    osg::Matrix matrix = *(cv->getModelViewMatrix());
            osg::RefMatrix& projection 
    = *(cv->getProjectionMatrix());
            osgUtil::StateGraph* rg = cv-
    >getCurrentStateGraph();
            if (rg->leaves_empty())
            {
                // this 
    is first leaf to be added to StateGraph
                // and therefore should not 
    already know current render bin,
                // so need to add it.
                cv-
    >getCurrentRenderBin()->addStateGraph(rg);
            }
    获取模型视图矩阵、获取投影矩阵、获取当前的渲染根节点。
    typeid(*object)==typeid(LightPointDrawable)
    用于判断object是否是(LightPointDrawable)类型的,如果是返回true否则返回false。
    接下来 drawable = _pointSprites ? new LightPointSpriteDrawable : new 
    LightPointDrawable;
    这里我们看到了_pointSprites ,这就是是否让LightPointNode使用纹理,如果使用纹理则new 
    LightPointSpriteDrawable否则new LightPointDrawable。并且把这个drawable设置成了当前的
    userdata。
    接下来把这个drawable收到的添加到rg->addLeaf(new osgUtil::RenderLeaf
    (drawable,&projection,NULL,FLT_MAX));渲染叶中,到目前为止需要注意,这个drawable中还
    没有任何内容,接下来就需要根据_lightPointList去向这个drawable添加绘制的内容,注意添
    加addBlendedLightPoint和addAdditiveLightPoint。
    现在我们进入LightPointDrawable中一看究竟,LightPointDrawable继承Drawable,需实现
    drawImplementation接口,关于drawImplementation我们会在不久的以后进行详细的研究。
    这里根据_sizedOpaqueLightPointList、_sizedBlendedLightPointList、
    _sizedAdditiveLightPointList中的内容进行了绘制,在这里面看到了状态的切换,看到了
    opengl的代码。
    再补充一下,LightPointDrawable中没有应用模糊纹理,因此state.applyTextureMode
    (0,GL_TEXTURE_1D,false);
        state.applyTextureMode(0,GL_TEXTURE_2D,false);
    而看看LightPointSpriteDrawable,state.applyTextureMode(0,GL_TEXTURE_2D,true);这里应
    用了纹理,这就是两者差别的体现。
    研究完了这一趟,似乎触及到了osg中核心的一些东西。至于我们刚才提出的问题为什么没有把
    他设计成Geode,而是继承Node,接下来大家一起思考。

  • 相关阅读:
    邻接表(网)
    邻接表(无向图)
    邻接表(无向图)
    邻接表(有向图)
    邻接表(有向图)
    邻接表(无向图)
    邻接表(有向图)
    邻接表(有向图)
    邻接表(网)
    完美解决循环线性操作倒计时无报错
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/7600524.html
Copyright © 2011-2022 走看看