osg osgText::Text 中文乱码问题修复 解决中
#include <osgDB/ConvertUTF>
osg::Camera* osgWidget::createTextHUD()
{
osgText::Font* fontHei = osgText::readFontFile("Fonts/simkai.ttf");
text->setFont(fontHei);
// 步骤二:设置 文字颜色: 红色, 透明度有效(opengl需要额外开启透明通道)
text->setColor(osg::Vec4f(1.0, 1.0, 1.0, 1.0));
// pText->setColor(osg::Vec4f(1.0, 1.0, 1.0, 0.2));
// 步骤三:设置 文字位置(设置文字框的中心点的坐标)
text->setPosition(osg::Vec3f(0, 0, 0));
// 步骤四:设置 文字方向
//text->setAxisAlignment(osgText::Text::XZ_PLANE);
// 步骤五:设置 大小模式(测试当前没发现有什么区别)
text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
// pText->setCharacterSizeMode(osgText::Text::SCREEN_COORDS);
// pText->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
// 步骤六:设置 分辨率
text->setFontResolution(50, 50);
// 步骤七:设置 对齐方式
text->setAlignment(osgText::Text::LEFT_CENTER);
// 步骤八:设置 输出格式
text->setLayout(osgText::Text::LEFT_TO_RIGHT);
// pText->setLayout(osgText::Text::RIGHT_TO_LEFT);
// pText->setLayout(osgText::Text::VERTICAL);
// 步骤九:设置 绘制模式
// pText->setDrawMode(osgText::Text::TEXT);
// pText->setDrawMode(osgText::Text::BOUNDINGBOX);
// pText->setDrawMode(osgText::Text::FILLEDBOUNDINGBOX);
// pText->setDrawMode(osgText::Text::ALIGNMENT);
// 步骤十:设置 背景类型
// pText->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
// pText->setBackdropType(osgText::Text::DROP_SHADOW_CENTER_RIGHT);
// pText->setBackdropType(osgText::Text::DROP_SHADOW_TOP_RIGHT);
// pText->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_CENTER);
// pText->setBackdropType(osgText::Text::DROP_SHADOW_TOP_CENTER);
// pText->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_LEFT);
// pText->setBackdropType(osgText::Text::DROP_SHADOW_CENTER_LEFT);
// pText->setBackdropType(osgText::Text::DROP_SHADOW_TOP_LEFT);
// pText->setBackdropType(osgText::Text::OUTLINE);
text->setBackdropType(osgText::Text::NONE);
// 步骤十一:设置 颜色倾斜模式
text->setColorGradientMode(osgText::Text::SOLID);
// pText->setColorGradientMode(osgText::Text::PER_CHARACTER);
// pText->setColorGradientMode(osgText::Text::OVERALL);
// 以上部分属性是默认的,可以不设置,此处为阅读都写出来
QString version = "V1.16.0";
QString textString = QString("OsgDemo %1(渲染中文文字)").arg(version);
std::string str = osgDB::convertStringFromCurrentCodePageToUTF8(textString.toStdString());
text->setText(str, osgText::String::ENCODING_UTF8);
//
//压入顶点
osg::Vec3Array *vecArray = new osg::Vec3Array;
vecArray->push_back(osg::Vec3(0.0, 0.0, 0.0));
vecArray->push_back(osg::Vec3(200.0, 0.0, 0.0));
vecArray->push_back(osg::Vec3(200.0, 100.0, 0.0));
vecArray->push_back(osg::Vec3(0.0, 100.0, 0.0));
geometry->setVertexArray(vecArray);
//法线
osg::Vec3Array *vecNorm = new osg::Vec3Array;
vecNorm->push_back(osg::Vec3(0.0, 0.0, 1.0));
geometry->setNormalArray(vecNorm);
geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
//设置纹理
osg::Vec2Array *vec2Coord = new osg::Vec2Array;
vec2Coord->push_back(osg::Vec2(0.0, 0.0));
vec2Coord->push_back(osg::Vec2(1.0, 0.0));
vec2Coord->push_back(osg::Vec2(1.0, 1.0));
vec2Coord->push_back(osg::Vec2(0.0, 1.0));
geometry->setTexCoordArray(0, vec2Coord);
osg::DrawArrays *drawArrays = new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4);
//drawArrays->setPrimitiveSet(0,drawArrays1);
geometry->addPrimitiveSet(drawArrays);
osg::Image* image = osgDB::readImageFile("############.jpg");
osg::Texture2D* texture2d = new osg::Texture2D;
texture2d->setDataVariance(osg::Object::DYNAMIC);
texture2d->setImage(image);
geometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2d, osg::StateAttribute::ON);
//关闭灯光
geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
//geode->addDrawable(geometry);
geode->addDrawable(text);
camera->addChild(geode);
return camera;
}
看似中文 其实是乱码
而0xEFBFBDEFBFBD被GBK解码时,正好就是锟(0xEFBF),斤(0xBDEF),拷(0xBFBD)。
而 GBK 编码依然采用双字节编码方案,因此上面的 6 字节0xEFBFBDEFBFBD,就被拆成了 3 个 2 字节字符即0xEFBF, 0xBDEF, 0xBFBD 对应 GBK 编码里面就是:锟(0xEFBF),斤(0xBDEF),拷(0xBFBD)。
最后粗暴解决办法
osgText::Font* fontHei = osgText::readFontFile("fonts/kaiti.ttf");
text->setFont(fontHei);
text->setText(L"(作者:PHP代码 博客地址: blog.csdn.net/phpxi)");
效果图
https://www.cnblogs.com/herd/p/11107858.html
字符串 前加L的意思,转码是 2个字节!!!!!! L L L 字母是 关键 灵魂
字符串 前 L 和 _T()的含义_心情第一的博客-CSDN博客
上面L 办法只是针对字符串 如果是 wchar_t* 这种类型的
使用 LC_ALL 进行转换 用法一致
text->setText(LC_ALL+ mTextstr);
https://www.cnblogs.com/HsinTsao/p/7105510.html
参考文章
Python模拟锟斤拷等各类乱码_python 锟斤拷锟斤拷_小小明-代码实体的博客-CSDN博客