解决Dear ImGUI无法显示中文的问题

文章目录[x]
  1. 1:使用支持中文的字体
  2. 2:使用字体前要加载字体
  3. 3:确保字符串是unicode格式的
  4. 4:检查文字图集
  5. 5:自言自语
  6. 6:参考

今天使用Dear ImGui时发现无法显示中文,经过折腾最终解决了这个问题。

使用支持中文的字体


有些字体只支持英文,所以在选择字体时一定要注意

 

使用字体前要加载字体


ImGuiIO& io = ImGui::GetIO();
ImFont* font = io.Fonts->AddFontFromFileTTF("Resources/Fonts/zhankuwenyiti.ttf", 22.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());

这里要注意的是

io.Fonts->GetGlyphRangesChineseSimplifiedCommon(); // 这个是只加载常用汉字,是参考的维基百科上的2500个汉字,但是现在的常用汉字是3500个,所以少了1000个
io.Fonts->GetGlyphRangesChineseFull();  // 这个是加载字体中所有的汉字

在这里扁扁推荐先使用加载常用汉字的方法,如果遇到有文字不显示再改用加载所有汉字的方式。
比如扁扁发现,2500个汉字中竟然不包括  “呵呵” ,那我只有真的呵呵了。

 

确保字符串是unicode格式的


这里以C++举例,通常有两种方式

  1. 如果使用的的是C++11,那么直接在字符串前面加上 u8 即可,如 u8"123abc你好"
  2. 使用转换函数自己转换,如下
View Code
// AMD64 如果你和我一样是AMD64,那么请加上下面这句宏
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnls.h>

// UTF8转std:string
// 转换过程:先将utf8转双字节Unicode编码,再通过WideCharToMultiByte将宽字符转换为多字节。
static std::string UTF82String(const std::string& str)
{
    int nwLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
    wchar_t* pwBuf = new wchar_t[nwLen + 1];    //一定要加1,不然会出现尾巴
    memset(pwBuf, 0, nwLen * 2 + 2);
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), pwBuf, nwLen);
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
    char* pBuf = new char[nLen + 1];
    memset(pBuf, 0, nLen + 1);
    WideCharToMultiByte(CP_ACP, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

    std::string strRet = pBuf;

    delete[]pBuf;
    delete[]pwBuf;
    pBuf = NULL;
    pwBuf = NULL;

    return strRet;
}

// std:string转UTF8
static std::string String2UTF8(const std::string& str)
{
    int nwLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
    wchar_t* pwBuf = new wchar_t[nwLen + 1];    //一定要加1,不然会出现尾巴
    ZeroMemory(pwBuf, nwLen * 2 + 2);
    ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), pwBuf, nwLen);
    int nLen = ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, -1, NULL, NULL, NULL, NULL);
    char* pBuf = new char[nLen + 1];
    ZeroMemory(pBuf, nLen + 1);
    ::WideCharToMultiByte(CP_UTF8, 0, pwBuf, nwLen, pBuf, nLen, NULL, NULL);

    std::string strRet(pBuf);

    delete[]pwBuf;
    delete[]pBuf;
    pwBuf = NULL;
    pBuf = NULL;

    return strRet;
}

 

检查文字图集


一般经过上面3个步骤,就能正常显示中文,但是如果依然不显示中文,那么就是异常情况。这里提供一种检测方式,就是查看文字图集。

使用如下代码显示测试窗口

ImGui::ShowTestWindow();

 

然后按下面图示找到图集

如上图所示,则是图集加载成功的样子的。(旧版的测试窗口可能图集位置不同)

 

自言自语


ImGUI也是扁扁最近发现的一个十分强大的GUI工具,有人把它玩出了花样。比如:

  • 有人用它写了一套游戏引擎UI,比如集成进 Ogre,Cocos,UE4。
  • 有人用它写了一套NodeEditor(类似Unity中ShaderGraphics那种连连看),
  • 有人觉得Unity自带的ImGUI(就是UnityEditor的UI)太难用,把ImGUI集成进Unity,替换Unity的ImGUI,比如 Unity全新UI系统"dear imgui"

而且,很多人对ImGUI做出了扩展,使其能够使用C#,Python,Lua,GO,Java,JS作为开发语言。

总之,扁扁也是刚了解到这个GUI工具,暂时还没有体会到它的强大,希望慢慢了解吧。

 

可以在里看到N多期的大神show https://github.com/ocornut/imgui/issues/772

 

参考


UTF8与std:string互转

Don't display Chinese

 

Dear ImGUI地址:imgui

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像