【OSG学习笔记】Day 50: Text与Font

Text与Font

在OpenSceneGraph(OSG)三维渲染开发中,文字渲染是场景标注、信息展示的核心功能。

无论是三维模型的标签、场景的说明文字,还是始终面向屏幕的UI文字,都依赖osgText::TextosgText::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文字渲染的标准流程:

  1. 创建Font对象:加载字体文件,提供字符字形数据;
  2. 创建Text对象:绑定字体、设置文字内容与样式;
  3. 封装为Geode节点:Text是Drawable,必须放入Geode才能渲染;
  4. 加入场景树:通过Group节点管理,最终由OSG Viewer渲染;
  5. 自动内存管理 :全程使用ref_ptr智能指针,无需手动delete。

设计亮点

  • 职责分离:Font管字体,Text管渲染,互不耦合;
  • 屏幕适配setAutoRotateToScreen(true)实现三维文字的Billboard(公告板)效果,是三维场景文字标注的最优方案;
  • 跨平台兼容:代码支持Windows/Linux/macOS,仅需适配字体路径。

总结

osgText::FontosgText::Text是OSG三维文字渲染的两大基石,Font负责字体管理,Text负责渲染展示 。它们的设计完美践行了抽象、封装、继承、多态 四大设计原则,依托OSG底层基类实现了高效、简洁、可扩展的三维文字系统。

相关推荐
于慨2 小时前
flutter开发笔记
笔记
jimmyleeee2 小时前
人工智能基础知识笔记三十九:几个Skills的网站
人工智能·笔记·chatgpt
Hello_Embed2 小时前
嵌入式上位机开发入门(二十二):RTU/TCP 双协议互斥访问寄存器
笔记·网络协议·tcp/ip·嵌入式
绿豆人2 小时前
Go设计模式学习
学习·设计模式·golang
Fanfanaas2 小时前
Linux 系统编程 进程篇(一)
linux·运维·服务器·c语言·开发语言·网络·学习
qq_172805592 小时前
Xinference介绍与学习
学习·xinference
南宫萧幕2 小时前
自动控制原理|稳定性与劳斯判据 知识点+计算题+MATLAB实现全套笔记
笔记·matlab·控制
有个人神神叨叨2 小时前
Claude Managed Agents 快速入门笔记
人工智能·笔记
-To be number.wan3 小时前
重新认识一下“私有继承”
c++·学习