显示英文和数字是可以的,如何用opengl显示中文字体。谢谢。

解决方案 »

  1.   

    Font_CB: TComboBox;Font_CB.items := screen.fonts;试一下
      

  2.   

    不太清楚:)
    我只知道一种办法,把文字画到一个位图上面,再在OPENGL中贴图。
      

  3.   

    Windows平台下OpenGL汉字处理方法 出 处:品雪其寒
    [ 2001-12-22 ] 作 者:品雪 
      目 录
      1 基本思想
      2 具体说明
      3 示意代码
     1、基本思想
      1)用wglUseFontOutlines或wglUseFontBitmaps为每个字生成一个List。
      2)为每个字调用glCallList()或为一个字串调用glCallLists()。2、具体说明
      OpenGL设计时考虑了非ASCII字符集文字的需求,在OpenGL中使用汉字是没有问题的。由于Windows95/NT所提供的wgl环境只在单缓冲时可以使用GDI函数,所以即使只是想写一些提示文字也要用这种方法。为此,Microsoft提供了wglUseFont??()函数,它的原型在wingdi.h中可以看到。如果只使用英文字符,那你可以使用类似下面的代码。
    · 在OpenGL初始化的末尾建立字体:#define LISTBASE 1000
    wglUseFontBitmaps(hDC,0,255,LSITBASE);
    · 在需要输出文字的地方调用:char pMyString="OpenGL Text Info";
    glListBase(LISTBASE);
    glCallLists(strlen(pMyString),GL_UNSIGNED_BYTE,pMyString);
      按我们已经习惯的思维逻辑,只要指定一个中文字体,用同样的方法就应该可以显示中文。但实际上并非如此,这样做会有两个问题:
    · 问题一
    一个中文字体至少有6~7千个字,需要占用很多的内存来保存这些List数据,严重影响程序性能。其解决的办法是只生成所用到字的List。简单的方法是在字串显示函数中对每个字做一次wglUseFont??(),再call对应的List,用完再删除这个List。显然这个法子性能也不会很好。
    改进的法子很多,举两个我想到了的例子:1)在程序中建立一个清单,每个字处理之前先到清单里找,如果有就直接CallList,否则生成List并加到清单里。2)对要大量使用文字的程序可以建立一个小字库,甚至可以是以编译(compiled)List形式存在的小字库。正如当年我们在DOS下处理汉字一样。
    · 问题二
    更重要的是由于wglUseFont??()函数的Microsoft特色,这样做根本就不能显示汉字。其解决的办法是自己处理双字节代码。将一个汉字的两个字节组合成一个DWORD传给wglUseFont??()。
    备注:wglUseFont系列函数其实都有asc和widechar两个版本,正如其实的字符串函数一样,这是Windows系统为简化制作国际化程序而设计的,可是,不幸的是,wglUseFont??W()工作并不正常,我真不明白,为什么?在试完这个问题之后,终于明白其中的原因,正如MSDN屏保程序(MultiMedia Opengl gl3dtext)作者所说的,一个臭虫。
    3、示意代码  // 注意,以下代码必须选用中文字体才能工作,
      // 但可以处理中英文混合字串,Win95/WinNT4下BCB测试通过
      void glDrawString(unsigned char *str)
      {
        GLYPHMETRICSFLOAT pgmf[1];
        HDC hDC=wglGetCurrentDC();
        DWORD dwChar;
        int ListNum;    for(size_t i=0;i< strlen((char *)str);i++)
        {
          if(IsDBCSLeadByte(str[i]))
          {
            dwChar=(DWORD)((str[i]><8)|str[i+1]);i++;
          }
          else
            dwChar=str[i];
          ListNum=glGenLists(1);
          bool ret=false;
          ret=wglUseFontOutlines(hDC,dwChar,1,ListNum,0.0,0.1,WGL_FONT_LINES,pgmf);
          glCallList(ListNum);
          glDeleteLists(ListNum,1);
        }
      }  提示:在BCB中用Form作OpenGL绘制时,可以利用Form的字体设置信息,在Form初始化或更改字体时显式建立该字体并将它指定给DC,就象这样:  void CreateFont(void)
      {
        HFONT HFont,HOldFont=0;
        LOGFON LogFont;    // 取字体信息
        GetObject(Form1->Font->Handle,sizeof(LOGFONT),&LogFont);    // 建立字体
        HFont = CreateFontIndirect(&LogFont);    // 选用字体
        HOldFont=SelectObject (Form1->hDC, HFont);    // 清除已经不用的字体
        DeleteObject(HOldFont);
      }
      

  4.   

    myling(贫困户)  这方法 太不实际了!还是利用2D纹理 实现吧!
      

  5.   


    procedure TMainFrm.FontIni;//在OnCreat中设置字体
    var
      H_CurrFont, H_OldFont: HFONT;
      lf: LOGFONT;
    begin
      Fillchar( lf, sizeof( LOGFONT ), 0 );  lf.lfHeight := -100;
      lf.lfWidth := 0;
      lf.lfEscapement := 0;
      lf.lfOrientation := 0;
      lf.lfWeight := FW_NORMAL;
      lf.lfItalic := 0;
      lf.lfUnderline := 1;
      lf.lfStrikeOut := 0;
      lf.lfCharSet := GB2312_CHARSET;
      lf.lfOutPrecision := OUT_TT_PRECIS;
      lf.lfClipPrecision := CLIP_DEFAULT_PRECIS;
      lf.lfQuality := PROOF_QUALITY;
      lf.lfPitchAndFamily := VARIABLE_PITCH or TMPF_TRUETYPE or FF_MODERN;
      lf.lfFaceName := '黑体';  H_CurrFont := CreateFontIndirect( lf );
      H_OldFont := HFONT( SelectObject( GLScenViewMain.RenderDC, H_CurrFont ) );
    end;
    procedure TMainFrm.TextOut( TextStr: string );//输出文字
    var
      I, J, ich: Longword;
      cch: char;
      FListBase: GLuint;
      agmf: array[0..128] of GLYPHMETRICSFLOAT;
      COText: array[0..128] of char;
      FTextList: array[0..128] of BYTE;
    begin  FListBase := 1000;
      i := 0;
      j := 0;
      ich := 0;  Strcopy( COText, '太阳出来亮晶晶!' ); //要输出的文本  while Byte( COText[i] ) <> 0 do
      begin
        if IsDBCSLeadByte( Byte( COText[i] ) ) then
        begin ///判断是否为双字节
          ich := Byte( COText[i] );
          ich := ich shl 8;
          ich := ich + Byte( COText[i + 1] );
          I := I + 2;
          wglUseFontOutlines( GLScenViewMain.RenderDC, /////字体轮廓设备联系DC
            ich, /////要转换为显示列表的第一个字符
            1, /////要转换为显示列表的字符数
            1000 + j, /////显示列表的基数
            0.0, /////指定与实际轮廓的最大偏移量
            0.0, /////在Z轴负方向的值
            WGL_FONT_POLYGONS, /////指定显示列表线段或多边形
            @agmf[j] ); /////接受字符的地址
          FTextList[j] := j;
          inc( J );
        end
        else
        begin
          cch := COText[i];
          inc( I );
          wglUseFontOutlines( GLScenViewMain.RenderDC, /////字体轮廓设备联系DC
            Longword( cch ), /////要转换为显示列表的第一个字符
            1, /////要转换为显示列表的字符数
            1000 + j, /////显示列表的基数
            0.0, /////指定与实际轮廓的最大偏移量
            0.0, /////在Z轴负方向的值
            WGL_FONT_POLYGONS, /////指定显示列表线段或多边形
            @agmf[j] ); /////接受字符的地址      FTextList[j] := j;
          inc( J );
        end;
      end;  glListBase( FListBase );
      glPushMatrix;
      glTranslatef( 50, 50, 0 ); ////要显示的文本位置
      glScalef( 100.0, 100.0, 0 );//放大
      glCallLists( J, GL_UNSIGNED_BYTE, @FTextList );
      glPopMatrix;end;