/// <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); }
/// <summary> /// Update eventual buffers required to hold glyph instances information. /// </summary> /// <param name="ctx"></param> /// <param name="glyphsInstances"></param> private void UpdateGlyphBuffer(GraphicsContext ctx, List <GlyphModelType> glyphsInstances) { // Set instances (in case of GL_ARB_draw_instanced and GL_ARB_uniform_buffer_object) // Note: update only once the uniform buffer if (_GlyphUniformBuffer != null) { _GlyphUniformBuffer.Map(ctx, BufferAccess.WriteOnly); try { for (int i = 0; i < glyphsInstances.Count; i++) { GlyphModelType glyph = glyphsInstances[i]; string structName = "glo_Glyphs[" + i + "]"; _GlyphUniformBuffer.SetUniform(structName + ".ModelViewProjection", glyph.ModelViewProjection); _GlyphUniformBuffer.SetUniform(structName + ".VertexParams", glyph.VertexParams); _GlyphUniformBuffer.SetUniform(structName + ".TexParams", glyph.TexParams); } } finally { _GlyphUniformBuffer.Unmap(ctx); } } // Set instances (in case of GL_ARB_instanced_arrays) // Note: update only once the array buffer if (_GlyphInstances != null) { _GlyphInstances.Map(ctx, BufferAccess.WriteOnly); try { for (uint i = 0; i < glyphsInstances.Count; i++) { GlyphModelType glyph = glyphsInstances[(int)i]; _GlyphInstances.SetElement(glyph.ModelViewProjection, i, 0); _GlyphInstances.SetElement(glyph.VertexParams, i, 1); _GlyphInstances.SetElement(glyph.TexParams, i, 2); } } finally { _GlyphInstances.Unmap(ctx); } } }