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):
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.