Open Scene Graph中文文字处理

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. 推荐的中文字体资源

  1. Windows系统自带

    • 黑体:simhei.ttf

    • 宋体:simsun.ttc

  2. 开源字体

    • 文泉驿微米黑:wqy-microhei.ttc

    • 思源黑体:SourceHanSansSC-Regular.otf

  3. 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); // 从左到右布局

猜你喜欢

转载自blog.csdn.net/byxdaz/article/details/147080579
今日推荐