若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/96102001
目录
前言
基本几何图元(枚举)
内置几何类型(类)
球体
代码
效果
场景中X轴与Z轴长度不同的问题
问题代码
寻找问题原因
解决方法
所有内置几何类型绘制
代码
效果
工程模板:对应版本号1.9.0
《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中的基本几何图形和内置几何类型(立体)。
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
}
从上图球体中可以看出球体的纵轴与横轴不同,这个问题在前面篇章中绘制图形也存在,笔者并没有管,画立体球形解决这个问题更合适。
未设置父类,GLWidget单独一个窗口,不变形
设置父类,GLWidget嵌入式QWidget,变形
查看GLWidget::resizeEvent代码,发现此处设置了大小
分别尝试一下:
修改一下变形的情况,发现是此处只是场景的大小,与实际变形没有关系。
原理上无法解决,窗口涉及到QGLWidget里面的绘制。
换个思路,直接用布局套进去。
然后,不要忘记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();
}
对应版本号1.9.0
原博主博客地址:https://blog.csdn.net/qq21497936
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/96102001