Ejemplo n.º 1
0
        /// <summary>
        /// Create a <see cref="VertexArrayObject"/> for rendering glyphs.
        /// </summary>
        private void LinkSharedResources(GraphicsContext ctx)
        {
            CheckCurrentContext(ctx);

            string resourceClassId = "OpenGL.Objects.FontPatch";
            string resourceBaseId  = String.Format("{0}.{1}-{2}-{3}", resourceClassId, Family, Size, Style);

            string vertexArrayId = resourceBaseId + ".VertexArray";
            string glyphDbId     = resourceBaseId + ".GlyphDb";

            #region Vertex Arrays

            _VertexArrays = (VertexArrayObject)ctx.GetSharedResource(vertexArrayId);
            Dictionary <char, Glyph> glyphsDb = null;

            if (_VertexArrays == null)
            {
                _VertexArrays = new VertexArrayObject();

                List <GlyphPolygons> glyphPolygons  = GenerateGlyphs(Family, Size, Style);
                List <Vertex2f>      glyphsVertices = new List <Vertex2f>();
                GlyphPolygons        gGlyph         = null;
                uint gVertexIndex = 0;

                glyphsDb = new Dictionary <char, Glyph>();

                using (Tessellator tessellator = new Tessellator()) {
                    tessellator.Begin += delegate(object sender, TessellatorBeginEventArgs e) {
                        gVertexIndex = (uint)glyphsVertices.Count;
                    };
                    tessellator.End += delegate(object sender, EventArgs e) {
                        // Create element (range)
                        int glyphIndex = _VertexArrays.SetElementArray(PrimitiveType.Triangles, gVertexIndex, (uint)glyphsVertices.Count - gVertexIndex);

                        glyphsDb.Add(gGlyph.GlyphChar, new Glyph(gGlyph.GlyphChar, gGlyph.GlyphSize, glyphIndex));
                    };
                    tessellator.Vertex += delegate(object sender, TessellatorVertexEventArgs e) {
                        glyphsVertices.Add((Vertex2f)e.Vertex);
                    };

                    // Tessellate all glyphs
                    foreach (GlyphPolygons glyph in glyphPolygons)
                    {
                        gGlyph = glyph;

                        if (glyph.Contours.Count == 0)
                        {
                            glyphsDb.Add(gGlyph.GlyphChar, new Glyph(gGlyph.GlyphChar, gGlyph.GlyphSize, -1));
                            continue;
                        }

                        tessellator.BeginPolygon();
                        foreach (List <Vertex2f> countour in glyph.Contours)
                        {
                            tessellator.AddContour(countour.ToArray(), Vertex3f.UnitZ);
                        }
                        tessellator.EndPolygon();
                    }
                }

                // Element vertices
                ArrayBufferObject <Vertex2f> gVertexPosition = new ArrayBufferObject <Vertex2f>(BufferObjectHint.StaticCpuDraw);
                gVertexPosition.Create(glyphsVertices.ToArray());
                _VertexArrays.SetArray(gVertexPosition, VertexArraySemantic.Position);

                // Share
                ctx.SetSharedResource(vertexArrayId, _VertexArrays);
            }
            LinkResource(_VertexArrays);

            #endregion

            #region Glyph Metadata

            _Glyphs = (Dictionary <char, Glyph>)ctx.GetSharedResource(glyphDbId);

            if (glyphsDb != null)
            {
                _Glyphs = glyphsDb;
            }
            if (_Glyphs == null)
            {
                throw new InvalidProgramException("no glyph metadata");
            }

            // Share
            ctx.SetSharedResource(glyphDbId, _Glyphs);

            #endregion
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Create a <see cref="VertexArrayObject"/> for rendering glyphs.
        /// </summary>
        /// <param name="fontFamily"></param>
        /// <param name="emSize"></param>
        /// <param name="glyphs"></param>
        /// <returns></returns>
        private static VertexArrayObject CreateVertexArray(GraphicsContext ctx, FontFamily fontFamily, uint emSize, FontStyle fontStyle, out Dictionary <char, Glyph> glyphs)
        {
            CheckCurrentContext(ctx);

            string resourceBaseId = String.Format("OpenGL.Objects.FontPatch.{0}-{1}-{2}", fontFamily, emSize, fontStyle);
            string vertexArrayId  = resourceBaseId + ".VertexArray";
            string glyphDbId      = resourceBaseId + ".GlyphDb";

            VertexArrayObject        vertexArrays = (VertexArrayObject)ctx.GetSharedResource(vertexArrayId);
            Dictionary <char, Glyph> glyphsDb     = (Dictionary <char, Glyph>)ctx.GetSharedResource(glyphDbId);

            if (vertexArrays != null && glyphsDb != null)
            {
                glyphs = glyphsDb;
                return(vertexArrays);
            }

            vertexArrays = new VertexArrayObject();
            glyphsDb     = new Dictionary <char, Glyph>();

            List <GlyphPolygons> glyphPolygons  = GenerateGlyphs(fontFamily, emSize, fontStyle);
            List <Vertex2f>      glyphsVertices = new List <Vertex2f>();
            GlyphPolygons        gGlyph         = null;
            uint gVertexIndex = 0;

            glyphs = new Dictionary <char, Glyph>();

            using (Tessellator tessellator = new Tessellator()) {
                tessellator.Begin += delegate(object sender, TessellatorBeginEventArgs e) {
                    gVertexIndex = (uint)glyphsVertices.Count;
                };
                tessellator.End += delegate(object sender, EventArgs e) {
                    // Create element (range)
                    int glyphIndex = vertexArrays.SetElementArray(PrimitiveType.Triangles, gVertexIndex, (uint)glyphsVertices.Count - gVertexIndex);

                    glyphsDb.Add(gGlyph.GlyphChar, new Glyph(gGlyph.GlyphChar, gGlyph.GlyphSize, glyphIndex));
                };
                tessellator.Vertex += delegate(object sender, TessellatorVertexEventArgs e) {
                    glyphsVertices.Add((Vertex2f)e.Vertex);
                };

                // Tessellate all glyphs
                foreach (GlyphPolygons glyph in glyphPolygons)
                {
                    gGlyph = glyph;

                    if (glyph.Contours.Count == 0)
                    {
                        glyphsDb.Add(gGlyph.GlyphChar, new Glyph(gGlyph.GlyphChar, gGlyph.GlyphSize, -1));
                        continue;
                    }

                    tessellator.BeginPolygon();
                    foreach (List <Vertex2f> countour in glyph.Contours)
                    {
                        tessellator.AddContour(countour.ToArray(), Vertex3f.UnitZ);
                    }
                    tessellator.EndPolygon();
                }
            }

            // Element vertices
            ArrayBufferObject <Vertex2f> gVertexPosition = new ArrayBufferObject <Vertex2f>(BufferObjectHint.StaticCpuDraw);

            gVertexPosition.Create(glyphsVertices.ToArray());
            vertexArrays.SetArray(gVertexPosition, VertexArraySemantic.Position);

            // Returns glyphs database
            glyphs = glyphsDb;

            // Share resources
            ctx.SetSharedResource(vertexArrayId, vertexArrays);
            ctx.SetSharedResource(glyphDbId, glyphsDb);

            return(vertexArrays);
        }