在Opengl中显示字符多用Glut单元中的glutBitmapCharacter进行显示。这样有两个问题。

1、是不能显示汉字。

2、是要glut32.dll库支持。

通过研究可以不用Glut,只用其它的GL库就能实现中文显示

1、加入库

uses
OpenGLContext, GL,glu;

2、生成Opengl显示窗口

var
GLBox:TOpenGLControl;

procedure TForm1.FormCreate(Sender: TObject);
begin
GLBox:=TOpenGLControl.Create(Form1);
GLBox.AutoResizeViewport:=True;
GLBox.Parent:=Self;
GLBox.MultiSampling:=4;
GLBox.Align:=alClient;
GLBox.OnPaint:=@GLboxPaint;
GLBox.Invalidate;

end;

//------------------------------------------------------------------------------

{
用位图方式显示文字
ShowText: 要显示的文字
ShowX: 显示坐标
ShowY: 显示坐标
TextSize: 字体大小
Color: 字体色
TextName:字体 =''为默认字体
isGLZb:是否使用GL坐标 -1到1 0为中心 ,默认不使用 从左上角为0,0
isTM: 是否透明 默认透明
isShowDL:是否独立元素显示 为false时会和上一个元素一起运动 默认独立元素
TextTMD:字体透明度--以下isTM为真时有效
OutTMD:外边透明度
}
procedure glShowBitMapText(ShowText: string;ShowX: GLfloat;ShowY: GLfloat;
TextSize: integer = 12; TextColor: TColor=clWhite;TextName:String='';
isGLZb:Boolean=False; isTM: boolean = True;isShowDL:Boolean=True;TextTMD:Byte=255;OutTMD:Byte=0);
var
bitmap: Graphics.TBitmap;
bitH, bitW: integer;
PixelData: pbyte;
i: integer;
RowSize: integer;
SourceRow, DestRow: integer;
begin
//显示图片
bitmap := Graphics.TBitmap.Create;
bitmap.PixelFormat := pf32bit;
bitmap.Width := 0;
bitmap.Height := 0;
//字边是否填充白色
if isTM then
bitmap.Canvas.Brush.Style := bsClear;

bitmap.Canvas.Font.Name:=TextName;//'Microsoft YaHei UI''楷体';
bitmap.Canvas.Font.Size := TextSize;
//调整图片大小与字符串一致
bitW := bitmap.Canvas.TextWidth(ShowText);
bitH := bitmap.Canvas.TextHeight(ShowText);
bitmap.Width := bitW;
bitmap.Height := bitH;

Bitmap.Canvas.Font.Color := TextColor;
bitmap.Canvas.TextOut(0, 0, ShowText);


// 获取每行像素数据的字节数
RowSize := bitmap.Width * bitmap.RawImage.Description.BitsPerPixel div 8;
if isTM then
begin
//设置透明
SourceRow := bitmap.RawImage.Description.BitsPerPixel div 8;
for i := 0 to (bitmap.RawImage.DataSize div SourceRow) - 1 do
begin
if (bitmap.RawImage.Data + i * SourceRow)^ +
(bitmap.RawImage.Data + i * SourceRow + 1)^ +
(bitmap.RawImage.Data + i * SourceRow + 2)^ > 0 then
(bitmap.RawImage.Data +i * SourceRow + 3)^ := TextTMD
else
(bitmap.RawImage.Data +i * SourceRow + 3)^ :=OutTMD;
end;
end;

// 垂直翻转图像数据
GetMem(PixelData, RowSize * bitmap.Height);
SourceRow := 0;
DestRow := bitmap.Height - 1;
for i := 0 to bitmap.Height - 1 do
begin
Move(bitmap.RawImage.Data[(SourceRow * RowSize)],
PixelData[(DestRow * RowSize)], RowSize);
Inc(SourceRow);
Dec(DestRow);
end;

if isShowDL then
glLoadIdentity;

If NOT isGLZb Then //GL坐标换算
begin
ShowY:=1-((ShowY+bitmap.Height)/(glGetViewportHeight/2));
ShowX:=(1-((ShowX)/(glGetViewportWidth/2)))*-1;
end;

glRasterPos2f(ShowX, ShowY); //使用画布 设置开始位置

if isTM then
begin
glEnable(GL_BLEND);//启动透明层
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawPixels(bitmap.Width, bitmap.Height, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
PixelData);
glDisable(GL_BLEND);
end
else
begin
glDisable(GL_BLEND);//关透明层
glDrawPixels(bitmap.Width, bitmap.Height, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
PixelData);
end;

Freemem(PixelData);
bitmap.Free;
end;

//--------------------------------------------------------------------------

procedure TForm1.GLboxPaint(Sender: TObject);

begin

glClearColor(0.27, 0.53, 0.71, 1.0); 
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glShowBitMapText('中文显示ABC',10,10,16,clRed,'楷体',false,true,true,255,0);

GLbox.SwapBuffers;
end;

利用上面的功能写的字符雨。

 

posted on 2024-03-04 11:52  禁卫军  阅读(14)  评论(0编辑  收藏  举报