请教 OpenGL 显示汉字的办法。最好是Delphi版的代码,C++我看不太懂 :(

解决方案 »

  1.   

    在TBitmap上画文字,然后利用这引位图生成纹理就可以了。
    http://www.cnblogs.com/youweibin
      

  2.   

    给你一个类unit DxOpenGlFont;interface
    uses OpenGL,Windows,Classes,Graphics;type
      TGlFont = class(TFont)
      private
      public
        constructor Create;
        procedure ShowText(const x,y: Integer;Text: string);
        procedure Show2DText(Text: string);
      end;
    implementation{ TGlFont }constructor TGlFont.Create;
    begin
      inherited Create;end;procedure TGlFont.Show2DText(Text: string);
    var
      FTextList: array[0..254] of Char;
      gmf: array[0..25] of GLYPHMETRICSFLOAT;
      m_iCount,i,j,ich,cch: integer;
      m_listbase: GLuint;
      DC: HDC;
      TextASCII: Integer;
    begin
      m_iCount := Length(Text);
      DC := wglGetCurrentDC;
      glPushMatrix();
      SelectObject(DC,Handle);
      i := 1;j := 0;
      m_listbase := glGenLists(256);
      glColor3f(GetRValue(Color)/255.0,GetGValue(Color)/255.0,GetBValue(Color)/255.0);
      while i<=m_iCount do
      begin
         TextASCII := Ord(Text[i]);
         if IsDBCSLeadByte(TextASCII) then
         begin
           //判断是否为双字节
            ich := TextASCII;
            ich := (ich shl 8) +256; //256为汉字内码“偏移量”
            ich := ich + Ord(Text[i+1]);
            inc(i,2);
            wglUseFontOutlines(DC,//字体轮廓设备联系DC
                ich, //要转换为显示列表的第一个字符
                1, //要转换为显示列表的字符数
                m_listbase+j,//显示列表的基数
                1.0, //指定与实际轮廓的最大偏移量
                0,//0.15f, //在Z轴负方向的值
                WGL_FONT_POLYGONS, //指定显示列表线段或多边形
                @gmf[j]); //接受字符的地址
            FTextList[j] := Char(j);
            Inc(j);
         end
         else
         begin
           cch := TextASCII;
           inc(i);
           wglUseFontOutlines(DC, //字体轮廓设备联系DC
               cch,//要转换为显示列表的第一个字符
               1,//要转换为显示列表的字符数
               m_listbase+j,//显示列表的基数
               0.0,//指定与实际轮廓的最大偏移量
               0.0,//0.15f,//在Z轴负方向的值
               WGL_FONT_POLYGONS, //指定显示列表线段或多边形
               @gmf[j]);//接受字符的地址
            FTextList[j] := Char(j);
            inc(j);
         end;
      end;
       glPushAttrib(GL_LIST_BIT);
       glListBase(m_listbase);
       glCallLists(m_iCount, GL_UNSIGNED_BYTE, @FTextList);
       glPopAttrib();
       glPopMatrix();
       glColor3f(1.0,1.0,1.0);
    end;procedure TGlFont.ShowText(const x, y: Integer; Text: string);
    var
      rect: TRect;
      left,top: GLfloat;
      bmpHandle,hPrevBmp: HBITMAP;
      bm: BITMAP;
      TextSize: TSize;
      pBmpBits: PUCHAR;
      Dc,hMemDC: HDC;
      hOldFont,hPrevFont: HFONT;
      bufsize: integer;
      Binf: BITMAPINFO;
    begin
       // 保存原投影矩阵,将投影矩阵设为平行投影
       glMatrixMode( GL_PROJECTION );
       glPushMatrix();
       glLoadIdentity();
       glOrtho( 0, 1152, 0, 864, -1, 1 );   // 保存原模型变换矩阵,平移至( x, y )
       glMatrixMode( GL_MODELVIEW );
       glPushMatrix();
       glLoadIdentity();
       GetClientRect(GetActiveWindow(),rect);
       left := x;top := y;
       glTranslatef(left,top,0);   
       Dc := wglGetCurrentDC;
       hOldFont := HFONT(SelectObject(Dc, Handle));//保存原字体
       GetTextExtentPoint32(Dc, PChar(Text), Length(Text), TextSize); //文字的矩形大小   bmpHandle := CreateBitmap(TextSize.cx, TextSize.cy,1, 1, nil);
       hMemDC := CreateCompatibleDC(dc);
       if hMemDC <> 0 then
       begin
         hPrevBmp := HBITMAP(SelectObject(hMemDC,bmpHandle));
         hPrevFont := HFONT(SelectObject(hMemDC, Handle));
         SetBkColor(hMemDC, RGB(0, 0, 0));
         SetTextColor(hMemDC,RGB(255,255,255));
         SetBkMode(hMemDC, OPAQUE);
         TextOut(hMemDC, 0, 0,PChar(Text),Length(Text));
         //把GDI位图复制到DIB
         SelectObject(dc,bmpHandle);
         GetObject(bmpHandle, sizeof(bm), @bm);
         Textsize.cx := (bm.bmWidth + 31) and (not 31);
         Textsize.cy := bm.bmHeight;
         bufsize := Textsize.cy * (((bm.bmWidth + 31) and  (not 31)) div 8);
         GetMem(pBmpBits,bufsize*sizeof(UChar));
         
         Binf.bmiHeader.biSize := SizeOf(Binf.bmiHeader);
         Binf.bmiHeader.biWidth := bm.bmWidth;
         Binf.bmiHeader.biHeight := bm.bmHeight;
         Binf.bmiHeader.biPlanes := 1;
         Binf.bmiHeader.biBitCount := 1;
         Binf.bmiHeader.biCompression := BI_RGB;
         Binf.bmiHeader.biSizeImage := bufsize;
         Binf.bmiHeader.biXPelsPerMeter := 1;
         Binf.bmiHeader.biYPelsPerMeter := 1;
         Binf.bmiHeader.biClrUsed := 0;
         Binf.bmiHeader.biClrImportant := 0;     GetDIBits(Dc, bmpHandle, 0, bm.bmHeight, pBmpBits, binf,DIB_RGB_COLORS);
         SelectObject(hMemDC,hPrevBmp);
       end;
       DeleteDC(hMemDC);
       DeleteObject(bmpHandle);
       SelectObject(Dc, hOldFont);
       {显示文字}
       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
       glColor3f(GetRValue(Color)/255.0,GetGValue(Color)/255.0,GetBValue(Color)/255.0);
       glRasterPos2i(x,y);
       glBitmap(Textsize.cx, Textsize.cy, 0.0, 2.0, Textsize.cx+2.0, 0.0, pBmpBits);
       Dispose(pBmpBits);
       // 恢复投影矩阵和模型变换矩阵
       glMatrixMode(GL_PROJECTION);
       glPopMatrix();
       glMatrixMode(GL_MODELVIEW);
       glPopMatrix();
       glColor3f(1.0,1.0,1.0);
    end;end.//用法:
    var
    f: TGlFont;
    begin
       F := TGlFont.Create;
       F.Color := clBlue;
       F.Name := '宋体';
       F.Size := 16;
       F.Style := [fsBold]
       f.ShowText(100,100,'我是不得闲,哈哈,测试');
       f.free;
    end;