w_chisum's picture

Problem with TextPrinter

I'm using the GLControl on a System.Windows.Forms.Form. The code below should draw a line from the top/left coner (-100/100) to the bottom/right (100,-100) corner. That's part of the code works correct.
But the text "ABC" is also displayed in the top/left corner and not in the center of the control (0/0) as expected. Does anybody know why?

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    if (!this.DesignMode)
    {
        MakeCurrent();
        GL.MatrixMode(MatrixMode.Projection);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
        GL.LoadIdentity();
        GL.Ortho(-100, 100, -100, 100, -100, 100);
        GL.Viewport(0, 0, Width, Height);
        DrawLineText();
        SwapBuffers();
    }
}
private void DrawText()
{
    GL.ClearColor(Color.White);
    GL.Color3(Color.Green);
    GL.Begin(BeginMode.LineLoop);
    GL.Vertex2(-100, 100);
    GL.Vertex2(100, -100);
    GL.End();
    TextHandle textHandle;
    TextureFont font = new TextureFont(new Font(FontFamily.GenericSansSerif, 8));
    ITextPrinter textPrinter = new TextPrinter();
    textPrinter.Prepare("ABC", font, out textHandle);
    textPrinter.Begin();
    GL.Translate(0,0,0);
    textPrinter.Draw(textHandle);
    textPrinter.End();
}

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
georgwaechter's picture

i would guess the text printer does not print the text in the world matrix, but directly on to the screen. So your Gl.Ortho() calls don't have any effect on the coordinates passed to the text printer.

w_chisum's picture

that's true (the left/top corner is always 0/0 and the right/bottom coner is always width/height). but is it bug of the text printer?
how can i change the 'coordinate system' of the text printer? is there a workaround?

objarni's picture

The font system is undergoing design changes.. I wouldn't depend too heavily on them.

Instead, I would create my own texture-bitmap-font, and use GL-Quads to print to the screen, just as any other triangles/polygons.

my 2 cc

segfaultvicta's picture

Hello!

There seems to have been a lot of work done since October 08; is there any fix to this? I recently migrated my project from Tao to OpenTK pretty much solely to take advantage of TK's text functionality, but we're running into essentially the exact same problem. Is there a workaround we can use to apply a transformation to put the text coordinate system in line with our viewport projection?

Barring that is there some kind of tutorial for generating texture bitmap fonts using OpenTK and being able to control string positioning? I'd rather not have to do this 'by hand' as it were, but if the text printer is bugged, we may have to. =/

Thank you!

the Fiddler's picture

This is supported now: simply omit the textPrinter.Begin() and textPrinter.End() lines and handle the projection and modelview transformation manually. These functions simply apply a default ortho projection and restore your original projection afterwards.

segfaultvicta's picture

Hmm.

That's what we'd been trying to do originally. Here's the code we were using, edited somewhat for clarity:

internal Font displayFont = new Font("arial", 32.0f, FontStyle.Regular);
internal TextPrinter printer = new TextPrinter();

....

(in the method where we're trying to draw text to the position of a button:)

GL.PushMatrix();
GL.Translate(button.Location.X, button.Location.Y, 0.0);
printer.Print("O HAI TEXT IS RENDERING", displayFont, Color.Black);
GL.PopMatrix();

Elsewhere in the code we're drawing quadric disks, we're Translate()ing to the correct location, and then drawing the disks, so we know it's not a problem with the screen coordinates not playing nicely with the projection we're using. The button Location and the quadric drawing location are in essentially the same numerical ranges, but the text is completely invisible:

GL.Translate(radial.Centre().X, radial.Centre().Y, 0.0f);
GL.Color3(1.0, 1.0, 1.0);
Glu.QuadricDrawStyle(quadric, QuadricDrawStyle.Fill);
Glu.Disk(quadric, Core.radialMargin / 2.0, Core.radialMargin, 40, 1);
printer.Print("Trying to render some text here", displayFont, Color.Black);

Oddly we can get text to render if we use printer.Begin() and printer.End() and offset the text location, but in that circumstance we can't get the coordinate systems to play nicely together. From your initial response it strikes me that the code we have above -should- be working, yet it's not.

Any thoughts?

Thanks!

the Fiddler's picture

TextPrinter.Print(...) calculates the layout of the text using absolute 2d coordinates. To get correct output, you will have to scale the output by the inverse of your viewport width and height (GL.Scale(2.0 / Width, 2.0 / Height, 1) - you are mapping [0, Width|Height] -> [-1, 1], hence the 2.0 factor).

This is a limitation of the underlying text drawing APIs.

segfaultvicta's picture

Thank you! We've got it working now; everything that's left is just a matter of correctly positioning the text underneath what we're drawing, which should be relatively straightforward. Thank you for all the help!