查看: 2690|回复: 3

2种绘制几何体方式

[复制链接]
  • TA的每日心情
    开心
    2020-3-20 17:50
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2020-4-15 20:43:32 | 显示全部楼层 |阅读模式
    osgearth提供简洁方式的AnnotationNode。
    CircleNode  EllipseNode FeatureNode  GeoPositionNode
    ImageOverlay  LableNode LocalGeometryNode  PlaceNode
    RectangleNode TrackNode

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

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

    osg::PrimitiveSet::POINTS对应OpenGL中的GL_POINTS绘制单独的点
    osg::PrimitiveSet:INES对应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();
    }
  • TA的每日心情
    开心
    2020-3-20 17:50
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 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:rawElementsUInt {
                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)[0] = newColor;  //错误哦

    使用使用setVertexArray setNormalArray setColorArray
        // 更新显示列表
        geometry->dirtyDisplayList();
    如果使用VBO来更新几何对象,需要使用Vec3Array::dirty()来将修改结果通知给VBO对象,这里使用
    ————————————————
  • TA的每日心情
    开心
    2020-3-20 17:50
  • 签到天数: 1 天

    [LV.1]初来乍到

     楼主| 发表于 2020-4-17 10:40:40 | 显示全部楼层
    本帖最后由 liyihongcug 于 2020-4-23 16:49 编辑

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

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

    该用户从未签到

    发表于 2020-4-28 22:31:49 | 显示全部楼层
    学习了,厉害了
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    OSG中国官方论坛-有您OSG在中国才更好

    网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

    联系我们

    • 工作时间:09:00--18:00
    • 反馈邮箱:1315785073@qq.com
    快速回复 返回顶部 返回列表