
QuickFont -- Problem with resizing the window
Posted Tuesday, 17 July, 2012 - 09:20 by rounder8 inHello everyone,
I'm new to OpenGL and OpenTK is my first dip into the world of 3D graphics. I want to thank this community for creating these wonderful tools!
Painting text to the screen seems to be quite a complicated task with OpenGL. Luckily I found this library called QuickFont that made my life easier. I've got a problem though. When I resize the window the QFont.Print command prints into wrong X-position. The code is as follows:
class TextPrinter : GameWindow { QFont BasicFont; public TextPrinter() : base() { Load += new EventHandler<EventArgs>(TextPrinter_Load); RenderFrame += new EventHandler<FrameEventArgs>(TextPrinter_RenderFrame); Resize += new EventHandler<EventArgs>(TextPrinter_Resize); UpdateFrame += new EventHandler<FrameEventArgs>(TextPrinter_UpdateFrame); Mouse.WheelChanged += new EventHandler<MouseWheelEventArgs>(Mouse_WheelChanged); Keyboard.KeyDown += new EventHandler<KeyboardKeyEventArgs>(Keyboard_KeyDown); } private void SetupViewport() { GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.Ortho(0, Width, 0, Height, -1, 1); GL.Viewport(0, 0, Width, Height); GL.Disable(EnableCap.DepthTest); } private void TextPrinter_Load(object sender, EventArgs e) { // Setup the QFont var builderconf = new QFontBuilderConfiguration(); builderconf.TextGenerationRenderHint = TextGenerationRenderHint.ClearTypeGridFit; BasicFont = new QFont(new Font("Calibri", 20f, FontStyle.Bold), builderconf); BasicFont.Options.Colour = new Color4(0f, 0f, 0f, 1f); SetupViewport(); } private void TextPrinter_Resize(object sender, EventArgs e) { SetupViewport(); } private void TextPrinter_UpdateFrame(object sender, EventArgs e) { //var mouse = } // For adjusting the window width on the fly private void Mouse_WheelChanged(object sender, MouseWheelEventArgs e) { this.Width += e.Delta; } // For adjusting the window width on the fly private void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e) { if (e.Key == Key.Left) { this.Width -= 1; } else if (e.Key == Key.Right) { this.Width += 1; } } private void TextPrinter_RenderFrame(object sender, EventArgs e) { GL.ClearColor(Color.LightGray); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.Color3(Color.Black); GL.Begin(BeginMode.Lines); GL.Vertex2(Width / 2.0, 0); GL.Vertex2(Width / 2.0, Height); GL.End(); GL.Begin(BeginMode.Lines); GL.Vertex2(Width / 3.0, 0); GL.Vertex2(Width / 3.0, Height); GL.End(); GL.Begin(BeginMode.Lines); GL.Vertex2(2f * (Width / 3.0), 0); GL.Vertex2(2f * (Width / 3.0), Height); GL.End(); QFont.Begin(); BasicFont.Print("O", QFontAlignment.Centre, new Vector2(Width / 2f, Height / 2f)); QFont.End(); GL.Disable(EnableCap.Texture2D); QFont.Begin(); BasicFont.Print("O", QFontAlignment.Centre, new Vector2(Width / 3f, Height / 2f)); QFont.End(); GL.Disable(EnableCap.Texture2D); QFont.Begin(); BasicFont.Print("O", QFontAlignment.Centre, new Vector2(2f * (Width / 3f), Height / 2f)); QFont.End(); GL.Disable(EnableCap.Texture2D); SwapBuffers(); } static void Main(string[] args) { using (TextPrinter win = new TextPrinter()) { win.Run(100.0); } } }
This is a demostration of the misbehavior of the program. The printed "O" should be aligned with the lines but they are not after window gets resized.
I checked what GL-commands were executed in QFont.Begin, QFont.Print and QFont.End methods and I came up with this list that you might find helpful:
QFont.Begin:
GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix(); //push projection matrix
GL.LoadIdentity();
GL.Ortho(currentVp.X, currentVp.Width, currentVp.Height, currentVp.Y, -1.0, 1.0);
GL.MatrixMode(MatrixMode.Modelview);
GL.PushMatrix(); //push modelview matrix
GL.LoadIdentity();
Print:
GL.PushMatrix();
GL.Translate(position.X, position.Y, 0f);
GL.Color4(1.0f, 1.0f, 1.0f, 1.0f);
GL.Enable(EnableCap.Texture2D);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.BindTexture(TextureTarget.Texture2D, sheet.GLTexID);
GL.Begin(BeginMode.Quads);
GL.TexCoord2(tx1, ty1); GL.Vertex2(x, y + glyph.yOffset);
GL.TexCoord2(tx1, ty2); GL.Vertex2(x, y + glyph.yOffset + glyph.rect.Height);
GL.TexCoord2(tx2, ty2); GL.Vertex2(x + glyph.rect.Width, y + glyph.yOffset + glyph.rect.Height);
GL.TexCoord2(tx2, ty1); GL.Vertex2(x + glyph.rect.Width, y + glyph.yOffset);
GL.End();
GL.PopMatrix();
QFont.End:
GL.MatrixMode(MatrixMode.Modelview);
GL.PopMatrix(); //pop modelview
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix(); //pop projection
GL.MatrixMode(MatrixMode.Modelview);


Comments
Re: QuickFont -- Problem with resizing the window
Hello,
Apologies for my recent inactivity, I've been rather busy at work.
I added a change to deal with this a few months ago, but haven't gotten round to releasing it.
I'll be releasing a new version this evening with this change along with numerous other bug fixes.
Regards,
James L.
Re: QuickFont -- Problem with resizing the window
The latest release is available here:
http://www.opentk.com/node/3120
When you change the viewport, you have three options to make QFont aware of it:
Call :
QFont.PopSoftwareViewport()
...followed by:
QFont.PushSoftwareViewport(Viewport viewport)
Where Viewport is what you have just defined the new viewport to be at the application level.
The third option is the most efficient, because it skips an unnecessary call to GL.GetInteger. However, in practise (given that you are probably only doing this on resize events) either of the other two will do fine.