liyihongcug 发表于 2020-4-15 20:43:32

2种绘制几何体方式

osgearth提供简洁方式的AnnotationNode。
CircleNodeEllipseNode FeatureNodeGeoPositionNode
ImageOverlayLableNode LocalGeometryNodePlaceNode
RectangleNode TrackNode

但有时候发现不好用,缺乏灵活性,如何是 new osgEarth::Features::Feature(new osgEarth::Symbology::Polygon,
会发现样式有很大的限制导致无法使用真正的面。
这时候有第二种方法使用原语操作geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));

几何体的形状参数除了QUADS之外,还有数种方式,以用于不同的用户需求,列表如下:
和opengl对比:

osg::PrimitiveSet::POINTS对应OpenGL中的GL_POINTS绘制单独的点
osg::PrimitiveSet::LINES对应OpenGL中的GL_LINES绘制每两点连接的线
osg::PrimitiveSet::LINE_STRIP对应OpenGL中的GL_LINE_STRIP绘制依次连接各点的线
osg::PrimitiveSet::LINE_LOOP对应OpenGL中的GL_LINE_LOOP绘制依次连接各点的线,首尾相连
osg::PrimitiveSet::POLYGON对应OpenGL中的GL_POLYGON绘制依次连接各点的多边形
osg::PrimitiveSet::QUADS对应OpenGL中的GL_QUADS绘制依次连接每四点的四边形
如:1、2、3、4、5、6、7、8点 绘制结果1、2、3、4组成四边形,5、6、7、8组成四边形
osg::PrimitiveSet::QUAD_STRIP对应OpenGL中的GL_QUAD_STRIP绘制四边形
如:1、2、3、4、5、6、7、8点 绘制结果1、2、3、4组成四边形,3、4、5、6组成四边形、5、
6、7、8组成四边形
osg::PrimitiveSet::TRIANGLES对应OpenGL中的GL_TRIANGLES绘制每三点连接的三角形
如:1、2、3、4、5、6点 绘制结果1、2、3组成三角形,4、5、6组成三角形
osg::PrimitiveSet::TRIANGLE_STRIP对应OpenGL中的GL_TRIANGLE_STRIP
如:1、2、3、4、5、6点 绘制结果1、2、3组成三角形,2、3、4组成三角形,3、4、5组成三角
形4、5、6组成三角形
osg::PrimitiveSet::TRIANGLE_FAN对应OpenGL中的GL_TRIANGLE_FAN
如:1、2、3、4、5、6点 绘制结果1、2、3组成三角形,1、3、4组成三角形,1、4、5组成三角
形,1、5、6组成三角形
例子代码

enum Mode
      {
            POINTS = GL_POINTS,
            LINES = GL_LINES,
            LINE_STRIP = GL_LINE_STRIP,
            LINE_LOOP = GL_LINE_LOOP,
            TRIANGLES = GL_TRIANGLES,
            TRIANGLE_STRIP = GL_TRIANGLE_STRIP,
            TRIANGLE_FAN = GL_TRIANGLE_FAN,
            QUADS = GL_QUADS,
            QUAD_STRIP = GL_QUAD_STRIP,
            POLYGON = GL_POLYGON,
            LINES_ADJACENCY = GL_LINES_ADJACENCY,
            LINE_STRIP_ADJACENCY = GL_LINE_STRIP_ADJACENCY,
            TRIANGLES_ADJACENCY = GL_TRIANGLES_ADJACENCY,
            TRIANGLE_STRIP_ADJACENCY = GL_TRIANGLE_STRIP_ADJACENCY,
            PATCHES = GL_PATCHES
      }; 四边形如下
osg::ref_ptr<osg::Node> GEOQuardTest::CreateNode()
{
        osg::ref_ptr<osg::Group> _root = new osg::Group;

        //创建一个叶结点对象
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        //创建一个几何体对象
        osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

        //创建顶点数组,逆时针顺序
        osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
        //逆时针添加数据
        v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
        v->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
        v->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
        v->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
        //设置顶点数据
        geom->setVertexArray(v);

        //创建颜色数组
        osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array;
        vc->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
        vc->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
        vc->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
        vc->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
        //设置颜色数组
        geom->setColorArray(vc);
        //设置颜色绑定模式
        geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

        //创建法线数组
        osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array;
        //增加法线,几何体顶点都是是在XOZ面上,所以法线是Y轴
        nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
        //设置法线
        geom->setNormalArray(nc);
        //设置法线的绑定方式为全部节点
        geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

        //添加图元,绘图基元为四边形,从第0个元素开始的四个元素,按照QUADS方式绘制四边形
        geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));

        //添加到叶子节点中
        geode->addChild(geom);

        _root->addChild(geode);

        return _root.get();
}

按照索引组织绘制数据,示例代码:
osg::ref_ptr<osg::Node> GEOQuardIndexTest::CreateNode()
{
        osg::ref_ptr<osg::Group> _root = new osg::Group;

        //创建一个叶结点对象
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        //创建一个几何体对象
        osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

        //创建顶点数组,逆时针顺序
        osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
        //逆时针添加数据
        v->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
        v->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
        v->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
        v->push_back(osg::Vec3(0.0f, 0.0f, 1.0f));
        v->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
        //设置顶点数据
        geom->setVertexArray(v);

        //创建四边形顶点索引数组,指定绘图基元为四边形
        osg::ref_ptr<osg::DrawElementsUInt> quad = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);
        //添加四边形的索引数据
        quad->push_back(0);
        quad->push_back(1);
        quad->push_back(2);
        quad->push_back(3);
        //添加到几何体
        geom->addPrimitiveSet(quad);

        //创建三角形顶点索引数据,制定绘图基元为三角形
        osg::ref_ptr<osg::DrawElementsUInt> tri = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);
        //添加数据
        tri->push_back(4);
        tri->push_back(0);
        tri->push_back(3);
        //添加到几何体
        geom->addPrimitiveSet(tri);

        //创建颜色数组
        osg::ref_ptr<osg::Vec4Array> vc = new osg::Vec4Array;
        vc->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
        vc->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
        vc->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
        vc->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));
        vc->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

        //设置颜色数组
        geom->setColorArray(vc);
        //设置颜色绑定模式
        geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

        //创建法线数组
        osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array;
        //增加法线,几何体顶点都是是在XOZ面上,所以法线是Y轴
        nc->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
        //设置法线
        geom->setNormalArray(nc);
        //设置法线的绑定方式为全部节点
        geom->setNormalBinding(osg::Geometry::BIND_OVERALL);

        //添加到叶子节点中
        geode->addChild(geom);
        _root->addChild(geode);

        return _root.get();
}

liyihongcug 发表于 2020-4-15 20:47:00

本帖最后由 liyihongcug 于 2020-4-16 10:45 编辑

补充:OSG中为了用户开发方便,已经内置了部分几何体,比如:立方体(osg::Box),椎体(osg::Cone),柱体(osg::Cylinder),球体(osg::Sphere)等。如果要渲染这些内嵌的几何体,可以将其与osg::ShapeDrawable关联来实现渲染。

在绘制这些内置几何体时候,对于趋近面,比如球体,圆柱等存在趋近面的时候,可以使用osg::TessellationHints网格化类来定义趋近面的精细程度,精细度越高细分越详细
www|qxqzx|com contents 303.html参考。

集合类
//geometry成员变量
      PrimitiveSetList                _primitives;
      osg::ref_ptr<Array>             _vertexArray;    //顶点
      osg::ref_ptr<Array>             _normalArray;    //法线
      osg::ref_ptr<Array>             _colorArray;//
      osg::ref_ptr<Array>             _secondaryColorArray;//
      osg::ref_ptr<Array>             _fogCoordArray;//
      ArrayList                     _texCoordList;//纹理UV
      ArrayList                     _vertexAttribList;//

      bool                            _containsDeprecatedData;    //
osgt文件中保存的格式:


osg::Geometry {
    UniqueID 2
    DataVariance STATIC
    StateSet TRUE {
      osg::StateSet {
            UniqueID 3
            DataVariance STATIC
            AttributeList 1 {
                osg::Material {
                  UniqueID 4
                  Ambient TRUE Front 1 1 1 1 Back 1 1 1 1
                  Diffuse TRUE Front 1 1 1 1 Back 1 1 1 1
                  Specular TRUE Front 0 0 0 1 Back 0 0 0 1
                  Emission TRUE Front 0 0 0 1 Back 0 0 0 1
                  Shininess TRUE Front 0 Back 0
                }
                Value OFF
            }
            TextureModeList 1 {
                Data 1 {
                  GL_TEXTURE_2D ON
                }
            }
            TextureAttributeList 1 {
                Data 1 {
                  osg::Texture2D {
                        UniqueID 5
                        DataVariance STATIC
                        WRAP_S CLAMP
                        WRAP_T CLAMP
                        WRAP_R CLAMP
                        MIN_FILTER LINEAR
                        MAG_FILTER LINEAR
                        UnRefImageDataAfterApply TRUE
                        Swizzle RGBA
                        Image TRUE {
                            ClassName osg::Image
                            UniqueID 6
                            FileName "Tile_1_L23_000001001000_0.dds"
                            WriteHint 2 2
                            DataVariance STATIC
                        }
                        TextureWidth 1024
                        TextureHeight 1024
                  }
                  Value OFF
                }
            }
      }
    }
    PrimitiveSetList 1 {
      osg::DrawElementsUInt {
            UniqueID 7
            Mode TRIANGLES
            vector 30450 {
                ........
            }
      }
    }
    VertexArray TRUE {
      osg::Vec3Array {
            UniqueID 8
            Binding BIND_PER_VERTEX
            vector 6681 {
                ........
            }
      }
    }
    TexCoordArrayList 1 {
      osg::Vec2Array {
            UniqueID 9
            Binding BIND_PER_VERTEX
            vector 6681 {
                ........
            }
      }
    }
}
View Code
大致分析一下:

一个geometry包含:

  一个stateset

  一个primitive列表

  一个顶点数组

  一个纹理数组列表



stateset包含:attribute数组,纹理数组

primitive包含:绘制的图元信息:(绘制格式,顶点索引)

顶点数组包含:三维顶点位置信息

纹理数组包含:二维顶点UV信息

小tips:

osg::Geometry *geometry = geode->getDrawable(0)->asGeometry();
geometry->setDataVariance(osg::Object::DYNAMIC);
geometry->setUseVertexBufferObjects(true);
    // 顶点数据
    osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
    // 法向量
    osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geometry->getNormalArray());
    // 颜色
    osg::Vec4Array* color = dynamic_cast<osg::Vec4Array*>(geometry->getColorArray());
    (*color) = newColor;//错误哦

使用使用setVertexArray setNormalArray setColorArray
    // 更新显示列表
    geometry->dirtyDisplayList();
如果使用VBO来更新几何对象,需要使用Vec3Array::dirty()来将修改结果通知给VBO对象,这里使用
————————————————

liyihongcug 发表于 2020-4-17 10:40:40

本帖最后由 liyihongcug 于 2020-4-23 16:49 编辑

实际使用 sg::PrimitiveSet::TRIANGLESFan
color绑定必须pl->setColorArray(vc);
                pl->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
                pl->dirtyDisplayList();

WEbgl的方式是使用primitive.更加灵活

dawei9989 发表于 2020-4-28 22:31:49

学习了,厉害了
页: [1]
查看完整版本: 2种绘制几何体方式