private void RenderAsTexture(FT_GlyphSlotRec glyphrec, int c) { int ret = FT.FT_Render_Glyph(ref glyphrec, FT_Render_Mode.FT_RENDER_MODE_NORMAL); FTGlyphOffset offset = new FTGlyphOffset(); if (ret != 0) { Report("Render failed for character " + c.ToString()); } string sError = ""; int size = (glyphrec.bitmap.width * glyphrec.bitmap.rows); if (size <= 0) { //Console.Write("Blank Character: " + c.ToString()); //space is a special `blank` character extent_x[c] = 0; if (c == 32) { Gl.glNewList((list_base + c), Gl.GL_COMPILE); Gl.glTranslatef(font_size >> 1, 0, 0); extent_x[c] = font_size >> 1; Gl.glEndList(); offset.left = 0; offset.top = 0; offset.height = 0; offset.width = extent_x[c]; offsets[c] = offset; } return; } byte[] bmp = new byte[size]; Marshal.Copy(glyphrec.bitmap.buffer, bmp, 0, bmp.Length); //Next we expand the bitmap into an opengl texture int width = next_po2(glyphrec.bitmap.width); int height = next_po2(glyphrec.bitmap.rows); byte[, ,] expanded = new byte[height + 2, width + 2, 2]; for (int j = 0; j < height + 2; j++) { for (int i = 0; i < width + 2; i++) { //Luminance expanded[j, i, 0] = (byte)255; expanded[j, i, 1] = 0; } } for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { //expanded[4 * (i + j * width) + 1] = (byte)255; //expanded[4 * (i + j * width) + 2] = (byte)255; // Alpha expanded[j + 1, i + 1,1] = (i >= glyphrec.bitmap.width || j >= glyphrec.bitmap.rows) ? (byte)0 : (byte)(bmp[i + glyphrec.bitmap.width * j]); } } //Set up some texture parameters for opengl Gl.glBindTexture(Engine.Renderer.GlTextureMode, textures[c]); Gl.glTexParameteri(Engine.Renderer.GlTextureMode, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE); Gl.glTexParameteri(Engine.Renderer.GlTextureMode, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE); Gl.glTexParameteri(Engine.Renderer.GlTextureMode, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Engine.Renderer.GlTextureMode, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR); //Create the texture Gl.glTexImage2D(Engine.Renderer.GlTextureMode, 0, Gl.GL_RGBA, width +2, height+2, 0, Gl.GL_LUMINANCE_ALPHA, Gl.GL_UNSIGNED_BYTE, expanded); expanded = null; bmp = null; //Create a display list and bind a texture to it Gl.glNewList((list_base + c), Gl.GL_COMPILE); Gl.glBindTexture(Engine.Renderer.GlTextureMode, textures[c]); //Account for freetype spacing rules Gl.glTranslatef(glyphrec.bitmap_left, 0, 0); Gl.glPushMatrix(); Gl.glTranslatef(0, glyphrec.bitmap_top - glyphrec.bitmap.rows, 0); double x = Engine.Renderer.TextureCoordinate(glyphrec.bitmap.width, width); double y = Engine.Renderer.TextureCoordinate(glyphrec.bitmap.rows, height); offset.left = glyphrec.bitmap_left; offset.top = glyphrec.bitmap_top; offset.height = glyphrec.bitmap.rows; offset.width = glyphrec.bitmap.width; offset.advance = glyphrec.advance; offset.lsb_delta = glyphrec.lsb_delta; offset.rsb_delta = glyphrec.rsb_delta; offset.linearHoriAdvance = glyphrec.linearHoriAdvance; offset.linearVertAdvance = glyphrec.linearVertAdvance; offsets[c] = offset; //Draw the quad Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2d(0, 0); Gl.glVertex2f(-1, glyphrec.bitmap.rows+1); Gl.glTexCoord2d(0, y); Gl.glVertex2f(-1, -1); Gl.glTexCoord2d(x, y); Gl.glVertex2f(glyphrec.bitmap.width+1, -1); Gl.glTexCoord2d(x, 0); Gl.glVertex2f(glyphrec.bitmap.width+1, glyphrec.bitmap.rows+1); Gl.glEnd(); Gl.glPopMatrix(); //Advance for the next character Gl.glTranslatef(glyphrec.advance.x >> 6, 0, 0); extent_x[c] = glyphrec.bitmap_left + (glyphrec.advance.x >> 6); Gl.glEndList(); sChars += "f:" + c.ToString() + "[w:" + glyphrec.bitmap.width.ToString() + "][h:" + glyphrec.bitmap.rows.ToString() + "]" + sError; }
private void CompileCharacterToTexture(FT_FaceRec face, int c) { FTGlyphOffset offset = new FTGlyphOffset(); //We first convert the number index to a character index uint index = FT.FT_Get_Char_Index(faceptr, (uint)c); string sError = ""; if (index == 0) { sError = "No Glyph"; } //Here we load the actual glyph for the character int ret = FT.FT_Load_Glyph(faceptr, index, FT.FT_LOAD_DEFAULT); if (ret != 0) { Console.Write("Load_Glyph failed for character " + c.ToString()); } FT_GlyphSlotRec glyphrec = (FT_GlyphSlotRec)Marshal.PtrToStructure(face.glyph, typeof(FT_GlyphSlotRec)); ret = FT.FT_Render_Glyph(ref glyphrec, FT_Render_Mode.FT_RENDER_MODE_NORMAL); if (ret != 0) { Console.Write("Render failed for character " + c.ToString()); } int size = (glyphrec.bitmap.width * glyphrec.bitmap.rows); if (size <= 0) { //Console.Write("Blank Character: " + c.ToString()); //space is a special `blank` character extent_x[c] = 0; if (c == 32) { Gl.glNewList((list_base + c), Gl.GL_COMPILE); Gl.glTranslatef(font_size >> 1, 0, 0); extent_x[c] = font_size >> 1; Gl.glEndList(); offset.left = 0; offset.top = 0; offset.height = 0; offset.width = extent_x[c]; offsets[c] = offset; } return; } byte[] bmp = new byte[size]; Marshal.Copy(glyphrec.bitmap.buffer, bmp, 0, bmp.Length); //Next we expand the bitmap into an opengl texture int width = next_po2(glyphrec.bitmap.width); int height = next_po2(glyphrec.bitmap.rows); byte[] expanded = new byte[2 * width * height]; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { //Luminance expanded[2 * (i + j * width)] = (byte)255; //expanded[4 * (i + j * width) + 1] = (byte)255; //expanded[4 * (i + j * width) + 2] = (byte)255; // Alpha expanded[2 * (i + j * width) + 1] = (i >= glyphrec.bitmap.width || j >= glyphrec.bitmap.rows) ? (byte)0 : (byte)(bmp[i + glyphrec.bitmap.width * j]); } } //Set up some texture parameters for opengl Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[c]); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR); //Create the texture Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, width, height, 0, Gl.GL_LUMINANCE_ALPHA, Gl.GL_UNSIGNED_BYTE, expanded); expanded = null; bmp = null; //Create a display list and bind a texture to it Gl.glNewList((list_base + c), Gl.GL_COMPILE); Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[c]); //Account for freetype spacing rules Gl.glTranslatef(glyphrec.bitmap_left, 0, 0); Gl.glPushMatrix(); Gl.glTranslatef(0, glyphrec.bitmap_top - glyphrec.bitmap.rows, 0); float x = (float)glyphrec.bitmap.width / (float)width; float y = (float)glyphrec.bitmap.rows / (float)height; offset.left = glyphrec.bitmap_left; offset.top = glyphrec.bitmap_top; offset.height = glyphrec.bitmap.rows; offset.width = glyphrec.bitmap.width; offset.advance = glyphrec.advance; offset.lsb_delta = glyphrec.lsb_delta; offset.rsb_delta = glyphrec.rsb_delta; offset.linearHoriAdvance = glyphrec.linearHoriAdvance; offset.linearVertAdvance = glyphrec.linearVertAdvance; offsets[c] = offset; //Draw the quad Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2d(0, 0); Gl.glVertex2f(0, glyphrec.bitmap.rows); Gl.glTexCoord2d(0, y); Gl.glVertex2f(0, 0); Gl.glTexCoord2d(x, y); Gl.glVertex2f(glyphrec.bitmap.width, 0); Gl.glTexCoord2d(x, 0); Gl.glVertex2f(glyphrec.bitmap.width, glyphrec.bitmap.rows); Gl.glEnd(); Gl.glPopMatrix(); //Advance for the next character Gl.glTranslatef(glyphrec.bitmap.width, 0, 0); extent_x[c] = glyphrec.bitmap_left + glyphrec.bitmap.width; Gl.glEndList(); sChars += "f:" + c.ToString() + "[w:" + glyphrec.bitmap.width.ToString() + "][h:" + glyphrec.bitmap.rows.ToString() + "]" + sError; }
private void CompileCharacterToTexture(FT_FaceRec face, int c) { FTGlyphOffset offset = new FTGlyphOffset(); //We first convert the number index to a character index uint index = FT.FT_Get_Char_Index(faceptr, (uint)c); string sError = ""; if (index == 0) sError = "No Glyph"; //Here we load the actual glyph for the character int ret = FT.FT_Load_Glyph(faceptr, index, FT.FT_LOAD_DEFAULT); if (ret != 0) { Console.Write("Load_Glyph failed for character " + c.ToString()); } FT_GlyphSlotRec glyphrec = (FT_GlyphSlotRec)Marshal.PtrToStructure(face.glyph, typeof(FT_GlyphSlotRec)); ret = FT.FT_Render_Glyph(ref glyphrec, FT_Render_Mode.FT_RENDER_MODE_NORMAL); if (ret != 0) { Console.Write("Render failed for character " + c.ToString()); } int size = (glyphrec.bitmap.width * glyphrec.bitmap.rows); if (size <= 0) { //Console.Write("Blank Character: " + c.ToString()); //space is a special `blank` character extent_x[c] = 0; if (c == 32) { Gl.glNewList((list_base + c), Gl.GL_COMPILE); Gl.glTranslatef(font_size >> 1, 0, 0); extent_x[c] = font_size >> 1; Gl.glEndList(); offset.left = 0; offset.top = 0; offset.height = 0; offset.width = extent_x[c]; offsets[c] = offset; } return; } byte[] bmp = new byte[size]; Marshal.Copy(glyphrec.bitmap.buffer, bmp, 0, bmp.Length); //Next we expand the bitmap into an opengl texture int width = next_po2(glyphrec.bitmap.width); int height = next_po2(glyphrec.bitmap.rows); byte[] expanded = new byte[2 * width * height]; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { //Luminance expanded[2 * (i + j * width)] = (byte)255; //expanded[4 * (i + j * width) + 1] = (byte)255; //expanded[4 * (i + j * width) + 2] = (byte)255; // Alpha expanded[2 * (i + j * width) + 1] = (i >= glyphrec.bitmap.width || j >= glyphrec.bitmap.rows) ? (byte)0 : (byte)(bmp[i + glyphrec.bitmap.width * j]); } } //Set up some texture parameters for opengl Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[c]); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR); //Create the texture Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, width, height, 0, Gl.GL_LUMINANCE_ALPHA, Gl.GL_UNSIGNED_BYTE, expanded); expanded = null; bmp = null; //Create a display list and bind a texture to it Gl.glNewList((list_base + c), Gl.GL_COMPILE); Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[c]); //Account for freetype spacing rules Gl.glTranslatef(glyphrec.bitmap_left, 0, 0); Gl.glPushMatrix(); Gl.glTranslatef(0, glyphrec.bitmap_top - glyphrec.bitmap.rows, 0); float x = (float)glyphrec.bitmap.width / (float)width; float y = (float)glyphrec.bitmap.rows / (float)height; offset.left = glyphrec.bitmap_left; offset.top = glyphrec.bitmap_top; offset.height = glyphrec.bitmap.rows; offset.width = glyphrec.bitmap.width; offset.advance = glyphrec.advance; offset.lsb_delta = glyphrec.lsb_delta; offset.rsb_delta = glyphrec.rsb_delta; offset.linearHoriAdvance = glyphrec.linearHoriAdvance; offset.linearVertAdvance = glyphrec.linearVertAdvance; offsets[c] = offset; //Draw the quad Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2d(0, 0); Gl.glVertex2f(0, glyphrec.bitmap.rows); Gl.glTexCoord2d(0, y); Gl.glVertex2f(0, 0); Gl.glTexCoord2d(x, y); Gl.glVertex2f(glyphrec.bitmap.width, 0); Gl.glTexCoord2d(x, 0); Gl.glVertex2f(glyphrec.bitmap.width, glyphrec.bitmap.rows); Gl.glEnd(); Gl.glPopMatrix(); //Advance for the next character Gl.glTranslatef(glyphrec.bitmap.width, 0, 0); extent_x[c] = glyphrec.bitmap_left + glyphrec.bitmap.width; Gl.glEndList(); sChars += "f:" + c.ToString() + "[w:" + glyphrec.bitmap.width.ToString() + "][h:" + glyphrec.bitmap.rows.ToString() + "]" + sError; }
private void CompileCharacterToTexture(Face face, int c) { FTGlyphOffset offset = new FTGlyphOffset(); //We first convert the number index to a character index //uint index = FT.FT_Get_Char_Index(faceptr, (uint)c); uint index = sharpFace.GetCharIndex((uint)c); string sError = ""; if (index == 0) { sError = "No Glyph"; } //Here we load the actual glyph for the character //int ret = FT.FT_Load_Glyph(faceptr, index, FT.FT_LOAD_DEFAULT); //if (ret != 0) //{ // Console.Write("Load_Glyph failed for character " + c.ToString()); //} try { sharpFace.LoadGlyph(index, LoadFlags.Default, LoadTarget.Normal); } catch { Console.Write("Load_Glyph failed for character " + c.ToString()); } // FT_GlyphSlotRec glyphrec = (FT_GlyphSlotRec)Marshal.PtrToStructure(face.glyph, typeof(FT_GlyphSlotRec)); //ret = FT.FT_Render_Glyph(ref glyphrec, FT_Render_Mode.FT_RENDER_MODE_NORMAL); // if (ret != 0) //{ // Console.Write("Render failed for character " + c.ToString()); //} GlyphSlot glyphrec = sharpFace.Glyph; int size = (glyphrec.Bitmap.Width * glyphrec.Bitmap.Rows); if (size <= 0) { //Console.Write("Blank Character: " + c.ToString()); //space is a special `blank` character extent_x[c] = 0; if (c == 32) { GL.NewList((list_base + c), ListMode.Compile); GL.Translate(font_size >> 1, 0, 0); extent_x[c] = font_size >> 1; GL.EndList(); offset.left = 0; offset.top = 0; offset.height = 0; offset.width = extent_x[c]; offsets[c] = offset; } return; } byte[] bmp = new byte[size]; Marshal.Copy(glyphrec.Bitmap.Buffer, bmp, 0, bmp.Length); //Next we expand the bitmap into an opengl texture int width = next_po2(glyphrec.Bitmap.Width); int height = next_po2(glyphrec.Bitmap.Rows); byte[] expanded = new byte[2 * width * height]; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { //Luminance expanded[2 * (i + j * width)] = (byte)255; //expanded[4 * (i + j * width) + 1] = (byte)255; //expanded[4 * (i + j * width) + 2] = (byte)255; // Alpha expanded[2 * (i + j * width) + 1] = (i >= glyphrec.Bitmap.Width || j >= glyphrec.Bitmap.Rows) ? (byte)0 : (byte)(bmp[i + glyphrec.Bitmap.Width * j]); } } //Set up some texture parameters for opengl GL.BindTexture(TextureTarget.Texture2D, textures[c]); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, 0x812F); //const Int32 GL_CLAMP_TO_EDGE = 0x812F; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, 0x812F); //const Int32 GL_CLAMP_TO_EDGE = 0x812F; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, 0x2601); //const Int32 GL_LINEAR = 0x2601; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, 0x2601); //const Int32 GL_LINEAR = 0x2601; //Create the texture GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.LuminanceAlpha, PixelType.UnsignedByte, expanded); expanded = null; bmp = null; //Create a display list and bind a texture to it GL.NewList((list_base + c), ListMode.Compile); GL.BindTexture(TextureTarget.Texture2D, textures[c]); //Account for freetype spacing rules GL.Translate(glyphrec.BitmapLeft, 0, 0); GL.PushMatrix(); GL.Translate(0, glyphrec.BitmapTop - glyphrec.Bitmap.Rows, 0); float x = (float)glyphrec.Bitmap.Width / (float)width; float y = (float)glyphrec.Bitmap.Rows / (float)height; offset.left = glyphrec.BitmapLeft; offset.top = glyphrec.BitmapTop; offset.height = glyphrec.Bitmap.Rows; offset.width = glyphrec.Bitmap.Width; offset.advance = glyphrec.Advance; offset.lsb_delta = glyphrec.DeltaLsb; offset.rsb_delta = glyphrec.DeltaRsb; offset.linearHoriAdvance = glyphrec.LinearHorizontalAdvance; offset.linearVertAdvance = glyphrec.LinearVerticalAdvance; offsets[c] = offset; //Draw the quad GL.Begin(BeginMode.Quads); GL.TexCoord2(0, 0); GL.Vertex2(0, glyphrec.Bitmap.Rows); GL.TexCoord2(0, y); GL.Vertex2(0, 0); GL.TexCoord2(x, y); GL.Vertex2(glyphrec.Bitmap.Width, 0); GL.TexCoord2(x, 0); GL.Vertex2(glyphrec.Bitmap.Width, glyphrec.Bitmap.Rows); GL.End(); GL.PopMatrix(); //Advance for the next character GL.Translate(glyphrec.Bitmap.Width, 0, 0); extent_x[c] = glyphrec.BitmapLeft + glyphrec.Bitmap.Width; GL.EndList(); sChars += "f:" + c.ToString() + "[w:" + glyphrec.Bitmap.Width.ToString() + "][h:" + glyphrec.Bitmap.Rows.ToString() + "]" + sError; }