OSG 支持中文文字显示,但需要正确配置字体和文本设置。以下是 OSG 中处理中文文字的完整方法:
1. 基本中文文本显示
1.1 使用 osgText 显示中文
#include <osgText/Text>
osgText::Text* createChineseText(const std::string& content, const osg::Vec3& position)
{
osgText::Text* text = new osgText::Text;
// 设置中文字体文件路径(重要!)
text->setFont("simhei.ttf"); // Windows系统黑体
// 或 text->setFont("/usr/share/fonts/wqy-microhei/wqy-microhei.ttc"); // Linux文泉驿微米黑
text->setCharacterSize(20.0f);
text->setPosition(position);
text->setText(content, osgText::String::ENCODING_UTF8); // 必须使用UTF-8编码
// 设置文本对齐方式
text->setAlignment(osgText::Text::LEFT_BASE_LINE);
// 解决中文显示模糊问题
text->setBackdropType(osgText::Text::OUTLINE);
text->setBackdropColor(osg::Vec4(0,0,0,1));
text->setBackdropOffset(0.07f);
return text;
}
1.2 添加到场景
osg::Geode* textGeode = new osg::Geode;
textGeode->addDrawable(createChineseText("你好,OpenSceneGraph!", osg::Vec3(100,100,0)));
root->addChild(textGeode);
2. 中文支持的常见问题解决
2.1 字体设置问题
解决方案:
-
确保字体文件存在且OSG可以访问
-
推荐使用以下中文字体:
-
Windows:
simhei.ttf
(黑体),simsun.ttc
(宋体) -
Linux:
wqy-microhei.ttc
(文泉驿微米黑) -
macOS:
STHeiti.ttf
(华文黑体)
-
2.2 中文显示为方框或乱码
原因:编码不正确或字体不支持中文
解决方法:
// 确保文本以UTF-8编码传递
std::string chineseText = "中文内容"; // 源文件必须保存为UTF-8编码
text->setText(chineseText, osgText::String::ENCODING_UTF8);
// 或者从UTF-8文件读取
std::ifstream t("chinese.txt");
std::string content((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
text->setText(content, osgText::String::ENCODING_UTF8);
2.3 中文显示模糊
优化方案:
text->setFontResolution(128, 128); // 提高字体分辨率
text->setCharacterSize(30.0f); // 增大字号
text->setBackdropType(osgText::Text::OUTLINE); // 添加轮廓
3. 高级中文文本处理
3.1 多语言切换
class LanguageManager : public osg::Referenced {
public:
void setLanguage(const std::string& lang) { _currentLang = lang; }
std::string getText(const std::string& key) {
return _dictionary[_currentLang][key];
}
void addTranslation(const std::string& lang, const std::string& key, const std::string& value) {
_dictionary[lang][key] = value;
}
private:
std::string _currentLang;
std::map<std::string, std::map<std::string, std::string> > _dictionary;
};
// 使用示例
osg::ref_ptr<LanguageManager> langMgr = new LanguageManager;
langMgr->addTranslation("zh", "welcome", "欢迎");
langMgr->addTranslation("en", "welcome", "Welcome");
text->setText(langMgr->getText("welcome"), osgText::String::ENCODING_UTF8);
3.2 中文文本特效
// 3D立体文字
osgText::Text3D* createChineseText3D(const std::string& content)
{
osgText::Text3D* text = new osgText::Text3D;
text->setFont("simhei.ttf");
text->setCharacterSize(20.0f);
text->setText(content, osgText::String::ENCODING_UTF8);
text->setDepth(5.0f); // 立体厚度
return text;
}
// 文字淡入淡出动画
class TextFadeCallback : public osg::NodeCallback {
public:
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) {
osgText::Text* text = dynamic_cast<osgText::Text*>(node->asGeode()->getDrawable(0));
if(text) {
static float alpha = 0.0f;
alpha += 0.01f;
if(alpha > 1.0f) alpha = 0.0f;
text->setColor(osg::Vec4(1,1,1,alpha));
}
traverse(node, nv);
}
};
4. 中文输入处理
4.1 接收中文输入
class ChineseInputHandler : public osgGA::GUIEventHandler {
public:
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
if(ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) {
// 处理中文输入法组合键
// 实际应用中需要结合IM框架如ibus/fcitx
}
return false;
}
};
5. 推荐的中文字体资源
-
Windows系统自带:
-
黑体:
simhei.ttf
-
宋体:
simsun.ttc
-
-
开源字体:
-
文泉驿微米黑:
wqy-microhei.ttc
-
思源黑体:
SourceHanSansSC-Regular.otf
-
-
macOS系统:
-
华文黑体:
STHeiti.ttf
-
苹方:
PingFang.ttc
-
6. 常见问题FAQ
Q: 为什么我的中文显示为方框?
A: 1) 检查字体路径是否正确 2) 确保文本以UTF-8编码传递 3) 确认字体包含中文字符集
Q: 如何提高中文显示质量?
A: 1) 增大字号 2) 提高字体分辨率 3) 使用抗锯齿 4) 添加文字轮廓
Q: 如何实现中文换行?
A: 使用\n
换行符或设置最大宽度自动换行:
text->setMaximumWidth(200.0f); // 自动换行宽度
text->setLayout(osgText::Text::LEFT_TO_RIGHT); // 从左到右布局