Example #1
0
        /// <summary>
        /// Function to persist the shader data to a stream as a <see cref="GorgonChunkFile{T}"/>.
        /// </summary>
        /// <param name="stream">The stream to write the data into.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="stream"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentException">Thrown when the stream is read only.</exception>
        /// <remarks>
        /// <para>
        /// This will write the shader data as <see cref="GorgonChunkFile{T}"/> formatted data into the supplied <paramref name="stream"/>. Shaders may take some time to compile, saving them to a binary
        /// format in a stream will help cut down on the time it takes to initialize an application.
        /// </para>
        /// <para>
        /// This makes use of the Gorgon <see cref="GorgonChunkFile{T}"/> format to allow flexible storage of data. The Gorgon shader format is broken into 2 chunks, both of which are available in the
        /// <see cref="GorgonShaderFactory.BinaryShaderMetaData"/>, and <see cref="GorgonShaderFactory.BinaryShaderByteCode"/> constants. The file header for the format is stored in the
        /// <see cref="GorgonShaderFactory.BinaryShaderFileHeader"/> constant.
        /// </para>
        /// <para>
        /// The file format is as follows:
        /// <list type="bullet">
        ///		<item>
        ///			<term><see cref="GorgonShaderFactory.BinaryShaderFileHeader"/></term>
        ///			<description>This describes the type of file, and the version.</description>
        ///		</item>
        ///		<item>
        ///			<term><see cref="GorgonShaderFactory.BinaryShaderMetaData"/></term>
        ///			<description>Shader metadata, such as the <see cref="Core.ShaderType"/> (<see cref="int"/>), debug flag (<see cref="bool"/>), and the entry point name (<see cref="string"/>) is stored here.</description>
        ///		</item>
        ///		<item>
        ///			<term><see cref="GorgonShaderFactory.BinaryShaderByteCode"/></term>
        ///			<description>The compiled shader byte code is stored here and is loaded as a <see cref="byte"/> array.</description>
        ///		</item>
        /// </list>
        /// </para>
        /// </remarks>
        /// <seealso cref="GorgonChunkFile{T}"/>
        /// <seealso cref="GorgonChunkFileReader"/>
        /// <seealso cref="GorgonChunkFileWriter"/>
        public void SaveToStream(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (!stream.CanWrite)
            {
                throw new ArgumentException(Resources.GORGFX_ERR_STREAM_WRITE_ONLY, nameof(stream));
            }

            var chunkFile = new GorgonChunkFileWriter(stream, GorgonShaderFactory.BinaryShaderFileHeader.ChunkID());

            try
            {
                GorgonBinaryWriter writer     = chunkFile.OpenChunk(GorgonShaderFactory.BinaryShaderMetaData);
                ShaderType         shaderType = ShaderType;
                writer.WriteValue(ref shaderType);
                writer.WriteValue(ref _isDebug);
                writer.Write(Name);
                chunkFile.CloseChunk();

                writer = chunkFile.OpenChunk(GorgonShaderFactory.BinaryShaderByteCode);
                writer.Write(D3DByteCode.Data);
            }
            finally
            {
                chunkFile.CloseChunk();
            }
        }
Example #2
0
        /// <summary>
        /// Function to write the font data to the stream.
        /// </summary>
        /// <param name="fontData">The font data to write.</param>
        /// <param name="stream">The stream to write into.</param>
        /// <remarks>
        /// <para>
        /// Implementors must override this method to write out the font data in the expected format.
        /// </para>
        /// </remarks>
        protected override void OnWriteFontData(GorgonFont fontData, Stream stream)
        {
            var             fontFile = new GorgonChunkFileWriter(stream, FileHeader.ChunkID());
            IGorgonFontInfo fontInfo = fontData.Info;

            try
            {
                fontFile.Open();

                GorgonBinaryWriter writer = fontFile.OpenChunk(FontInfoChunk);

                writer.Write(fontInfo.FontFamilyName);
                writer.Write(fontInfo.Size);
                writer.WriteValue(fontInfo.FontHeightMode);
                writer.WriteValue(fontInfo.FontStyle);
                writer.Write(fontInfo.DefaultCharacter);
                writer.Write(string.Join(string.Empty, fontInfo.Characters));
                writer.WriteValue(fontInfo.AntiAliasingMode);
                writer.Write(fontInfo.OutlineColor1.ToARGB());
                writer.Write(fontInfo.OutlineColor2.ToARGB());
                writer.Write(fontInfo.OutlineSize);
                writer.Write(fontInfo.PackingSpacing);
                writer.Write(fontInfo.TextureWidth);
                writer.Write(fontInfo.TextureHeight);
                writer.Write(fontInfo.UsePremultipliedTextures);
                writer.Write(fontInfo.UseKerningPairs);
                fontFile.CloseChunk();

                writer = fontFile.OpenChunk(FontHeightChunk);
                writer.Write(fontData.FontHeight);
                writer.Write(fontData.LineHeight);
                writer.Write(fontData.Ascent);
                writer.Write(fontData.Descent);
                fontFile.CloseChunk();

                if (fontInfo.Brush != null)
                {
                    writer = fontFile.OpenChunk(BrushChunk);
                    writer.Write((int)fontInfo.Brush.BrushType);
                    fontInfo.Brush.WriteBrushData(writer);
                    fontFile.CloseChunk();
                }

                if (fontInfo.UseKerningPairs)
                {
                    WriteKerningValues(fontData, fontFile);
                }
            }
            finally
            {
                fontFile.Close();
            }
        }
Example #3
0
        /// <summary>
        /// Function to write out the kerning pair information for the font.
        /// </summary>
        /// <param name="fontData">The font data to write.</param>
        /// <param name="fontFile">The font file that is being persisted.</param>
        private static void WriteKerningValues(GorgonFont fontData, GorgonChunkFileWriter fontFile)
        {
            GorgonBinaryWriter writer = fontFile.OpenChunk(KernDataChunk);

            writer.Write(fontData.KerningPairs.Count);

            foreach (KeyValuePair <GorgonKerningPair, int> kerningInfo in fontData.KerningPairs)
            {
                writer.Write(kerningInfo.Key.LeftCharacter);
                writer.Write(kerningInfo.Key.RightCharacter);
                writer.Write(kerningInfo.Value);
            }

            fontFile.CloseChunk();
        }
Example #4
0
        public void ChunkReaderWriter()
        {
            const string stringChunk = "STRSCHNK";
            const string intChunk    = "INTSCHNK";
            const string header      = "TheHeader";

            string[] strs =
            {
                "Cow",
                "Dog",
                "Cat",
                "Rabbit",
                "Duck"
            };

            int[] ints =
            {
                32,
                11,
                89,
                64,
                87,
                77,
                16,
                2,
                42
            };

            int expectedStrLength  = strs.Length;
            int expectedIntsLength = ints.Length;

            using (MemoryStream stream = new MemoryStream())
            {
                var fileWriter = new GorgonChunkFileWriter(stream, header.ChunkID());
                fileWriter.Open();

                GorgonBinaryWriter writer = fileWriter.OpenChunk(stringChunk.ChunkID());

                writer.Write(strs.Length);

                foreach (string str in strs)
                {
                    writer.Write(str);
                }

                fileWriter.CloseChunk();

                writer = fileWriter.OpenChunk(intChunk.ChunkID());

                writer.Write(ints.Length);

                foreach (int intVal in ints)
                {
                    writer.Write(intVal);
                }

                fileWriter.CloseChunk();

                fileWriter.Close();

                stream.Position = 0;

                var fileReader = new GorgonChunkFileReader(stream,
                                                           new[]
                {
                    header.ChunkID()
                });

                fileReader.Open();

                GorgonBinaryReader reader = fileReader.OpenChunk(intChunk.ChunkID());

                int numInts = reader.ReadInt32();

                Assert.AreEqual(expectedIntsLength, numInts);

                int[] intVals = new int[numInts];

                for (int i = 0; i < numInts; ++i)
                {
                    intVals[i] = reader.ReadInt32();
                }

                Assert.IsTrue(ints.SequenceEqual(intVals));

                fileReader.CloseChunk();

                reader = fileReader.OpenChunk(stringChunk.ChunkID());

                int numStrs = reader.ReadInt32();

                Assert.AreEqual(expectedStrLength, numStrs);

                string[] strVals = new string[numStrs];

                for (int i = 0; i < numStrs; ++i)
                {
                    strVals[i] = reader.ReadString();
                }

                Assert.IsTrue(strs.SequenceEqual(strVals));

                fileReader.CloseChunk();

                fileReader.Close();
            }
        }