若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/96102001
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究若该文为原创文章,未经允许不得转载
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)
OSG开发专栏(点击传送门)
上一篇:《OSG开发笔记(十一):OSG渲染状态与2D纹理映射》
下一篇:《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<osg::Node> OsgWidget::getDrawSphere()
{
osg::ref_ptr<osg::Group> pGroop = new osg::Group;
#if 1
{
// 绘制球体
// 步骤一:创建一个用户保存几何信息的对象osg::Geode
osg::ref_ptr<osg::Geode> pGeode = new osg::Geode;
// 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
osg::ref_ptr<osg::TessellationHints> 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
}
效果
场景中X轴与Z轴长度不同的问题
从上图球体中可以看出球体的纵轴与横轴不同,这个问题在前面篇章中绘制图形也存在,笔者并没有管,画立体球形解决这个问题更合适。
问题代码
未设置父类,GLWidget单独一个窗口,不变形
设置父类,GLWidget嵌入式QWidget,变形
寻找问题原因
查看GLWidget::resizeEvent代码,发现此处设置了大小
分别尝试一下:
- 不变形情况
- 变形情况
修改一下变形的情况,发现是此处只是场景的大小,与实际变形没有关系。
原理上无法解决,窗口涉及到QGLWidget里面的绘制。
解决方法
换个思路,直接用布局套进去。
然后,不要忘记new之后要delete,养成好习惯。
所有内置几何类型绘制
代码
osg::ref_ptr<osg::Node> 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<osg::Group> pGroop = new osg::Group;
#if DRAW_SPHERE
{
// 绘制球体
// 步骤一:创建一个用户保存几何信息的对象osg::Geode
osg::ref_ptr<osg::Geode> pGeode = new osg::Geode;
// 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
osg::ref_ptr<osg::TessellationHints> 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<osg::Geode> pGeode = new osg::Geode;
// 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
osg::ref_ptr<osg::TessellationHints> 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<osg::Geode> pGeode = new osg::Geode;
// 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
osg::ref_ptr<osg::TessellationHints> 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<osg::Geode> pGeode = new osg::Geode;
// 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
osg::ref_ptr<osg::TessellationHints> 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<osg::Geode> pGeode = new osg::Geode;
// 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
osg::ref_ptr<osg::TessellationHints> 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<osg::Geode> pGeode = new osg::Geode;
// 步骤二:创建专门指明精细度的类osg::TessellationHints,并设置对应精细度
osg::ref_ptr<osg::TessellationHints> pHints = new osg::TessellationHints;
pHints->setDetailRatio(0.5);
// 步骤三:绘制几何类型(几何体)
qreal radius = 1.0f;
qreal height = 2.0f;
osg::ref_ptr<osg::CompositeShape> 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
对应版本号1.9.0
上一篇:《OSG开发笔记(十一):OSG渲染状态与2D纹理映射》
下一篇:《OSG开发笔记(十三):OSG三维纹理映射(体渲染)》
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/96102001