【OSG学习笔记】Day 15: PrimitiveSet类
·

osg::PrimitiveSet 类与继承体系详解
在 OSG 的几何体渲染流程中,osg::PrimitiveSet 是连接顶点数据与 GPU 绘制指令的关键桥梁,它定义了“如何用顶点数据组成可渲染的图元”(如点、线、三角形等)。
本文结合你提供的继承关系图,系统梳理 PrimitiveSet 的核心作用、类层级与每个子类的具体功能。
osg::PrimitiveSet 核心定位
1. 定义
osg::PrimitiveSet 是图元渲染的抽象基类,本身不能直接实例化,它的核心职责是:
- 告诉渲染器:用什么方式(图元类型)去绘制顶点数据
- 管理顶点索引或顶点范围,实现高效的几何数据复用
- 作为
osg::Geometry的子元素,与顶点数组(VertexArray)配合完成渲染
2. 上层继承关系
osg::Referenced(引用计数,自动内存管理)
↓
osg::Object(OSG 对象基类,支持命名、克隆)
↓
osg::PrimitiveSet(图元渲染抽象基类)
osg::Referenced:实现引用计数,保证PrimitiveSet生命周期自动管理osg::Object:扩展为可命名、可克隆的场景对象osg::PrimitiveSet:定义图元渲染的统一接口,子类实现具体绘制逻辑
osg::PrimitiveSet 完整子类继承关系(对照图示)
根据你提供的继承图,PrimitiveSet 的子类体系如下:
osg::PrimitiveSet
├── osg::DrawArrayLengths
├── osg::DrawArrays
└── osg::DrawElements
├── osg::DrawElementsUByte
├── osg::DrawElementsUShort
└── osg::DrawElementsUInt
每个子类详细作用解析
1. osg::DrawArrays(最常用的顺序绘制类)
- 继承关系:直接继承
PrimitiveSet - 核心作用:按顶点数组的顺序,从指定起始位置绘制连续的顶点
- 典型用法:
// 绘制 4 个顶点,组成一个四边形 geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4)); - 关键参数:
- 图元类型(
POINTS/LINES/TRIANGLES/QUADS等) - 起始顶点索引
- 顶点数量
- 图元类型(
- 特点:
- 无需索引,直接按顺序读取顶点数组
- 实现简单,适合顶点不重复的场景
- 是你之前遮挡节点代码中使用的绘制方式
2. osg::DrawArrayLengths(分段绘制类)
- 继承关系:直接继承
PrimitiveSet - 核心作用:分段绘制顶点数组,支持多段独立图元
- 典型场景:
- 绘制多条独立的线段(如道路网、轨迹线)
- 绘制多个不连续的多边形(如建筑轮廓、区域边界)
- 特点:
- 允许指定每一段的顶点数量
- 适合顶点数据连续但逻辑上分段的场景
- 相比多次调用
DrawArrays,性能更优
3. osg::DrawElements(索引绘制抽象基类)
- 继承关系:直接继承
PrimitiveSet - 核心作用:通过索引数组复用顶点数据,实现高效渲染
- 核心思想:
顶点数组存储所有唯一顶点,用索引数组指定“哪些顶点组成一个图元”,避免重复存储共享顶点(如立方体的 8 个顶点可被 6 个面复用) - 特点:
- 是索引绘制的抽象基类,不能直接实例化
- 子类通过不同索引类型(字节/短整型/无符号整型)平衡内存占用与索引范围
4. osg::DrawElementsUByte(8位索引绘制)
- 继承关系:继承
DrawElements - 索引类型:
GLubyte(0~255) - 适用场景:顶点数量 ≤ 256 的小型几何体(如简单立方体、小图标)
- 特点:
- 内存占用最小(每个索引 1 字节)
- 索引范围有限,仅适合超小规模模型
5. osg::DrawElementsUShort(16位索引绘制)
- 继承关系:继承
DrawElements - 索引类型:
GLushort(0~65535) - 适用场景:顶点数量 ≤ 65536 的中等规模模型(如角色模型、小型场景)
- 特点:
- 内存占用适中(每个索引 2 字节)
- 是最常用的索引类型,平衡性能与范围
6. osg::DrawElementsUInt(32位索引绘制)
- 继承关系:继承
DrawElements - 索引类型:
GLuint(0~4294967295) - 适用场景:大规模模型(如地形、高精度城市模型、大型场景)
- 特点:
- 索引范围极大,支持海量顶点
- 内存占用最高(每个索引 4 字节),适合顶点数极多的场景
PrimitiveSet 核心概念:图元类型
所有 PrimitiveSet 子类都需要指定图元类型,决定顶点如何被组装:
| 图元类型 | 含义 |
|---|---|
osg::PrimitiveSet::POINTS |
独立点 |
osg::PrimitiveSet::LINES |
每两个顶点组成一条线段 |
osg::PrimitiveSet::LINE_STRIP |
连续线段(后一个顶点接前一个) |
osg::PrimitiveSet::LINE_LOOP |
闭合线段(首尾相连) |
osg::PrimitiveSet::TRIANGLES |
每三个顶点组成一个三角形 |
osg::PrimitiveSet::TRIANGLE_STRIP |
连续三角形带 |
osg::PrimitiveSet::TRIANGLE_FAN |
扇形三角形(共享第一个顶点) |
osg::PrimitiveSet::QUADS |
每四个顶点组成一个四边形 |
osg::PrimitiveSet::QUAD_STRIP |
连续四边形带 |
osg::PrimitiveSet::POLYGON |
多边形(任意数量顶点) |
DrawArrays vs DrawElements:核心区别
| 特性 | DrawArrays(顺序绘制) |
DrawElements(索引绘制) |
|---|---|---|
| 顶点复用 | 无法复用,重复顶点需重复存储 | 可通过索引复用共享顶点,减少内存占用 |
| 实现复杂度 | 简单,直接指定起始位置和数量 | 需额外维护索引数组 |
| 性能 | 适合顶点无重复的场景 | 适合顶点共享多的场景(如立方体、地形) |
| 内存占用 | 较高(重复顶点) | 较低(复用顶点) |
结合代码示例:PrimitiveSet 的实际使用
示例 1:用 DrawArrays 绘制四边形(你的遮挡节点代码)
// 绘制 4 个顶点组成的四边形
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
- 从第 0 个顶点开始,连续取 4 个顶点,组装为
QUADS(四边形) - 实现简单,适合顶点无重复的场景
示例 2:用 DrawElementsUShort 绘制立方体
osg::ref_ptr<osg::Vec3Array> verts = new osg::Vec3Array();
// 存储立方体 8 个顶点...
osg::ref_ptr<osg::DrawElementsUShort> de = new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS);
// 用索引指定 6 个面,每个面 4 个顶点,复用 8 个顶点
de->addIndex(0); de->addIndex(1); de->addIndex(2); de->addIndex(3); // 前面
// ... 其他 5 个面的索引
geom->setVertexArray(verts);
geom->addPrimitiveSet(de);
- 8 个顶点被 6 个面复用,内存占用大幅降低
- 适合复杂模型的高效渲染
总结
osg::PrimitiveSet 是 OSG 几何体渲染的核心调度层:
- 它定义了顶点数据的组装规则,是连接
osg::Geometry与 GPU 绘制指令的关键 DrawArrays适合简单、无顶点复用的场景,实现便捷DrawElements系列子类通过索引复用顶点,是高性能渲染的核心选择- 不同索引类型(
UByte/UShort/UInt)平衡了内存占用与顶点数量上限
掌握 PrimitiveSet 的继承体系与子类特性,是理解 OSG 几何体渲染流程、优化场景性能的关键一步。

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)