在OpenTK中写文本

时间:2016-04-02 08:38:48

标签: c# opentk

我正在使用OpenTK创建一个Graph Drawing程序来完成我的计算机图形练习。

问题是我必须将文本写入glcontrol以指示点的坐标,就像这张图片一样:

enter image description here

请帮忙!

这是我的代码:

private void glControl1_Paint(object sender, PaintEventArgs e)
{
    if (!loaded) // Play nice
    return;

    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
    GL.LineWidth(2);
    DrawingObjects.DrawOxy(leftOr, rightOr, topOr, bottomOr);
    color = Color.Red;
    GL.Color3(color);
    glControl1.SwapBuffers();
}


public static void DrawOxy(int lO, int rO, int tO, int bO)
{
    GL.Color3(Color.Blue);
    GL.Begin(BeginMode.Lines);
    GL.Vertex2(lO, 0);
    GL.Vertex2(rO, 0);
    GL.Vertex2(0, tO);
    GL.Vertex2(0, bO);
    for (int i = lO; i < rO; i+=2)
    {
        GL.Vertex2(i, 0.5);
        GL.Vertex2(i, -0.5);
    }
    for (int j = bO; j < tO; j+=2)
    {
        GL.Vertex2(0.2, j);
        GL.Vertex2(-0.2, j);
    }
        GL.End();
}

抱歉我的英文!

2 个答案:

答案 0 :(得分:3)

与您可能期望的相反,使用像OpenGL这样的低级库,渲染简单的字符串非常困难。但基本上,你遍历字符串,为每个字符渲染纹理四边形。

我的方法是这样,将每个可能的字符存储在一个字符串中。

static string CharSheet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()-=_+[]{}\\|;:'\".,<>/?`~ ";

创建包含这些字符的纹理。保留一行简化了计算。

BitmapFont

然后,当应用程序加载时,为每个字符创建一个VAO,包含顶点位置(四边形的大小)和它的纹理坐标。此字体是等宽的,因此顶点位置只是:

float h = charHeight / (screenHeight / 2);
float w = charWidth / (screenWidth / 2);

Vector2[] vertices = new Vector2[]{
    new Vector2( 0, h),
    new Vector2( w, h),
    new Vector2( w, 0),

    new Vector2( 0, h),
    new Vector2( w, 0),
    new Vector2( 0, 0)
};

然而,纹理坐标取决于CharSheet中的字符索引:

float x1 = (charWidth / textureWidth) * i;
float x2 = (charWidth / textureWidth) * (i + 1);

Vector2[] textureData = new Vector2[] {
    new Vector2 (x1, 0),
    new Vector2 (x2, 0),
    new Vector2 (x2, 1),

    new Vector2 (x1, 0),
    new Vector2 (x2, 1),
    new Vector2 (x1, 1) 
};

要绘制一个角色,只需要指定相同的索引,以及所需的X,Y屏幕坐标:

public static void draw(Shader shader, char character, float x, float y)
{
    // Convert to pixel Co-ordinates
    x = x / (screenWidth/2) - 1;
    y = (screenHeight - y - charHeight) / (screenHeight/2) - 1;
    Vector3 Position = new Vector3 (x, y, 0);

    // Update shader with quad position
    Matrix4 modelMatrix = Matrix4.CreateScale (scale) * Matrix4.CreateTranslation(Position);
    GL.UniformMatrix4(shader.modelviewMatrixLocation, false, ref modelMatrix);

    // Draw
    GL.BindVertexArray( VAOs[ CharSheet.IndexOf( character ) ] );
    GL.DrawArrays (PrimitiveType.Triangles, 0, 6);
}

导致:

Result

答案 1 :(得分:0)

OpenGL和OpenTK不支持任何内置文本呈现。从本质上讲,它们太“低级”了。然而,许多应用程序(例如你的应用程序)需要文本呈现,并且已经做了大量工作来找到通过OpenGL(当然还有OpenTK)呈现文本的有效方法。一种流行的技术基于“距离场”,由2007年SIGGRAPH论文着名,来自Chris Green。在我自己的应用程序中,我使用基于距离字段的技术在OpenTK上实现了对文本呈现的支持,并且对此方法的整体质量,性能和灵活性感到非常满意:

http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf