Martin's picture

Problem with printing text

I am trying to print text and have adapted the following example here :http://www.opentk.com/doc/graphics/how-to-render-text-using-opengl#comment-form into a Text class:

public class Text
    {
        Font TextFont = new Font(FontFamily.GenericSansSerif, 14);
        Bitmap TextBitmap;
        PointF position;
        string text;
        Brush color;
        int texture;
 
        public Text(Rectangle ClientSize)
        {           
            TextBitmap = new Bitmap(ClientSize.Width, ClientSize.Height);
            texture = GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, texture);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, TextBitmap.Width, TextBitmap.Height, 0,
                PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
        }
 
        public void Resize(int newWidth, int newHeight)
        {
            // Ensure Bitmap and texture match window size
            TextBitmap.Dispose();
            TextBitmap = new Bitmap(newWidth, newHeight);
 
            GL.BindTexture(TextureTarget.Texture2D, texture);
            GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, TextBitmap.Width, TextBitmap.Height,
                PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
        }
 
        public void PrintText(string s, PointF pos, Brush col)
        {
            text = s;
            position = pos;
            color = col;            
            UpdateText();
        }
 
        public void UpdateText()
        {
            using (Graphics gfx = Graphics.FromImage(TextBitmap))
            {
                gfx.Clear(Color.Transparent);
                gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                gfx.DrawString(text, TextFont, color, position);
            }
 
            System.Drawing.Imaging.BitmapData data = TextBitmap.LockBits(new Rectangle(0, 0, TextBitmap.Width, TextBitmap.Height),
                System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, TextBitmap.Width, TextBitmap.Height, PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
            TextBitmap.UnlockBits(data);           
        }
 
        public void Draw()
        {
 
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(0, TextBitmap.Width, TextBitmap.Height, 0, -1, 1);
 
            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
 
            GL.Begin(BeginMode.Quads);
            GL.TexCoord2(0f, 1f); GL.Vertex2(0f, 0f);
            GL.TexCoord2(1f, 1f); GL.Vertex2(1f, 0f);
            GL.TexCoord2(1f, 0f); GL.Vertex2(1f, 1f);
            GL.TexCoord2(0f, 0f); GL.Vertex2(0f, 1f);
            GL.End();
        }
    }

I instantiate the Text class from a GameWindow instance in its OnLoad method:

protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            GL.ClearColor(0.1f, 0.2f, 0.5f, 0.0f);
            GL.Enable(EnableCap.DepthTest);
            t = new Text(new Rectangle(0, 0, this.ClientSize.Width, this.ClientSize.Height));
        }

In OnRenderFrame I call PrintText and Draw on Text (there is also some remnants of some code making a triangle move to the left):

protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
 
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref modelview);
 
            GL.Begin(BeginMode.Triangles);
 
            GL.Color3(1.0f, 1.0f, 0.0f); GL.Vertex3(a, -1.0f, 4.0f);
            GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex3(b, -1.0f, 4.0f);
            GL.Color3(0.2f, 0.9f, 1.0f); GL.Vertex3(c, 1.0f, 4.0f);
 
            a += inc;
            b += inc;
            c += inc;
 
            GL.End();
 
            t.PrintText("Hello...", new PointF(-5f, -5f), Brushes.Green);
            t.Draw();
            SwapBuffers();
            System.Threading.Thread.Sleep(1); //Must be here. See http://www.opentk.com/node/1045
        }

In my OnResize, I call the Resize method on the Text instance:

protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
 
            GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
 
            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f);
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref projection);
            t.Resize(this.ClientSize.Width, this.ClientSize.Height);
        }

My problem is, that on startup, the program crashes on the second to last line in the resize code in the Text class. When I try to debug, I get a message saying, that a debugger is already attached. I am using VS2010. Any ideas on how to solve this or get some debug output at least? Are some of my GL statements out of order? Any help is greatly appreciated. I am new to OpenTK.


Comments

Comment viewing options

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

Problem solved. For anyone else with text printing problems who happen to be reading this post, take a look at the "GameWindow states" sample included in the OpenTK release.