OpenGL的图像处理功能不可谓不强大,但是本身却不提供文字的显示和处理能力,所以我们只有借助于第三方的库来完成这个功能。这里介绍windows下如何在OpenGL里完成中文(当然也包括其他单字节字符了)的正常显示。
这里介绍windows的一个API函数:wglUseFontBitmapsW() ,函数的声明如下:

WINGDIAPI BOOL WINAPI wglUseFontBitmapsW(HDC, DWORD, DWORD, DWORD);

网上很多人都说wglUseFontBitmaps()函数无法显示中文,其实我们只要用wglUseFontBitmapsW()就好了,这个函数即宽字节版本,这样就可以对双字节字符进行正确处理。不过在调用函数前需要将字符串转成宽字节字符,这里调用MultiByteToWideChar()即可。函数的参数说明如下:
第一个参数是HDC,只要知道调用wglGetCurrentDC函数,就可以得到一个HDC了,这是一个windows的显示设备号。
第二个参数表示第一个要产生的字符。
第三个参数表示要产生字符的总个数。
第四个参数表示第一个字符所对应显示列表的编号。假如这里填1000,则第一个字符的绘制命令将被装到第1000号显示列表,第二个字符的绘制命令将被装到第1001号显示列表,依次类推。
下面是显示中文字符的函数:

void drawCNString(const char* str)
{
    int len, i;
    wchar_t* wstring;
    HDC hDC = wglGetCurrentDC(); //获取显示设备
    GLuint list = glGenLists(1); //申请1个显示列表
    //计算字符的个数
    //如果是双字节字符的(比如中文字符),两个字节才算一个字符
    //否则一个字节算一个字符
    len = 0;
    for(i=0; str[i]!=; ++i)
    {
        if( IsDBCSLeadByte(str[i]) )
            ++i;
        ++len;
    }
    // 将混合字符转化为宽字符
    wstring = (wchar_t*)malloc((len+1) * sizeof(wchar_t));
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstring, len);
    wstring[len] = L;// 只是转义符,它本身的类型是wchar_t
    // 逐个输出字符
    for(i=0; i<len; ++i)
    {
    wglUseFontBitmapsW(hDC, wstring[i], 1, list);
    glCallList(list);
    }
    // 回收所有临时资源
    free(wstring);
    glDeleteLists(list, 1);
}

这个函数的用法比较简单,只要了解了wglUseFontBitmapsW()函数就很容易明白了。调用方法如下:

glColor3f(1.0f, 1.0f, 0.0f);  // 颜色
glRasterPos2f(-0.7f, -0.1f);  // 位置
drawCNString(“中国汉字”);

当然了,我们还可以通过CreateFontA()来创建自己需要的字体,使我们的显示具有各种各样的效果,这里就不再详细讨论了。

暂无相关产品

7则回应给“OpenGL中文字符的显示”

  1. iam070说道:

    OpenGL游戏里一般不用这个函数来输出字符的,效率太低。原先的做法都是用贴图字符显示,现在也有直接渲染ttf字体的。。配置高了,也就无所谓这一点效率了。

    [回复]

    ian 回复:

    是的,这种方法的效率确实比较低,而且占用内存资源也比较大,贴图字符的方式我倒是知道,不过怎么直接渲染ttf字体呢?望指教……

    [回复]

    kennir 回复:

    freetype2用的比较多

    [回复]

  2. iam070说道:

    可能我说错了,现在很多游戏支持直接指定用某种ttf字体作为游戏的字体,可能采用类似freetype的机制吧。

    [回复]

  3. iOver说道:

    不懂 图形开发的飘过。。

    [回复]

  4. http://www.vimer.cn真好,有博客真好,我什么时候才能有一个?

    [回复]

    Dante 回复:

    呵呵,可以搭建一个试试~~主要是要保持经常更新~

    [回复]

发表评论