请教 OpenGL 显示汉字的办法

zing21cn 2008-02-25 07:23:01
请教 OpenGL 显示汉字的办法。最好是Delphi版的代码,C++我看不太懂 :(
...全文
101 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
不得闲 2009-04-11
  • 打赏
  • 举报
回复
给你一个类

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;

taxi 2009-04-04
  • 打赏
  • 举报
回复
在TBitmap上画文字,然后利用这引位图生成纹理就可以了。
http://www.cnblogs.com/youweibin
knowledge_Is_Life 2008-05-01
  • 打赏
  • 举报
回复
我也想知道,正在找這方面的資料~~~~~
UltraBejing 2008-05-01
  • 打赏
  • 举报
回复
都是很好的建议! 值得学习

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧