Beispiel #1
0
        /// <summary>Reserves the required space in the vertex and index arrays</summary>
        /// <param name="font">Font the vertices for the letters will be taken from</param>
        /// <param name="text">String of which a mesh will be built</param>
        private void resizeVertexAndIndexArrays(VectorFont font, string text)
        {
            int vertexCount = 0;
            int indexCount  = 0;

            // Count the vertices and indices requires for all characters in the string
            for (int index = 0; index < text.Length; ++index)
            {
                int fontCharacterIndex;

                // Try to find the current character in the font's character map. If it isn't
                // there, we'll ignore it, just like the mesh creation routine does.
                if (font.CharacterMap.TryGetValue(text[index], out fontCharacterIndex))
                {
                    VectorFontCharacter character = font.Characters[fontCharacterIndex];

                    vertexCount += character.Vertices.Count * 2;  // multiply by 2 for front and
                    indexCount  += character.Faces.Count * 3 * 2; // back face of the mesh

                    // There may be empty characters (characters without a visual representation
                    // in the font, so we need to check this before accessing the outline array
                    if (character.Outlines.Count > 0)
                    {
                        VectorFontCharacter.Outline finalOutline =
                            character.Outlines[character.Outlines.Count - 1];

                        int outlineVertexCount = finalOutline.StartVertexIndex + finalOutline.VertexCount;
                        indexCount += outlineVertexCount * 6; // 2 triangles each
                    }
                }
            }

            this.vertices = new VertexPositionNormalTexture[vertexCount];
            this.indices  = new short[indexCount];
        }
Beispiel #2
0
        /// <summary>Reserves the required space in the vertex and index arrays</summary>
        /// <param name="font">Font the vertices for the letters will be taken from</param>
        /// <param name="text">String of which a mesh will be built</param>
        private void resizeVertexAndIndexArrays(VectorFont font, string text)
        {
            int vertexCount = 0;
            int indexCount  = 0;

            // Count the vertices and indices requires for all characters in the string
            for (int index = 0; index < text.Length; ++index)
            {
                int fontCharacterIndex;

                // Try to find the current character in the font's character map. If it isn't
                // there, we'll ignore it, just like the vertex creation routine does.
                if (font.CharacterMap.TryGetValue(text[index], out fontCharacterIndex))
                {
                    VectorFontCharacter character = font.Characters[fontCharacterIndex];

                    // There may be empty characters (characters without a visual representation
                    // in the font, so we need to check this before accessing the outline array
                    if (character.Outlines.Count > 0)
                    {
                        VectorFontCharacter.Outline finalOutline =
                            character.Outlines[character.Outlines.Count - 1];

                        // We calculate the vertex count from the outline instead of just taking
                        // the size of the vertex array because we might not need all vertices to
                        // render an outline (some have been added by the tessellation processor and
                        // are only used as supporting vertices to fill the faces)
                        int outlineVertexCount = finalOutline.StartVertexIndex + finalOutline.VertexCount;

                        // Advance the counters
                        vertexCount += outlineVertexCount;
                        indexCount  += outlineVertexCount * 2;
                    }
                }
            }

            this.vertices = new VertexPositionNormalTexture[vertexCount];
            this.indices  = new short[indexCount];
        }
Beispiel #3
0
        /// <summary>Builds the combined outline for the letters in this string</summary>
        /// <param name="font">Vector font to take the vertex data from</param>
        /// <param name="text">String of which a mesh is to be built</param>
        private void buildStringOutline(VectorFont font, string text)
        {
            Vector2 position = Vector2.Zero;

            int baseVertexIndex = 0; // base index in the vertex array
            int baseIndexIndex  = 0; // base index in the index array

            for (int characterIndex = 0; characterIndex < text.Length; ++characterIndex)
            {
                int fontCharacterIndex;

                // Only add this character to the mesh if there is an actual font character
                // for this unicode symbol in the font (characters not imported by the user
                // will be silently skipped -- this is the only sane option imho)
                if (font.CharacterMap.TryGetValue(text[characterIndex], out fontCharacterIndex))
                {
                    VectorFontCharacter character = font.Characters[fontCharacterIndex];

                    if (character.Outlines.Count > 0)
                    {
                        VectorFontCharacter.Outline finalOutline =
                            character.Outlines[character.Outlines.Count - 1];

                        // We calculate the vertex count from the outline instead of just taking
                        // the size of the vertex array because we might not need all vertices to
                        // render an outline (some have been added by the tessellation processor and
                        // are only used as supporting vertices to fill the faces)
                        int outlineVertexCount = finalOutline.StartVertexIndex + finalOutline.VertexCount;

                        // Import all of the vertices of this font (we need both the outline vertices
                        // as well as the mesh supporting vertices)
                        for (int index = 0; index < outlineVertexCount; ++index)
                        {
                            this.vertices[baseVertexIndex + index] = new VertexPositionNormalTexture(
                                new Vector3(character.Vertices[index] + position, 0.0f),
                                Vector3.Forward, Vector2.Zero
                                );
                        }

                        // Transform the outline index ranges into single big line list pointing
                        // to the vertices we just imported from the font
                        for (int index = 0; index < character.Outlines.Count; ++index)
                        {
                            VectorFontCharacter.Outline outline = character.Outlines[index];

                            // Set up the indices for the outline exluding the final connection from
                            // the outline's end to its start
                            for (int lineIndex = 0; lineIndex < outline.VertexCount - 1; ++lineIndex)
                            {
                                this.indices[baseIndexIndex + lineIndex * 2 + 0] =
                                    (short)(baseVertexIndex + outline.StartVertexIndex + lineIndex);
                                this.indices[baseIndexIndex + lineIndex * 2 + 1] =
                                    (short)(baseVertexIndex + outline.StartVertexIndex + lineIndex + 1);
                            }

                            // Add the connection from the end of the outline to its start
                            this.indices[baseIndexIndex + outline.VertexCount * 2 - 2] =
                                (short)(baseVertexIndex + outline.StartVertexIndex + outline.VertexCount - 1);
                            this.indices[baseIndexIndex + outline.VertexCount * 2 - 1] =
                                (short)(baseVertexIndex + outline.StartVertexIndex);

                            // Advance the index pointer for the next run
                            baseIndexIndex += outline.VertexCount * 2;
                        }

                        // Adjust the base vertex index for the next character
                        baseVertexIndex += outlineVertexCount;
                    }

                    // Advance to the next character
                    position += character.Advancement;
                } // if
            }     // for

            this.width         = position.X;
            this.height        = font.LineHeight;
            this.primitiveType = PrimitiveType.LineList;
        }
Beispiel #4
0
        /// <summary>Builds the combined mesh for the letters in this string</summary>
        /// <param name="font">Vector font to take the vertex data from</param>
        /// <param name="text">String of which a mesh is to be built</param>
        private void buildStringMesh(VectorFont font, string text)
        {
            Vector2 position = Vector2.Zero;

            int baseVertexIndex = 0; // base index in the vertex array
            int baseIndexIndex  = 0; // base index in the index array

            for (int characterIndex = 0; characterIndex < text.Length; ++characterIndex)
            {
                int fontCharacterIndex;

                // Only add this character to the mesh if there is an actual font character
                // for this unicode symbol in the font (characters not imported by the user
                // will be silently skipped -- this is the only sane option imho)
                if (font.CharacterMap.TryGetValue(text[characterIndex], out fontCharacterIndex))
                {
                    VectorFontCharacter character = font.Characters[fontCharacterIndex];

                    // Import all of the vertices of this font (we need both the outline vertices
                    // as well as the mesh supporting vertices). Each vertex is imported two times,
                    // once with a z coordinate of -0.5 and once with a z coordinate of +0.5
                    for (int vertexIndex = 0; vertexIndex < character.Vertices.Count; ++vertexIndex)
                    {
                        Vector2 adjustedPosition = character.Vertices[vertexIndex] + position;
                        Vector3 frontPosition    = new Vector3(adjustedPosition, -0.5f);
                        Vector3 backPosition     = new Vector3(adjustedPosition, +0.5f);

                        Vector2 textureCoordinates = new Vector2(
                            (frontPosition.X / font.LineHeight + frontPosition.Z) / 2.0f,
                            frontPosition.Y / font.LineHeight
                            );

                        this.vertices[baseVertexIndex + vertexIndex * 2 + 0] = new TextVertex(
                            frontPosition, Vector3.Forward, textureCoordinates
                            );
                        this.vertices[baseVertexIndex + vertexIndex * 2 + 1] = new TextVertex(
                            backPosition, Vector3.Backward, textureCoordinates
                            );
                    }

                    // Transform the outline index ranges into single big line list pointing
                    // to the vertices we just imported from the font
                    for (int index = 0; index < character.Outlines.Count; ++index)
                    {
                        VectorFontCharacter.Outline outline = character.Outlines[index];
                        int startIndex, endIndex;

                        // Set up the indices for the outline exluding the final connection from
                        // the outline's end to its start
                        for (int lineIndex = 0; lineIndex < outline.VertexCount - 1; ++lineIndex)
                        {
                            startIndex = baseVertexIndex + (outline.StartVertexIndex + lineIndex) * 2;
                            endIndex   = startIndex + 2;

                            this.indices[baseIndexIndex + lineIndex * 6 + 0] = (short)(startIndex + 0);
                            this.indices[baseIndexIndex + lineIndex * 6 + 1] = (short)(startIndex + 1);
                            this.indices[baseIndexIndex + lineIndex * 6 + 2] = (short)(endIndex + 0);
                            this.indices[baseIndexIndex + lineIndex * 6 + 3] = (short)(endIndex + 0);
                            this.indices[baseIndexIndex + lineIndex * 6 + 4] = (short)(startIndex + 1);
                            this.indices[baseIndexIndex + lineIndex * 6 + 5] = (short)(endIndex + 1);
                        }

                        int lastLineIndex = outline.VertexCount - 1;
                        startIndex = baseVertexIndex + outline.StartVertexIndex * 2;
                        endIndex   = startIndex + lastLineIndex * 2;

                        this.indices[baseIndexIndex + lastLineIndex * 6 + 0] = (short)(startIndex + 0);
                        this.indices[baseIndexIndex + lastLineIndex * 6 + 1] = (short)(startIndex + 1);
                        this.indices[baseIndexIndex + lastLineIndex * 6 + 2] = (short)(endIndex + 0);
                        this.indices[baseIndexIndex + lastLineIndex * 6 + 3] = (short)(endIndex + 0);
                        this.indices[baseIndexIndex + lastLineIndex * 6 + 4] = (short)(startIndex + 1);
                        this.indices[baseIndexIndex + lastLineIndex * 6 + 5] = (short)(endIndex + 1);

                        // Advance the index pointer for the next run
                        baseIndexIndex += outline.VertexCount * 6;
                    }

                    // Add the indices for the vertices of font's faces, once for the front face and
                    // once for the back face we generated.
                    for (int faceIndex = 0; faceIndex < character.Faces.Count; ++faceIndex)
                    {
                        this.indices[baseIndexIndex + faceIndex * 6 + 0] =
                            (short)(character.Faces[faceIndex].FirstVertexIndex * 2 + baseVertexIndex);
                        this.indices[baseIndexIndex + faceIndex * 6 + 1] =
                            (short)(character.Faces[faceIndex].SecondVertexIndex * 2 + baseVertexIndex);
                        this.indices[baseIndexIndex + faceIndex * 6 + 2] =
                            (short)(character.Faces[faceIndex].ThirdVertexIndex * 2 + baseVertexIndex);

                        this.indices[baseIndexIndex + faceIndex * 6 + 3] =
                            (short)(character.Faces[faceIndex].FirstVertexIndex * 2 + baseVertexIndex + 1);
                        this.indices[baseIndexIndex + faceIndex * 6 + 4] =
                            (short)(character.Faces[faceIndex].SecondVertexIndex * 2 + baseVertexIndex + 1);
                        this.indices[baseIndexIndex + faceIndex * 6 + 5] =
                            (short)(character.Faces[faceIndex].ThirdVertexIndex * 2 + baseVertexIndex + 1);
                    }

                    // Adjust the base vertex index for the next character
                    baseIndexIndex  += character.Faces.Count * 6;
                    baseVertexIndex += character.Vertices.Count * 2;

                    // Update the position to the next character
                    position += character.Advancement;
                } // if
            }     // for

            this.width         = position.X;
            this.height        = font.LineHeight;
            this.primitiveType = PrimitiveType.TriangleList;
        }