diff --git a/Source/Examples/Tutorial/Fonts.cs b/Source/Examples/Tutorial/Fonts.cs
index 10964284..62f602c7 100644
--- a/Source/Examples/Tutorial/Fonts.cs
+++ b/Source/Examples/Tutorial/Fonts.cs
@@ -165,12 +165,7 @@ namespace Examples.Tutorial
{
GL.Clear(ClearBufferMask.ColorBufferBit);
- GL.MatrixMode(MatrixMode.Projection);
- GL.LoadIdentity();
- GL.Ortho(0.0, Width, Height, 0.0, 0.0, 1.0);
-
- GL.MatrixMode(MatrixMode.Modelview);
- GL.LoadIdentity();
+ printer.Begin();
// Print using the first font.
for (int i = 0; i < handles.Length / 2; i++)
@@ -190,6 +185,8 @@ namespace Examples.Tutorial
GL.Translate(0, fonts[i].Height, 0);
}
+ printer.End();
+
SwapBuffers();
}
diff --git a/Source/Examples/Tutorial/Text.cs b/Source/Examples/Tutorial/Text.cs
index 4357559b..a78063c3 100644
--- a/Source/Examples/Tutorial/Text.cs
+++ b/Source/Examples/Tutorial/Text.cs
@@ -120,20 +120,18 @@ namespace Examples.Tutorial
else if (scroll_speed < 0.0f && current_position < warparound_position)
current_position = initial_position;
- // Prepare to draw text. We want pixel perfect precision, so we setup a 2D mode,
- // with size equal to the window (in pixels).
- // While we could also render text in 3D mode, it would be very hard to get
- // pixel-perfect precision.
- GL.MatrixMode(MatrixMode.Projection);
- GL.LoadIdentity();
- GL.Ortho(0.0, Width, Height, 0.0, 0.0, 1.0);
-
- GL.MatrixMode(MatrixMode.Modelview);
- GL.LoadIdentity();
+ // TextPrinter.Begin() sets up a 2d orthographic projection, with the x axis
+ // moving from 0 to viewport.Width (left to right) and the y axis from
+ // 0 to viewport.Height (top to bottom). This is the typical coordinate system
+ // used in 2d graphics, and is necessary for achieving pixel-perfect glyph rendering.
+ // TextPrinter.End() restores your previous projection/modelview matrices.
+ text.Begin();
GL.Translate(0.0f, current_position, 0.0f);
text.Draw(poem_handle);
+ text.End();
+
SwapBuffers();
}
diff --git a/Source/OpenTK/Fonts/ITextPrinter.cs b/Source/OpenTK/Fonts/ITextPrinter.cs
index 3ee3b290..aaf74e62 100644
--- a/Source/OpenTK/Fonts/ITextPrinter.cs
+++ b/Source/OpenTK/Fonts/ITextPrinter.cs
@@ -21,5 +21,7 @@ namespace OpenTK.Fonts
void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp, StringAlignment alignment);
void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp, StringAlignment alignment, bool rightToLeft);
void Draw(TextHandle handle);
+ void Begin();
+ void End();
}
}
diff --git a/Source/OpenTK/Fonts/TextPrinter.cs b/Source/OpenTK/Fonts/TextPrinter.cs
index a8a9b6ca..238892ca 100644
--- a/Source/OpenTK/Fonts/TextPrinter.cs
+++ b/Source/OpenTK/Fonts/TextPrinter.cs
@@ -27,6 +27,7 @@ namespace OpenTK.Fonts
//static char[] split_chars = new char[] { ' ', '\n', '\t', ',', '.', '/', '?', '!', ';', '\\', '-', '+', '*', '=' };
static bool functionality_checked = false;
static ITextPrinterImplementation printer;
+ float[] viewport = new float[6];
#region --- Constructor ---
@@ -62,21 +63,72 @@ namespace OpenTK.Fonts
#region --- ITextPrinter Members ---
+ #region public void Prepare(string text, TextureFont font, out TextHandle handle)
+
+ ///
+ /// Prepares text for drawing.
+ ///
+ /// The string to draw.
+ /// The font to use for drawing.
+ /// The handle to the cached text. Use this to draw the text with the Draw() function.
+ ///
public void Prepare(string text, TextureFont font, out TextHandle handle)
{
this.Prepare(text, font, out handle, 0, false, StringAlignment.Near, false);
}
+ #endregion
+
+ #region public void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp)
+
+ ///
+ /// Prepares text for drawing.
+ ///
+ /// The string to draw.
+ /// The font to use for drawing.
+ /// The handle to the cached text. Use this to draw the text with the Draw() function.
+ /// Not implemented.
+ /// Not implemented.
+ ///
public void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp)
{
this.Prepare(text, font, out handle, width, wordWarp, StringAlignment.Near, false);
}
+ #endregion
+
+ #region public void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp, StringAlignment alignment)
+
+ ///
+ /// Prepares text for drawing.
+ ///
+ /// The string to draw.
+ /// The font to use for drawing.
+ /// The handle to the cached text. Use this to draw the text with the Draw() function.
+ /// Not implemented.
+ /// Not implemented.
+ /// Not implemented.
+ ///
public void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp, StringAlignment alignment)
{
this.Prepare(text, font, out handle, width, wordWarp, alignment, false);
}
+ #endregion
+
+ #region public void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp, StringAlignment alignment, bool rightToLeft)
+
+ ///
+ /// Prepares text for drawing.
+ ///
+ /// The string to draw.
+ /// The font to use for drawing.
+ /// The handle to the cached text. Use this to draw the text with the Draw() function.
+ /// Not implemented.
+ /// Not implemented.
+ /// Not implemented.
+ /// Not implemented.
+ ///
public void Prepare(string text, TextureFont font, out TextHandle handle, float width, bool wordWarp, StringAlignment alignment, bool rightToLeft)
{
if (!functionality_checked)
@@ -88,6 +140,9 @@ namespace OpenTK.Fonts
if (text.Length > 8192)
throw new ArgumentOutOfRangeException("text", text.Length, "Text length must be between 1 and 8192 characters");
+ if (wordWarp || rightToLeft || alignment != StringAlignment.Near)
+ throw new NotImplementedException();
+
Vector2[] vertices = new Vector2[8 * text.Length]; // Interleaved, vertex, texcoord, vertex, etc...
ushort[] indices = new ushort[6 * text.Length];
float x_pos = 0, y_pos = 0;
@@ -167,8 +222,49 @@ namespace OpenTK.Fonts
handle.font = font;
}
+ #endregion
+
+ #region public void Draw(TextHandle handle)
+
+ ///
+ /// Draws the cached text referred to by the TextHandle.
+ ///
+ /// The TextHandle to the cached text.
public void Draw(TextHandle handle)
{
+ GL.BindTexture(TextureTarget.Texture2d, handle.font.Texture);
+
+ printer.Draw(handle);
+ }
+
+ #endregion
+
+ #region public void Draw(string text)
+
+ #endregion
+
+ #region public void Begin()
+
+ ///
+ /// Sets up OpenGL state for drawing text.
+ ///
+ public void Begin()
+ {
+ GL.PushMatrix();
+
+ GL.GetFloat(GetPName.Viewport, viewport);
+
+ // Prepare to draw text. We want pixel perfect precision, so we setup a 2D mode,
+ // with size equal to the window (in pixels).
+ // While we could also render text in 3D mode, it would be very hard to get
+ // pixel-perfect precision.
+ GL.MatrixMode(MatrixMode.Projection);
+ GL.LoadIdentity();
+ GL.Ortho(viewport[0], viewport[2], viewport[3], viewport[1], 0.0, 1.0);
+
+ GL.MatrixMode(MatrixMode.Modelview);
+ GL.LoadIdentity();
+
GL.PushAttrib(AttribMask.TextureBit);
GL.PushAttrib(AttribMask.EnableBit);
@@ -177,15 +273,24 @@ namespace OpenTK.Fonts
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.Disable(EnableCap.DepthTest);
-
- GL.BindTexture(TextureTarget.Texture2d, handle.font.Texture);
-
- printer.Draw(handle);
-
- GL.PopAttrib();
- GL.PopAttrib();
}
#endregion
+
+ #region public void End()
+
+ ///
+ /// Restores OpenGL state.
+ ///
+ public void End()
+ {
+ GL.PopAttrib();
+ GL.PopAttrib();
+ GL.PopMatrix();
+ }
+
+ #endregion
+
+ #endregion
}
}