
Text与Font
在OpenSceneGraph(OSG)三维渲染开发中,文字渲染是场景标注、信息展示的核心功能。
无论是三维模型的标签、场景的说明文字,还是始终面向屏幕的UI文字,都依赖osgText::Text与osgText::Font两大核心类实现。
本文将结合完整可运行的OSG文字渲染代码,深度解析Text、Font类的设计思想、继承体系、核心用法,并拆解代码实现逻辑,帮助开发者掌握三维文字开发的核心技巧。
前置基础
OSG的osgText是专门用于三维空间文字渲染的模块,完美适配三维场景的透视投影、相机视角变换,支持中文字体加载、文字自适应屏幕、颜色/大小/对齐方式定制化。
其核心设计遵循面向对象封装、职责分离、可扩展 的原则,将字体管理 与文字渲染拆分为两个独立类,同时依托OSG底层渲染基类实现无缝集成。
核心类解析
1. 类定义与核心职责
osgText::Font是OSG文字模块的字体管理核心类 ,专门负责字体文件的加载、解析、纹理缓存、字符渲染数据管理。
它的核心职责是将.ttf/.ttc等字体文件转换为OSG可渲染的字符数据,为Text类提供字符形状、轮廓支持。
简单来说:Font是文字的"字体模板",决定文字的字形、粗细、风格。
2. 类的继承体系
Font类严格遵循OSG的基类设计规范,继承链清晰:
osg::Object(所有OSG对象基类)
↓
osg::Referenced(引用计数智能指针基类)
↓
osgText::Font
- 继承
osg::Object:获得命名、克隆、序列化能力; - 继承
osg::Referenced:支持OSG智能指针ref_ptr自动内存管理,无需手动释放字体对象。
3. 核心API与代码中的用法
| API函数 | 功能说明 | 代码中应用 |
|---|---|---|
readFontFile(路径) |
加载本地字体文件(.ttf/.ttc) | font->readFontFile("simhei.ttf") |
getFontHeight() |
获取字体默认高度 | 内部自动调用,适配字符大小 |
代码关键点:必须加载中文字体(如黑体simhei.ttf),否则中文会显示为乱码或方框。
osgText::Text
1. 类定义与核心职责
osgText::Text是OSG文字模块的渲染核心类 ,继承自OSG可渲染基类osg::Drawable,专门负责文字内容渲染、三维空间定位、视觉样式控制、视角适配。它依赖Font类提供的字体数据,将字符串转换为三维空间中的可见图形。
简单来说:Text是文字的"渲染载体",决定文字的内容、位置、颜色、显示方式。
2. 类的继承体系
Text类的继承链体现了OSG的渲染设计规范:
osg::Object
↓
osg::Referenced
↓
osg::Drawable(可渲染对象基类,所有场景图形父类)
↓
osgText::Text
- 继承
osg::Drawable:可以直接添加到osg::Geode节点中,参与OSG渲染流程; - 天然支持OSG的场景遍历、裁剪、光照、矩阵变换等核心功能。
3. 核心API与代码中的用法
| API函数 | 功能说明 | 代码作用 |
|---|---|---|
setFont(Font*) |
绑定字体对象 | 关联黑体字体,支持中文渲染 |
setText(字符串) |
设置显示文字内容 | 展示OSG中国官网文字 |
setCharacterSize(float) |
设置字符三维尺寸 | 控制文字大小为0.5 |
setAutoRotateToScreen(bool) |
自动旋转面向屏幕 | 文字始终正对观察者 |
setColor(Vec4) |
设置文字颜色(RGBA) | 纯白色文字 |
setPosition(Vec3f) |
设置三维空间坐标 | 定位在(0,0,-10)位置 |
setAlignment(Alignment) |
设置文字对齐方式 | 居中置顶对齐 |
setAxisAlignment(AxisAlignment) |
设置坐标轴对齐方式 | 屏幕坐标系对齐 |
设计思想
OSG的osgText模块是面向对象设计 的典范,其设计完全符合抽象、封装、继承、多态四大设计原则,我们结合代码逐一解析:
1. 抽象:提取共性,定义核心接口
OSG将文字系统的核心能力抽象为独立接口:
- 抽象
Font的核心能力:加载字体、提供字符数据; - 抽象
Text的核心能力:渲染文字、控制样式; - 无需关心底层字体解析、渲染管线细节,开发者只需调用高层API。
2. 封装:隐藏细节,简化使用
封装是OSG文字模块最核心的设计:
- 细节隐藏:Font类封装了ttf字体解析、字符纹理生成、内存管理等底层逻辑;
- 细节隐藏:Text类封装了字符顶点计算、矩阵变换、屏幕适配等渲染逻辑;
- 对外简化 :开发者仅需
new Font()、new Text()、调用几个set函数,即可完成三维文字渲染,无需理解OSG底层渲染原理。
3. 继承:复用能力,扩展灵活
通过继承实现代码复用与功能扩展:
- Font/Text继承
osg::Referenced:直接获得智能指针内存管理能力; - Text继承
osg::Drawable:直接复用OSG的渲染、场景遍历、裁剪能力; - 继承体系让文字对象与OSG整个框架无缝融合,无需重复开发基础功能。
4. 多态:统一接口,灵活扩展
多态特性让文字系统具备极强的扩展性:
- OSG通过
osg::Drawable的多态,统一管理模型、文字、图片等所有可渲染对象; - 可以自定义继承Font/Text的子类,重写字体加载、文字渲染逻辑,无需修改原有代码;
- 代码中
ref_ptr<Drawable> drawable = new Text()就是多态的直接体现。
代码
本文使用的完整代码(可直接编译运行):
cpp
#include <osg/Group>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgText/Text>
#include <osgText/Font>
#include <osgUtil/Optimizer>
#include <iostream>
#ifdef _WIN32
#include <windows.h>
#endif
using namespace osg;
using namespace osgText;
using namespace std;
// 创建文字渲染节点
ref_ptr<Geode> createText()
{
// 1. 创建文字核心对象
ref_ptr<Text> text = new Text();
// 2. 加载并绑定字体
ref_ptr<Font> font = new Font();
if (!font->readFontFile("simhei.ttf"))
{
cout << "警告:黑体字体文件缺失,请将simhei.ttf放入程序目录!" << endl;
}
// 3. 文字属性配置
text->setFont(font.get());
text->setText("http://www.OsgChina.org ------ OpenSceneGraph 中国官方");
text->setCharacterSize(0.5f); // 字符大小
text->setAutoRotateToScreen(true); // 自动面向屏幕
text->setColor(Vec4(1.0f, 1.0f, 1.0f, 1.0f));// 白色文字
text->setPosition(Vec3f(0.0f, 0.0f, -10.0f));// 三维空间位置
text->setAlignment(Text::CENTER_TOP); // 对齐方式
text->setAxisAlignment(Text::SCREEN); // 屏幕对齐
// 4. 封装为可渲染节点
ref_ptr<Geode> geode = new Geode();
geode->addDrawable(text.get());
return geode.release();
}
int main()
{
#ifdef _WIN32
CoInitialize(nullptr);
#endif
// OSG渲染核心流程
ref_ptr<Viewer> viewer = new Viewer();
ref_ptr<Group> root = new Group();
root->addChild(createText());
// 场景优化
osgUtil::Optimizer optimizer;
optimizer.optimize(root.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
#ifdef _WIN32
CoUninitialize();
#endif
return 0;
}

结合完整代码,我们可以看到OSG文字渲染的标准流程:
- 创建Font对象:加载字体文件,提供字符字形数据;
- 创建Text对象:绑定字体、设置文字内容与样式;
- 封装为Geode节点:Text是Drawable,必须放入Geode才能渲染;
- 加入场景树:通过Group节点管理,最终由OSG Viewer渲染;
- 自动内存管理 :全程使用
ref_ptr智能指针,无需手动delete。
设计亮点:
- 职责分离:Font管字体,Text管渲染,互不耦合;
- 屏幕适配 :
setAutoRotateToScreen(true)实现三维文字的Billboard(公告板)效果,是三维场景文字标注的最优方案; - 跨平台兼容:代码支持Windows/Linux/macOS,仅需适配字体路径。
总结
osgText::Font与osgText::Text是OSG三维文字渲染的两大基石,Font负责字体管理,Text负责渲染展示 。它们的设计完美践行了抽象、封装、继承、多态 四大设计原则,依托OSG底层基类实现了高效、简洁、可扩展的三维文字系统。
