OSG开发笔记(十二):OSG基本几何图形、内置几何类型

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/96102001

目录

前言

基本几何图元(枚举)

内置几何类型(类)

球体

代码

效果

场景中X轴与Z轴长度不同的问题

问题代码

寻找问题原因

解决方法

所有内置几何类型绘制

代码

效果

工程模板:对应版本号1.9.0


 

OSG三维开发专栏

OSG开发笔记(一):OSG介绍、编译

OSG开发笔记(二):OSG帮助文档编译

OSG开发笔记(三):OSG使用osgQt嵌入Qt应用程序

OSG开发笔记(四):OSG不使用osgQt重写类嵌入Qt应用程序》:

OSG开发笔记(五):OSG场景理解与基础类概述

OSG开发笔记(六):OSG内存管理

OSG开发笔记(七):OSG复现OpenGL入门示例和OSG坐标系

OSG开发笔记(八):OSG模型文件存储与读取

OSG开发笔记(九):OSG模型的基本操作之添加/删除、显示/隐藏、开关节点开/》:

OSG开发笔记(十):OSG模型的变换之平移、旋转和缩放

OSG开发笔记(十一):OSG渲染状态与2D纹理映射

OSG开发笔记(十二):OSG基本几何图形、内置几何类型

OSG开发笔记(十三):OSG三维纹理映射(体渲染)

OSG开发笔记(十四):OSG交互

OSG开发笔记(十五):OSG光照

OSG开发笔记(十六):OSG视口、相机和视点

OSG开发笔记(十七):OSG中的相机移动

OSG开发笔记(十八):OSG鼠标拾取pick、拽托球体以及多光源

OSG开发笔记(十九):OSG文字显示

OSG开发笔记(二十):OSG使用HUD显示文字

OSG开发笔记(二十一):OSG使用HUD绘制图形以及纹理混合模式

OSG开发笔记(二十二):OSG场景背景

OSG开发笔记(二十三):Qt使用QOpenGLWidget渲染OSG地球仪

OSG开发笔记(二十四):OSG漫游之平移、转向和低抬头

OSG开发笔记(二十五):OSG漫游之CS移动、碰撞检测与跳跃

OSG开发笔记(二十六):OSG漫游之上下楼梯

《OSG开发笔记(二十七):OSG路径漫游之录制播放固定路径动画

《OSG开发笔记(二十八):OSG模型固定路径动画

  持续补充中…

 

     OSG开发笔记(十二):OSG基本几何图形、内置几何类型

 

前言

       OSG中的基本几何图形和内置几何类型(立体)。

 

基本几何图元(枚举)

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
};

        枚举中的常用枚举详细描述:

序号

枚举

描述

详细说明

1

POINTS

绘制点

绘制用户制指定的所有顶点

2

LINES

绘制直线

直线的起点、终点有数组中先后相邻的两个点决定;用于提供的点不止两个时,,将尝试继续绘制新的直线

3

LINE_STRIP

绘制多段直线

多段直线的第一段由数组中的前两个点决定;其余段的起点位置为上一段的终点坐标,而终点位置由数组中随后的点决定。

4

LINE_LOOP

绘制封闭直线

绘图方式与多段直线相同,但是最后将自动封闭该直线。

5

TRIANGLES

绘制三角形

三角形的三个顶点由数组中相邻的三个点决定,并按照逆时针的顺序进行绘制;用户提供的点不止三个时,将尝试继续绘制新的三角形。

6

TRIANGLE_STRIP

绘制多段三角形

第一段三角形的由数组中的前三个点决定;其余段三角形的绘制,起始边由上一段三角形的后两个点决定,第三点由数组中随后的一点决定

7

TRIANGLE_FAN

绘制三角扇形

第一段三角形的由数组中的前三个点决定;其余段三角形的绘制,起始边由整个数组的第一点和上一段三角形的最后一个点决定,第三点由数组中随后的一点决定。

8

QUADS

绘制四边形

四边形的四个顶点由数组中相邻的四个点决定,并按照逆时针的顺序进行绘制;用户提供的点不止四个时,将尝试继续绘制新的四边形。

9

QUAD_STRIP

绘制多段四边形

第一段四边形的起始边由数组中的前两个点决定,边的矢量方向由这两点的延伸方向决定;起始边的对边由其后的两个点决定,如果起始边和对边的矢量方向不同,那么四边形将会扭曲;其余段四边形的绘制,起始边由上一段决定,其对边由随后的两点及其延伸方向决定。

10

POLYGON

绘制任意多边形

根据用户提供的顶点的数量,绘制多边形。

 

内置几何类型(类)

序号

类型

描述

详细说明

1

Sphere

绘制球体

函数1:参数为中心点和半径

2

Box

绘制盒子(立方体、长方体)

函数1:参数为中心点和宽度

函数2:参数为中心点、x方向长度、y方向长度、z方向长度

3

Cone

绘制圆锥体

函数1:参数为中心点、半径和高度

4

Cylinder

绘制圆柱

函数1:参数为中心点、半径和高度

5

Capsule

绘制胶囊体

函数1:参数为中心点、半径和高度

6

InfinitePlane

绘制无线平面

需要结合其他绘制,暂不清楚

7

TriangleMesh

绘制三角网格

需要结合其他绘制,暂不清楚

8

ConvexHull

绘制凸形

需要结合其他绘制,暂不清楚

9

HeightField

绘制高度场

需要结合其他绘制,暂不清楚

10

CompositeShape

绘制复合型

添加其他几何体类型,形成混合体,作为单个结合体操作

 

球体

代码

osg::ref_ptr OsgWidget::getDrawSphere()
{
    osg::ref_ptr pGroop = new osg::Group;
#if 1
    {
        // 绘制球体
        // 步骤一:创建一个用户保存几何信息的对象osg::Geode
        osg::ref_ptr pGeode = new osg::Geode;
        // 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
        osg::ref_ptr pHints = new osg::TessellationHints;
        pHints->setDetailRatio(0.5);
        // 步骤三:绘制几何类型(几何体)
        qreal radius = 1.0f;
        pGeode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0, 0, 0), radius), pHints));
        // 步骤四:添加进结点组
        pGroop->addChild(pGeode);
    }
#endif
}

效果

OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第1张图片

 

场景中X轴与Z轴长度不同的问题

       从上图球体中可以看出球体的纵轴与横轴不同,这个问题在前面篇章中绘制图形也存在,笔者并没有管,画立体球形解决这个问题更合适。

问题代码

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第2张图片

        未设置父类,GLWidget单独一个窗口,不变形

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第3张图片

        设置父类,GLWidget嵌入式QWidget,变形

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第4张图片

寻找问题原因

        查看GLWidget::resizeEvent代码,发现此处设置了大小

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第5张图片

        分别尝试一下:

  • 不变形情况

        

  • 变形情况

        

       修改一下变形的情况,发现是此处只是场景的大小,与实际变形没有关系。

       原理上无法解决,窗口涉及到QGLWidget里面的绘制。

解决方法

       换个思路,直接用布局套进去。

       OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第6张图片

       然后,不要忘记new之后要delete,养成好习惯。

       

所有内置几何类型绘制

代码

osg::ref_ptr OsgWidget::getDrawAllGeode()
{
    
#define DRAW_SPHERE            (1)     // 绘制球体
#define DRAW_BOX               (1)     // 绘制盒体(立方体、长方体)
#define DRAW_CONE              (1)     // 绘制圆锥体
#define DRAW_CYLINDER          (1)     // 绘制圆柱
#define DRAW_CAPSULE           (1)     // 胶囊体(圆柱两头有半个球体封闭)
#define DRAW_COMPOSITESHAPE   (1)     // 绘制胶囊体(圆柱两头有半个球体封闭)
    
    osg::ref_ptr pGroop = new osg::Group;
#if DRAW_SPHERE
    {
        // 绘制球体
        // 步骤一:创建一个用户保存几何信息的对象osg::Geode
        osg::ref_ptr pGeode = new osg::Geode;
        // 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
        osg::ref_ptr pHints = new osg::TessellationHints;
        pHints->setDetailRatio(0.5);
        // 步骤三:绘制几何类型(几何体)
        qreal radius = 1.0f;
        pGeode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0, 0, 0), radius), pHints));
        // 步骤四:添加进结点组
        pGroop->addChild(pGeode);
    }
#endif
#if DRAW_BOX
    {
        // 绘制盒体(立方体、长方体)
        // 步骤一:创建一个用户保存几何信息的对象osg::Geode
        osg::ref_ptr pGeode = new osg::Geode;
        // 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
        osg::ref_ptr pHints = new osg::TessellationHints;
        pHints->setDetailRatio(0.5);
        // 步骤三:绘制几何类型(几何体)
        qreal width = 1.0f;
        // 函数1
        pGeode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2, 2, 0), width), pHints));
        qreal lengthX = 1.0f;
        qreal lengthY = 2.0f;
        qreal lengthZ = 3.0f;
        // 函数2
        pGeode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(4, 2, 0), lengthX, lengthY, lengthZ), pHints));
        // 步骤四:添加进结点组
        pGroop->addChild(pGeode);
    }
#endif
#if DRAW_CONE
    {
        // 绘制圆锥体
        // 步骤一:创建一个用户保存几何信息的对象osg::Geode
        osg::ref_ptr pGeode = new osg::Geode;
        // 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
        osg::ref_ptr pHints = new osg::TessellationHints;
        pHints->setDetailRatio(0.5);
        // 步骤三:绘制几何类型(几何体)
        qreal radius = 1.0f;
        qreal height = 2.0f;
        pGeode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(6, 4, 0), radius, height), pHints));
        // 步骤四:添加进结点组
        pGroop->addChild(pGeode);
    }
#endif
#if DRAW_CYLINDER
    {
        // 绘制圆柱
        // 步骤一:创建一个用户保存几何信息的对象osg::Geode
        osg::ref_ptr pGeode = new osg::Geode;
        // 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
        osg::ref_ptr pHints = new osg::TessellationHints;
        pHints->setDetailRatio(0.5);
        // 步骤三:绘制几何类型(几何体)
        qreal radius = 1.0f;
        qreal height = 2.0f;
        pGeode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(8, 6, 0), radius, height), pHints));
        // 步骤四:添加进结点组
        pGroop->addChild(pGeode);
    }
#endif
#if DRAW_CAPSULE
    {
        // 绘制胶囊体(圆柱两头有半个球体封闭)
        // 步骤一:创建一个用户保存几何信息的对象osg::Geode
        osg::ref_ptr pGeode = new osg::Geode;
        // 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
        osg::ref_ptr pHints = new osg::TessellationHints;
        pHints->setDetailRatio(0.5);
        // 步骤三:绘制几何类型(几何体)
        qreal radius = 1.0f;
        qreal height = 2.0f;
        pGeode->addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(10, 8, 0), radius, height), pHints));
        // 步骤四:添加进结点组
        pGroop->addChild(pGeode);
    }
#endif
#if DRAW_COMPOSITESHAPE
    {
        // 绘制胶囊体(圆柱两头有半个球体封闭)
        // 步骤一:创建一个用户保存几何信息的对象osg::Geode
        osg::ref_ptr pGeode = new osg::Geode;
        // 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
        osg::ref_ptr pHints = new osg::TessellationHints;
        pHints->setDetailRatio(0.5);
        // 步骤三:绘制几何类型(几何体)
        qreal radius = 1.0f;
        qreal height = 2.0f;
        osg::ref_ptr pCompositeShape = new osg::CompositeShape;
        // 添加一个圆柱
        pCompositeShape->addChild(new osg::Cylinder(osg::Vec3(12, 10, 0), radius, height));
        // 添加一个圆锥体
        pCompositeShape->addChild(new osg::Cone(osg::Vec3(12, 10, 1.5), radius, height));
        pGeode->addDrawable(new osg::ShapeDrawable(pCompositeShape.get(), pHints));
        // 步骤四:添加进结点组
        pGroop->addChild(pGeode);
    }
#endif
    return pGroop.get();
}

效果

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第7张图片

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第8张图片

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第9张图片

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第10张图片

        OSG开发笔记(十二):OSG基本几何图形、内置几何类型_第11张图片

 

工程模板:对应版本号1.9.0

        对应版本号1.9.0


原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/96102001

你可能感兴趣的:(Qt开发专栏,OSG,OSG三维开发专栏)