OpenTK使用Power of Two位图纹理将文本写入屏幕

时间:2011-11-30 19:28:19

标签: c# .net multithreading opentk

我遇到了一个问题,我是一个需要两个力量(POT)纹理并且似乎无法使用NPOT的幸运者之一。

通常情况下,这并不会让我太烦恼,因为我只需要确保我需要使用的任何纹理都是POT。但是,我在尝试将光标X和Y位置渲染到屏幕时遇到了问题。

        public int LoadHudTextures(int xPos, int yPos, Color color, GLControl context)
    {
        context.MakeCurrent();

        int Text_Texture;
        text_bmp1 = new Bitmap(50, 24);

        Text_Texture = GL.GenTexture();
        GL.BindTexture(TextureTarget.Texture2D, Text_Texture);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
        //GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, text_bmp1.Width, text_bmp1.Height, 0,
            //OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 1024, 1024, 0, 
            OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);

        Graphics gfx = Graphics.FromImage(text_bmp1);
        gfx.Clear(Color.Transparent);
        FontFamily fontfamily = new FontFamily("Arial");
        Font font = new Font(fontfamily, 16, FontStyle.Regular,GraphicsUnit.Pixel);
        gfx.DrawString("X:" + xPos.ToString() + "\n"
            + "Y:" + yPos.ToString(), font, new SolidBrush(color), new PointF(1.5f, 1.5f));

        // Upload the Bitmap to OpenGL.
        // Do this only when text changes.
        System.Drawing.Imaging.BitmapData data = text_bmp1.LockBits(new Rectangle(0, 0, text_bmp1.Width, text_bmp1.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 50, 24, 0,
            OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
        text_bmp1.UnlockBits(data);
        return Text_Texture;

    }

这是问题所在。如果我使用“text_bmp1.Width”和“text_bmp1.Height”,我得到的只是一个白色的盒子。 (要纹理化的对象)。我认为这是因为我的POT问题。如果我使用POT(512,1024等)的宽度和高度,纹理渲染,但A)它不是我想要显示的字符串,B)它在几次渲染后被破坏,然后最终消隐, C)渲染的纹理没有被裁剪并且被非常奇怪地拉伸。

如果我只更改TexCoord2(,)X和Y值,则可以修复

C)。 我想知道是否有办法将文本图像动态填充到下一个POT并裁掉多余的东西?

为了清楚起见,我正在编写一个环境,将HP / GL2 PCL源代码文件中的项目显示到屏幕上,然后再将其发送到打印机以获取动态药房标签。

如果有人需要更多说明,请告诉我。谢谢你

1 个答案:

答案 0 :(得分:3)

GL.TexImage2D会破坏当前绑定的纹理,并使用您指定的大小重新创建它。你想要做的是在创建POT纹理时使用GL.TexImage2D一次,并使用GL.TexSubImage2D更新它的特定部分。

在屏幕上渲染此纹理时,请指定与您更新的特定部分对应的texcoords,即不从(0,0)渲染到(1,1),而是从(0,0)渲染到(text_width / pot_width) ,text_height / pot_height)。这样,您可以忽略填充并避免拉伸纹理。

在任何情况下,请查看QuickFont(http://www.opentk.com/project/QuickFont),它允许您直接呈现文本而无需进入脏信息。