示例#1
0
        /// <summary>
        /// Acquires a mesh for given resolution.
        /// </summary>
        /// <param name="resolution"></param>
        /// <returns></returns>
        public TriangleSoup2f AcquireFilled(float resolution)
        {
            // We first check the cache.
            if (filledCache != null)
            {
                ICacheable cacheable = filledCache.FindAndTouch(resolution);
                if (cacheable != null)
                {
                    GlyphShapeCache data = cacheable as GlyphShapeCache;
                    return(data.Data);
                }
            }

            // Otherwise not found, we create it.
            TriangleSoup2f soup = new TriangleSoup2f();

            outline.Tesselate(resolution, soup);

            if (filledCache != null)
            {
                // We ignore if already there.
                filledCache.Add(resolution, new GlyphShapeCache(soup));
            }
            return(soup);
        }
示例#2
0
        public void FillShape(IFill fill, IArea2f shape, IMapper mapper)
        {
            TriangleSoup2f soup = new TriangleSoup2f();

            shape.Tesselate(-info.TesselationResolution, soup);

            FillShape(fill, soup, mapper);
        }
示例#3
0
        /// <summary>
        /// Acquires a tesselated outline.
        /// </summary>
        /// <param name="width">The width of outline.</param>
        /// <param name="resolution"></param>
        /// <returns></returns>
        public TriangleSoup2f AcquireOutline(float resolution, OutlineTesselation.TesselationOptionsf options)
        {
            // For now caching is not supported.

            TriangleSoup2f soup = new TriangleSoup2f();

            outline.TesselateOutline(resolution, options, soup);
            return(soup);
        }
示例#4
0
        /// <summary>
        /// Render outlined characters.
        /// </summary>
        /// <param name="pen"></param>
        /// <param name="range"></param>
        public void Render(Pen pen, Vector2i range)
        {
            if (range.Y < range.X)
            {
                return;
            }
            ValidateRange(range);

            canvas.Begin(CanvasRenderFlags.SoftwarePositionTransform);
            try
            {
                for (int i = range.X; i <= range.Y; i++)
                {
                    RenderGlyphInfo info = glyphs[i];
                    if (glyphs[i].RenderingData == null)
                    {
                        continue;
                    }

                    // We set transform.
                    canvas.Transform =
                        new LinearTransform(
                            Matrix4x4f.CreateTranslate(info.LeftBottom.Vec3) *
                            Matrix4x4f.CreateScale(new Vector3f(fontSize, fontSize, fontSize))
                            );


                    // We finally render.
                    TriangleSoup2f soup =
                        info.RenderingData.AcquireOutline(canvas.CanvasInfo.TesselationResolution,
                                                          pen.ToOutlineTesselationOptions(canvas.CanvasInfo));
                    canvas.FillShape(pen.Fill, soup, info.AttachedMapper);
                }
            }
            finally
            {
                canvas.End();
            }
        }
示例#5
0
 /// <summary>
 /// A glyph shape cache.
 /// </summary>
 /// <param name="soup"></param>
 public GlyphShapeCache(TriangleSoup2f soup)
 {
     this.soup = soup;
 }
示例#6
0
        public void FillShape(IFill fill, TriangleSoup2f mesh, IMapper mapper)
        {
            if (mapper == null)
            {
                mapper = new PositionMapper();
            }

            // We first find "apropriate id" for instance independant fills
            uint fillID = uint.MaxValue;

            if (!fill.IsInstanceDependant)
            {
                for (int i = 0; i < fills.Count; i++)
                {
                    if (fills[i].GetType() == fill.GetType())
                    {
                        fillID = (uint)i;
                        break;
                    }
                }
            }
            else
            {
                int i;
                // We try to find exact (reference) match.
                for (i = 0; i < fills.Count; i++)
                {
                    if (fills[i] == fill)
                    {
                        fillID = (uint)i;
                        break;
                    }
                }

                // If we found it.
                if (i >= fills.Count)
                {
                    // We try to find compare match.
                    for (int j = 0; j < fills.Count; j++)
                    {
                        if (fills[j].Equals(fills))
                        {
                            fillID = (uint)j;
                            break;
                        }
                    }
                }
            }

            // We now insert fill if no appropriate was found.
            if (fillID == uint.MaxValue)
            {
                // We add it and save id.
                fillID = (uint)fills.Count;
                fills.Add(fill);
            }


            // We extract indices and vertices.
            List <Vector2f> vertices = mesh.Vertices;
            List <uint>     indices  = mesh.Indices;

            // We go for each triangle.
            int vertexCount = vertices.Count;

            VertexData[] triangleData = new VertexData[vertices.Count];



            // We prepare vertices.
            for (int i = 0; i < vertexCount; i++)
            {
                // We fill data.
                if (fill.CustomAttributeCount >= 1)
                {
                    triangleData[i].CustomAttribute0 = fill.CalcCustomAttribute(0, mesh, vertices[i]);

                    if (fill.CustomAttributeCount >= 2)
                    {
                        throw new NotSupportedException("Too many attributes.");
                    }
                }
                else
                {
                    triangleData[i].CustomAttribute0 = Vector3f.Zero;
                }


                // Fill ID.
                triangleData[i].FillID = fillID;

                // Positions.
                triangleData[i].Position = vertices[i];
            }

            // We generate them.
            Vector2f[] mappingCoord = mapper.Generate(mesh, vertices.ToArray());


            DataTransform ttransform = textureTransforms.Peek();

            // We do preprocessing.
            if (ttransform.Transform.NeedsPreprocess)
            {
                mappingCoord = (Vector2f[])ttransform.Transform.Preprocess(
                    PreprocessDataType.TextureCoordinates, mappingCoord);
            }

            if (ttransform.ProcessCPU)
            {
                Matrix4x4f matrix = ttransform.Transform.RuntimeForm;

                // We write them.
                for (int i = 0; i < vertexCount; i++)
                {
                    triangleData[i].TexCoord0 = (matrix * mappingCoord[i].Vec3).Vec2;
                }
            }
            else
            {
                // We write them.
                for (int i = 0; i < vertexCount; i++)
                {
                    triangleData[i].TexCoord0 = mappingCoord[i];
                }
            }

            // We may need to transform.
            DataTransform vtransform = positionTransforms.Peek();

            if (vtransform.ProcessCPU)
            {
                // We create matrix.
                Matrix4x4f matrix =
                    Matrix4x4f.CreateTranslate(new Vector3f(-unitSize.X, -unitSize.Y, 0)) *
                    Matrix4x4f.CreateScale(new Vector3f(2.0f, 2.0f, 2.0f)) *
                    vtransform.Transform.RuntimeForm;

                // We transform all points.
                for (int i = 0; i < triangleData.Length; i++)
                {
                    triangleData[i].Position = (matrix * new Vector4f(triangleData[i].Position.X,
                                                                      triangleData[i].Position.Y, 0, 1)).Vec2;
                }
            }

            // Send data to batch.
            ulong r = batch.AddVertices(triangleData);

            // If we cannot draw it, we flush and try again.
            // FIXME: this is far from optimal.
            if (r != (ulong)triangleData.LongLength)
            {
                Flush(true);

                if (batch.AddVertices(triangleData) != (ulong)triangleData.LongLength)
                {
                    throw new NotSupportedException("Big vertex chunks not supported, consider creating bigger buffers.");
                }

                batch.AddVertices(triangleData);
            }

            // We now prepare indices.
            uint[] transIndices = new uint[indices.Count];
            uint   offset       = (uint)batch.VertexCount - (uint)triangleData.Length;
            int    indexCount   = indices.Count;

            for (int i = 0; i < indexCount; i++)
            {
                transIndices[i] = indices[i] + offset;
            }

            batch.AddIndices(transIndices);
        }