/// <summary> /// Draw a character sequence. /// </summary> /// <param name="ctx"> /// The <see cref="GraphicsContext"/> used for drawing. /// </param> /// <param name="modelview"> /// The <see cref="Matrix4x4"/> the model-view-projection matrix for the first character of <paramref name="s"/>. /// </param> /// <param name="color"> /// The <see cref="ColorRGBAF"/> that specifies the glyph color. /// </param> /// <param name="s"> /// A <see cref="String"/> that specifies the characters for be drawn. /// </param> public override void DrawString(GraphicsContext ctx, Matrix4x4 modelview, ColorRGBAF color, string s) { ModelMatrix charModel = new ModelMatrix(modelview); ctx.Bind(_FontProgram); // Set uniforms _FontProgram.SetUniform(ctx, "glo_UniformColor", color); _FontProgram.SetUniform(ctx, "glo_FontGlyph", _FontTexture); // Set instances char[] fontChars = s.ToCharArray(); uint instances = 0; _GlyphInstances.Map(ctx, BufferAccessARB.WriteOnly); try { for (int i = 0; i < fontChars.Length; i++) { Glyph glyph; if (_GlyphDb.TryGetValue(fontChars[i], out glyph) == false) { continue; } // Set instance information Matrix4x4f modelViewProjection = new Matrix4x4f( new Vertex4f(charModel.GetColumn(0)), new Vertex4f(charModel.GetColumn(1)), new Vertex4f(charModel.GetColumn(2)), new Vertex4f(charModel.GetColumn(3)) ); Vertex3f glyphVertexParams = new Vertex3f( glyph.GlyphSize.Width, glyph.GlyphSize.Height, glyph.Layer ); Vertex2f glyphTexParams = new Vertex2f( glyph.TexScale.Width, glyph.TexScale.Height ); _GlyphInstances.SetElement(modelViewProjection, instances, 0); _GlyphInstances.SetElement(glyphVertexParams, instances, 1); _GlyphInstances.SetElement(glyphTexParams, instances, 2); // Count the instance instances++; // Move next charModel.Translate(glyph.GlyphSize.Width, 0.0f); } } finally { _GlyphInstances.Unmap(ctx); } // Rasterize it using (State.BlendState stateBlend = State.BlendState.AlphaBlending) { stateBlend.ApplyState(ctx, _FontProgram); _VertexArrays.DrawInstanced(ctx, _FontProgram, instances); } }
/// <summary> /// Get a list of <see cref="GlyphModelType"/> for a specific string and model-view-projection matrix. /// </summary> /// <param name="modelview"></param> /// <param name="s"></param> /// <returns></returns> private List <GlyphModelType> GetGlyphsInstances(Matrix4x4 modelview, string s) { ModelMatrix charModel = new ModelMatrix(modelview); List <GlyphModelType> glyphsInstances = new List <GlyphModelType>(); char[] fontChars = s.ToCharArray(); for (int i = 0; i < fontChars.Length; i++) { Glyph glyph; if (_GlyphMetadata.TryGetValue(fontChars[i], out glyph) == false) { continue; } // Set instance information Matrix4x4f modelViewProjection = new Matrix4x4f( new Vertex4f(charModel.GetColumn(0)), new Vertex4f(charModel.GetColumn(1)), new Vertex4f(charModel.GetColumn(2)), new Vertex4f(charModel.GetColumn(3)) ); Vertex3f glyphVertexParams = new Vertex3f( glyph.GlyphSize.Width, glyph.GlyphSize.Height, glyph.Layer ); Vertex2f glyphTexParams = new Vertex2f( glyph.TexScale.Width, glyph.TexScale.Height ); GlyphModelType glyphModel = new GlyphModelType(); glyphModel.ModelViewProjection = modelViewProjection; glyphModel.VertexParams = glyphVertexParams; glyphModel.TexParams = glyphTexParams; glyphsInstances.Add(glyphModel); // Move next charModel.Translate(glyph.GlyphSize.Width, 0.0f); } return(glyphsInstances); }