1
\$\begingroup\$

Starting off the class in question is here:

using System;

public class FontService
{
    private int[] characterTextures;

    public void InitalizeTextures()
    {
        characterTextures = new int[94];
        var font = new FontFace(File.OpenRead(Path.Combine(Environment.GetFolderPath(
            Environment.SpecialFolder.ApplicationData), @"RyuFs\system\fonts\FontStandard.ttf")));

        for (int i = 33; i < 127; i++)
        {
            var surface = RenderSurface((char)i, font);

            characterTextures[i - 33] = LoadTexture(surface);
        }
    }

    public void DrawText(string text)
    {
        GL.Viewport(0, 0, 500, 500);
        GL.BindTexture(TextureTarget.Texture2D, characterTextures[text[0] - 33]);

        GL.Enable(EnableCap.Blend);
        GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
        GL.Enable(EnableCap.DepthTest);
        GL.DepthFunc(DepthFunction.Lequal);
        GL.Enable(EnableCap.Texture2D);

        GL.ClearDepth(1);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
        GL.ClearColor(Color.White);


        GL.Begin(PrimitiveType.Triangles);
        GL.Color4(Color.White);

        GL.TexCoord2(0, 0); GL.Vertex2(100, 100);
        GL.TexCoord2(0, 64); GL.Vertex2(100, 164);
        GL.TexCoord2(32, 64); GL.Vertex2(132, 164);

        GL.TexCoord2(32, 64); GL.Vertex2(132, 164);
        GL.TexCoord2(32, 0); GL.Vertex2(132, 100);
        GL.TexCoord2(0, 0); GL.Vertex2(100, 100);
        GL.End();

        GL.BindTexture(TextureTarget.Texture2D, 0);
        GL.Disable(EnableCap.Texture2D);
        GL.Disable(EnableCap.DepthTest);

    }

    public unsafe Surface RenderSurface(char c, FontFace font)
    {
        var glyph = font.GetGlyph(c, 32);
        var surface = new Surface
        {
            Bits = Marshal.AllocHGlobal(glyph.RenderWidth * glyph.RenderHeight),
            Width = glyph.RenderWidth,
            Height = glyph.RenderHeight,
            Pitch = glyph.RenderWidth
        };

        var stuff = (byte*)surface.Bits;
        for (int i = 0; i < surface.Width * surface.Height; i++)
            *stuff++ = 0;

        glyph.RenderTo(surface);

        return surface;
    }

    private unsafe int LoadTexture(Surface surface)
    {
        int width = 32; //surface.Width;
        int height = 64; //surface.Height;
        int len = width * height;
        byte[] data = new byte[len];
        //Marshal.Copy(surface.Bits, data, 0, len);
        int[] pixels = new int[len];

        int index = 0;
        for (int i = 0; i < len; i++)
        {
            int c = (byte)i; //data[i];
            pixels[i] = (byte.MaxValue << 24) | (c << 16) | (c << 8) | c;
        }

        GL.Enable(EnableCap.Texture2D);
        int textureID = GL.GenTexture();
        GL.BindTexture(TextureTarget.Texture2D, textureID);

        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);

        fixed (int* dataptr = pixels)
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)dataptr);
        GL.BindTexture(TextureTarget.Texture2D, 0);
        GL.Disable(EnableCap.Texture2D);

        Marshal.FreeHGlobal(surface.Bits); //Give the memory back!
        return textureID;
    }
}

Currently I get this output (It's an odd shaped window): https://puu.sh/CBMIm/a55ef28299.png

What I expect the code to do is generate rainbow textures with constant Alpha on line 96:

int index = 0;
for (int i = 0; i < len; i++)
{
    int c = (byte)i; //data[i];
    pixels[i] = (byte.MaxValue << 24) | (c << 16) | (c << 8) | c;
}

After that I expect it to convert the data into a texture on line 113:

fixed (int* dataptr = pixels)
    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)dataptr);

Finally DrawText should render just the first char of the string, 'H' in my example but as it's just got a dummy texture it should render a rainbow square.

I would also like to be able to blend it properly with respect to alpha so 0 alpha is totally transparent and 100% alpha is totally opaque.

Some extra info that may help you, help me:

  • Running under .Net Core 2.0
  • OpenTK window host
  • Using Open GL ES 2.0
  • InitalizeTextures is called on GL load
  • DrawText is called with help in gldraw. The only other gl calls are a clearcolor to white (prior) and a frame swap (post)
  • No shaders are loaded
  • Orthographic viewport where 1 pixel = 1 unit

So to sum it all up, what's wrong with my code causing these issues? I know it's messy, I will clean it up on commit :)

Thank you for reading this far and any help would be appreciated.

\$\endgroup\$
2
  • \$\begingroup\$ Please embed the relevant code and image example in your question itself, not as external links. This may involve whittling your problem down to a minimal complete verifiable example. \$\endgroup\$
    – DMGregory
    Commented Jan 24, 2019 at 22:11
  • \$\begingroup\$ Your texture creation code won't make a rainbow. It will either make a gray ramp or a ramp from transparent red to solid white, depending on whether it's ARGB or RGBA (or possible transparent blue to solid white if it's BGRA). \$\endgroup\$ Commented Jan 25, 2019 at 4:45

1 Answer 1

2
\$\begingroup\$

Turns out there are a couple issues with my code: the fact that it doesn't generate a rainbow box but a grey gradient as user1118321 said in a comment; the wrong pixel type, byte, not uint8888; and probably more.

But the real issue was the texture coordinates. I failed to realize they are always from (0,0) to (1,1) and not the size of the of the texture as I had been using them. Anyway with that done it's all fixed. I don't have the code as I ended up completely rewriting it for its actual use.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .