先上平面文字绘制函数:DrawText(int x, int y, float r, float g, float b, string faceName, float fontSize, string text)
其中:
x,y:是屏幕坐标,及像素坐标;
r,g,b:是RGB颜色,范围:0~1f;
faceName:字体类型;
fontSize:字体大小;
text:绘制的内容;
需要注意的是:DrawText绘制需要用到屏幕像素坐标,在OpenGL中是3维世界坐标,我们绘制的物体通过视图矩阵、投影矩阵、模型矩阵等操作将其映射在2维屏幕上。
所以,若想将text精准的绘制在图形某一位置,就需要知道图形位置映射到屏幕上的坐标,就需要用到project投影函数。
SharpGL中可以用两种方式,两种方式原理上一样,只是SharpGL对其封装了一下,用起来更方便,不需要在重新获取OpenGL的视图矩阵、投影矩阵、模型矩阵。这里我们直接上封装后的方法,原始方法Project有一个对应的UnProject操作,下一节在整理。
在SharpGL命名空间下有一个:SceneGraph命名空间,其主要包括OpenGL对象和场景元素,如:光、材质、纹理、NURBS、着色器等,在该命名空间下有一个扩展类:OpenGLSceneGraphExtensions,这里就封装了投影矩阵以及获取OpenGL当前状态的视图矩阵、投影矩阵、纹理矩阵等方法,这里我们只用投影矩阵:
Vertex SharpGL.SceneGraph.OpenGLSceneGraphExtensions.Project(this OpenGL gl, Vertex vertex)
其中:
vertex:就是OpenGL世界坐标系下的坐标点。
返回值:就是该点对应的屏幕坐标点。
看下效果:绘制一个矩形框,并在四个顶点位置绘制指定坐标值
private void openGLControl1_OpenGLDraw(object sender, RenderEventArgs args)
{
OpenGL gl = this.openGLControl1.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.MatrixMode(OpenGL.GL_PROJECTION);
gl.LoadIdentity();
gl.Ortho(-10, 10, -10, 10, 0.01, 100);
gl.LookAt(eyex, eyey, eyez, 0, 0, 0, 0, 0, 1);//键盘操作相机位置
gl.MatrixMode(OpenGL.GL_MODELVIEW);
gl.LoadIdentity();
DrawBox(gl, 4, 0, 0, 0, true);//绘制边长为4f的矩形框
//三维点映射到屏幕上的二维坐标
var sv = SharpGL.SceneGraph.OpenGLSceneGraphExtensions.Project(gl, new SharpGL.SceneGraph.Vertex(4, 4, 0));
gl.DrawText((int)sv.X, (int)sv.Y, 1f, 1f, 1f, "Courier New", 12, "(4,4)");
sv = SharpGL.SceneGraph.OpenGLSceneGraphExtensions.Project(gl, new SharpGL.SceneGraph.Vertex(0, 0, 0));
gl.DrawText((int)sv.X, (int)sv.Y, 1f, 1f, 1f, "Courier New", 12, "(0,0)");
sv = SharpGL.SceneGraph.OpenGLSceneGraphExtensions.Project(gl, new SharpGL.SceneGraph.Vertex(4, 0, 0));
gl.DrawText((int)sv.X, (int)sv.Y, 1f, 1f, 1f, "Courier New", 12, "(4,0)");
sv = SharpGL.SceneGraph.OpenGLSceneGraphExtensions.Project(gl, new SharpGL.SceneGraph.Vertex(0, 4, 0));
gl.DrawText((int)sv.X, (int)sv.Y, 1f, 1f, 1f, "Courier New", 12, "(0,4)");
//gl.DrawText3D("Arial",12f, 0f, 0.5f, "(0,0)");//绘制立体文字
gl.Flush();
}
效果如下:
DrawText3D立体文字,操作相对就比较单一些:
DrawText3D(string faceName, float fontSize, float deviation, float extrusion, string text)
其中:
faceName:字体类型
fontSize:字体大小
deviation:偏差
extrusion:拉伸深度
text:绘制的内容
DrawText3D好像不支持设置坐标,所以,默认都是在(0,0)位置,(0,1)方向绘制。复杂的3D文字建议采用纹理的方式实现。
注意:不管是DrawText平面文字还是DrawText3D立体文字,都不能绘制中文字符,text设置中文字符会显示乱码。
查阅相关资料,OpenGL本身是无法支持绘制中文字符的,可以用外部第三方库实现,比如:FreeType,具体没研究过。
测试程序在这里:SharpGL测试范例