/*
         * Draw text: the text by default lies in the x,y plane and along the x axis in the positive direction.
         * It can be tilted about the x-axis using the SetTiltInRadians method.
         * Returns the string length in pixels.
         */
        public void DrawText(float x, float y, float z, string text)
        {
            // Make this texture active
            GL.Enable(EnableCap.Texture2D);
            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
            GL.BindTexture(TextureTarget.Texture2D, FontTextureID);

            GL.Begin(PrimitiveType.Quads);
            GL.Color3(Color.Transparent);
            float xScreen = x;
            float yScreen = y;

            foreach (var idx in text)
            {
                TextureSettings.GlyphInfo glyphoInfo = _textureSettings.GlyphInfoArray[idx];
                float xTexture      = (float)glyphoInfo.X / (float)TextureWidth;
                float yTexture      = (float)glyphoInfo.Y / (float)TextureHeight;
                float widthTexture  = (float)glyphoInfo.Width / (float)TextureWidth;
                float heightTexture = (float)glyphoInfo.Height / (float)TextureHeight;

                float dy = (float)(glyphoInfo.Height * _cosineTilt);
                float dz = -(float)(glyphoInfo.Height * _sineTilt);

                GL.TexCoord3(xTexture, yTexture, z);
                GL.Vertex3(xScreen, yScreen + dy, z + dz);

                GL.TexCoord3(xTexture + widthTexture, yTexture, z);
                GL.Vertex3(xScreen + glyphoInfo.Width, yScreen + dy, z + dz);

                GL.TexCoord3(xTexture + widthTexture, yTexture + heightTexture, z);
                GL.Vertex3(xScreen + glyphoInfo.Width, yScreen, z);

                GL.TexCoord3(xTexture, yTexture + heightTexture, z);
                GL.Vertex3(xScreen, yScreen, z);

                xScreen += glyphoInfo.Width;
            }

            GL.End();
            GL.Disable(EnableCap.Texture2D);
            GL.Disable(EnableCap.Blend);
        }
        /*
         * Purpose: Creates a bitmap image of the character set and saves it as a file => [APP_DATA]\local\Temp\font_1.png
         *
         * We do this so that the bitmap can be loaded
         */
        private void GenerateFontImage()
        {
            System.Drawing.Font font;
            if (!string.IsNullOrWhiteSpace(_textureSettings.FromFile))
            {
                var collection = new System.Drawing.Text.PrivateFontCollection();
                collection.AddFontFile(_textureSettings.FromFile);
                var fontFamily = new System.Drawing.FontFamily(System.IO.Path.GetFileNameWithoutExtension(_textureSettings.FromFile), collection);
                font = new System.Drawing.Font(fontFamily, _textureSettings.FontSize);
            }
            else
            {
                font = new System.Drawing.Font(new System.Drawing.FontFamily(_textureSettings.FontName), _textureSettings.FontSize, FontStyle.Bold);
            }

            // Measure the size of each character when written to a bitmap
            using (System.Drawing.Bitmap bitmap = new Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
            {
                using (var graphics = System.Drawing.Graphics.FromImage(bitmap))
                {
                    char  c          = (char)0;
                    float previousY  = 0;
                    float lineHeight = 0;
                    for (int p = 0; p < _textureSettings.GlyphLineCount; p++)
                    {
                        float previousX = 0;
                        for (int n = 0; n < _textureSettings.GlyphsPerLine; n++, ++c)
                        {
                            SizeF size = graphics.MeasureString(c.ToString(), font, 0);
                            // The next step is purely empirical => remove superfluous padding
                            size = new SizeF(size.Width - _textureSettings.FontSize / 6, size.Height - _textureSettings.FontSize / 6);

                            if ((p == 0) && (n == 0))
                            {
                                lineHeight = size.Height;
                            }

                            TextureSettings.GlyphInfo glyphoInfo = new TextureSettings.GlyphInfo();
                            _textureSettings.GlyphInfoArray[c] = glyphoInfo;
                            glyphoInfo.X      = previousX;
                            glyphoInfo.Y      = previousY;
                            glyphoInfo.Width  = size.Width;
                            glyphoInfo.Height = size.Height;
                            previousX        += size.Width;

                            TextureWidth = System.Math.Max(TextureWidth, (int)(previousX + 1));
                        }
                        previousY    += lineHeight;
                        TextureHeight = System.Math.Max(TextureHeight, (int)(previousY + 1));
                    }
                }
            }

            // Now create the character bitmap
            using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(TextureWidth, TextureHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
            {
                using (var graphics = System.Drawing.Graphics.FromImage(bitmap))
                {
                    graphics.Clear(_backgroundColour);

                    if (_textureSettings.BitmapFont)
                    {
                        graphics.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.None;
                        graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;
                    }
                    else
                    {
                        graphics.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                        graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                    }

                    char c = (char)0;
                    for (int i = 0; i < 256; ++i, ++c)
                    {
                        TextureSettings.GlyphInfo glyphoInfo = _textureSettings.GlyphInfoArray[i];
                        graphics.DrawString(c.ToString(), font, new SolidBrush(_textColour), glyphoInfo.X, glyphoInfo.Y);
                    }
                }
                bitmap.Save(_textureSettings.FontBitmapFilename);
            }
        }