首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用OpenTK绘制文本

使用OpenTK绘制文本
EN

Stack Overflow用户
提问于 2014-11-18 18:47:26
回答 1查看 9K关注 0票数 3

我要疯狂地尝试使用OpenGL窗口画一些文本,使用OpenTK!我遵循了一些教程,但我无法使它工作,当我启用纹理的文本绘制,然后我只有一个白色的窗口,我画的测试四边形就消失了。如果有人有时间检查代码,它如下所示。我也可以发送我的测试程序,以检查它更快。谢谢您在这方面的任何帮助。

代码语言:javascript
复制
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

using OpenTK.Graphics.OpenGL;

using System.Diagnostics;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Bitmap textBmp;
        int textTexture = -1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!glControl1.Context.IsCurrent)
            {
                glControl1.MakeCurrent();
            }

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();

            GL.Ortho(0, glControl1.Width, 0, glControl1.Height, -1000, 1000);

            GL.Scale(1, 1, 1);

            GL.Viewport(0, 0, glControl1.Width, glControl1.Height);

            GL.ClearColor(Color.White);

            // Better point and line drawing
            GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
            GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);

            GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);

            GL.Enable(EnableCap.PointSmooth);
            GL.Enable(EnableCap.LineSmooth);

            GL.Enable(EnableCap.Blend);

            // Hide stuff behind in 3D
            GL.Enable(EnableCap.DepthTest);

            // Enable the texture
            GL.Enable(EnableCap.Texture2D);

            // Create Bitmap and OpenGL texture
            textBmp = new Bitmap((int)glControl1.Width, (int)glControl1.Height);

            textTexture = GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, textTexture);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, textBmp.Width, textBmp.Height, 0,
                            OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);

            ErrorCode errorCode = GL.GetError();
            Debug.Assert(errorCode == ErrorCode.NoError, "OpenTK error!");
        }

        private void glControl1_Paint(object sender, PaintEventArgs e)
        {
            ErrorCode errorCode;

            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);

            GL.PushMatrix();

            GL.Color3(Color.Black);

            GL.Begin(PrimitiveType.Quads);

            GL.Vertex3(10, 10, 10);
            GL.Vertex3(40, 10, 10);
            GL.Vertex3(40, 50, 10);
            GL.Vertex3(10, 50, 10);

            GL.End();

            if (textBmp != null)
            {
                using (Graphics gfx = Graphics.FromImage(textBmp))
                {
                    gfx.Clear(Color.Transparent);
                    gfx.DrawString("text", new Font("Arial", 10), Brushes.Black, new PointF(textBmp.Width / 2, textBmp.Height));
                }

                BitmapData data = textBmp.LockBits(new Rectangle(0, 0, textBmp.Width, textBmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, (int)glControl1.Width, (int)glControl1.Height, 0,
                    OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);

                textBmp.UnlockBits(data);

                errorCode = GL.GetError();
                Debug.Assert(errorCode == ErrorCode.NoError, "OpenTK error!");

                GL.Begin(PrimitiveType.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();
            }

            errorCode = GL.GetError();
            Debug.Assert(errorCode == ErrorCode.NoError, "OpenTK error!");

            glControl1.SwapBuffers();
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-21 15:20:08

好吧,我终于成功了。

在初始化时,我刚刚做了:

代码语言:javascript
复制
if (!control.Context.IsCurrent)
{
    control.MakeCurrent();
}

GL.Ortho(0, controlWidth, 0, controlHeight, -1000, 1000);
GL.Scale(1, -1, 1); // I work with a top/left image and openGL is bottom/left
GL.Viewport(0, 0, controlWidth, controlHeight);
GL.ClearColor(Color.White);
GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);
GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.OneMinusSrcAlpha);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
GL.Enable(EnableCap.PointSmooth);
GL.Enable(EnableCap.LineSmooth);
GL.Enable(EnableCap.Blend);
GL.Enable(EnableCap.DepthTest);
GL.ShadeModel(ShadingModel.Smooth);
GL.Enable(EnableCap.AutoNormal);

bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
gfx = Graphics.FromImage(bmp);
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

texture = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texture);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp.Width, bmp.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);

然后在位图中写入文本:

代码语言:javascript
复制
gfx.DrawString(text, font, brush, new PointF(x, y));

并提出:

代码语言:javascript
复制
if (!control.Context.IsCurrent)
{
    control.MakeCurrent();
}

GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

GL.MatrixMode(MatrixMode.Modelview);

GL.Enable(EnableCap.Texture2D);
GL.BindTexture(TextureTarget.Texture2D, Texture);

GL.Begin(PrimitiveType.Quads);

GL.TexCoord3(0.0f, 0.0f, 0f); GL.Vertex3(0f, 0f, 0f);
GL.TexCoord3(1.0f, 0.0f, 0f); GL.Vertex3(realWidth, 0f, 0f);
GL.TexCoord3(1.0f, 1.0f, 0f); GL.Vertex3(realWidth, realHeight, 0f);
GL.TexCoord3(0.0f, 1.0f, 0f); GL.Vertex3(0f, realHeight, 0f);

GL.End();

GL.Disable(EnableCap.Texture2D);

control.SwapBuffers();

这招成功了。

非常重要(至少我认为是这样):

  • GL.Enable(EnableCap.Texture2D)在呈现带有纹理和GL.Disable(EnableCap.Texture2D)后缀的四角体之前。
  • 启用GL.BindTexture(TextureTarget.Texture2D,纹理)之后的GL.Enable(EnableCap.Texture2D)。

希望这能帮上忙。如果我有时间的话,我会用它创建一个C#类,并在这里发布。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27001700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档