【OSG学习笔记】Day 17: Shape 与 ShapeDrawable
·

osg::Shape 与 osg::ShapeDrawable
在 OpenSceneGraph(OSG)三维开发中,除了通过 osg::Geometry 手动构建顶点、索引实现自定义几何体外,OSG 还提供了开箱即用的基础图形封装——osg::Shape 与 osg::ShapeDrawable。
这两个类专门用于快速创建立方体、球体、圆柱体、圆锥体等标准几何体,无需手动定义顶点数据,大幅简化基础三维图形的开发流程。
本文将详细讲解两者的核心作用、继承关系、使用方法,并结合完整代码示例演示实际用法,帮你快速掌握 OSG 标准图形渲染能力。
osg::Shape与osg::ShapeDrawable` 是什么?
1. osg::Shape:基础图形的数学定义类
osg::Shape 是一个抽象基类,它的核心作用是描述基础几何体的数学属性,不负责渲染,只定义「形状是什么」:
- 球体:半径、球心
- 立方体:长宽高、中心
- 圆柱体:底面半径、高度
- 圆锥体:底面半径、高度
它是纯数据类,仅存储几何参数,不参与场景渲染。
2. osg::ShapeDrawable:基础图形的可渲染类
osg::ShapeDrawable 是可渲染对象,继承自 osg::Drawable,它的核心作用是将 osg::Shape 定义的数学形状,转换成可被 OSG 渲染的图形:
- 接收
osg::Shape对象作为渲染数据源 - 自动生成顶点、法线、颜色等渲染数据
- 直接挂载到
osg::Geode节点完成渲染 - 支持设置颜色、渲染精度等属性
简单总结:
osg::Shape= 图纸(定义形状)osg::ShapeDrawable= 施工队(把图纸变成可见图形)
完整继承关系(类层级)
1. osg::Shape 类继承链
osg::Shape 是所有基础形状的根类,派生类对应具体的标准几何体:
osg::Object(所有OSG对象根类)
↓
osg::Shape(抽象基类:基础图形定义)
├─ osg::Sphere 球体
├─ osg::Box 立方体/长方体
├─ osg::Cylinder 圆柱体
├─ osg::Cone 圆锥体
├─ osg::Capsule 胶囊体
└─ osg::InfinitePlane 无限平面
2. osg::ShapeDrawable 类继承链
osg::ShapeDrawable 属于可渲染对象层级,专门用于渲染 Shape 定义的图形:
osg::Object
↓
osg::Drawable(可渲染对象抽象基类)
↓
osg::ShapeDrawable(基础图形渲染类)
3. 三者协作关系(Shape + ShapeDrawable + Geode)
osg::Shape(定义形状)
↓ 关联
osg::ShapeDrawable(渲染形状)
↓ 挂载
osg::Geode(场景叶节点,承载可渲染对象)
这是 OSG 标准图形的固定渲染流程,比手动写 Geometry 简单10倍。
核心类功能详解
1. osg::Shape 派生类常用功能
| 类名 | 作用 | 核心参数 |
|---|---|---|
osg::Sphere |
球体 | 球心、半径 |
osg::Box |
立方体 | 中心、长宽高 |
osg::Cylinder |
圆柱体 | 中心、半径、高度 |
osg::Cone |
圆锥体 | 顶点、底面半径、高度 |
2. osg::ShapeDrawable 核心方法
| 方法 | 作用 |
|---|---|
ShapeDrawable(Shape*) |
绑定要渲染的 Shape 对象 |
setColor(const Vec4&) |
设置图形颜色(RGBA) |
setTessellation(int) |
设置曲面细分精度(值越大越光滑) |
getShape() |
获取绑定的 Shape 对象 |
类图关系(可视化结构)
+------------------+
| osg::Object |
+------------------+
↑
|
+------------------+ +------------------+
| osg::Shape |<-------+ osg::ShapeDrawable |
+------------------+ +------------------+
| (纯数学定义) | | (可渲染对象) |
+------------------+ +------------------+
↑ (继承)
+------------------+
| osg::Sphere |
+------------------+
| osg::Box |
+------------------+
| osg::Cylinder |
+------------------+
| osg::Cone |
+------------------+
↓ (挂载)
+------------------+
| osg::Geode |
+------------------+
- 继承关系:
Object → Shape → 具体形状;Object → Drawable → ShapeDrawable - 关联关系:
ShapeDrawable持有Shape对象 - 挂载关系:
ShapeDrawable必须添加到Geode才能渲染
实战代码:快速渲染标准几何体
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/ShapeDrawable>
#include <osgUtil/Optimizer>
osg::ref_ptr<osg::Geode> createShape()
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
float redius = 0.8f;
float height = 1.0f;
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
hints->setDetailRatio(0.5f);
geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.f, 0.0f, 0.0f), redius), hints.get()));
geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2.f, 0.0f, 0.0f), 2*redius), hints.get()));
geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.f, 0.0f, 0.0f), redius, height), hints.get()));
geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.f, 0.0f, 0.0f), redius, height), hints.get()));
geode->addDrawable(new osg::ShapeDrawable(new osg::Capsule(osg::Vec3(8.f, 0.0f, 0.0f), redius, height), hints.get()));
return geode.get();
}
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
// 添加到场景
root->addChild(createShape());
// 优化场景数据
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
// 运行并渲染
return viewer->run();
}

ShapeDrawable 与 Geometry 的区别
| 特性 | osg::ShapeDrawable |
osg::Geometry |
|---|---|---|
| 使用场景 | 快速创建标准几何体(球、立方、圆柱等) | 自定义任意复杂几何体 |
| 数据定义 | 自动生成顶点、法线 | 手动定义顶点、索引、颜色 |
| 开发效率 | 极高(几行代码实现) | 低(需编写大量数据) |
| 灵活性 | 低(仅支持标准形状) | 极高(支持任意形状) |
| 适用人群 | 快速开发、基础图形展示 | 高精度自定义模型、复杂渲染 |
简单来说:
- 标准图形用
Shape+ShapeDrawable - 自定义图形用
Geometry
总结
osg::Shape:基础图形数学定义抽象类,派生类对应球体、立方体、圆柱体等,仅存储形状参数。osg::ShapeDrawable:基础图形可渲染类,继承自osg::Drawable,负责将Shape转换成可渲染图形。- 继承关系:
osg::Object → osg::Shape → 具体形状类osg::Object → osg::Drawable → osg::ShapeDrawable
- 渲染流程:定义
Shape→ 封装为ShapeDrawable→ 挂载到osg::Geode→ 完成渲染。 - 核心优势:无需手动处理顶点数据,快速实现标准三维图形渲染,是 OSG 入门必备的基础类。

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


所有评论(0)