Пример #1
0
        /// <summary>
        /// Function to retrieve the name of the associated texture.
        /// </summary>
        /// <param name="stream">The stream containing the texture data.</param>
        /// <returns>The name of the texture associated with the sprite, or <b>null</b> if no texture was found.</returns>
        protected override string OnGetAssociatedTextureName(Stream stream)
        {
            using (var reader = new GorgonChunkReader(stream))
            {
                if (!reader.HasChunk(FileHeader))
                {
                    throw new GorgonException(GorgonResult.CannotRead, Resources.GOR2DIO_ERR_INVALID_HEADER);
                }

                reader.Begin(FileHeader);
                reader.Begin(SpriteDataChunk);
                reader.SkipBytes(DX.Vector2.SizeInBytes
                                 + Unsafe.SizeOf <DX.Size2F>()
                                 + (sizeof(bool) * 2)
                                 + (GorgonColor.SizeInBytes * 4)
                                 + (DX.Vector2.SizeInBytes * 4));
                reader.End();

                // Read rendering information.
                reader.Begin(RenderDataChunk);
                reader.SkipBytes(Unsafe.SizeOf <CullingMode>() + Unsafe.SizeOf <GorgonRangeF>() + 91);
                reader.End();

                // Read texture information.
                reader.Begin(TextureDataChunk);
                reader.SkipBytes(GorgonColor.SizeInBytes + (sizeof(int) * 2) + Unsafe.SizeOf <TextureFilter>());
                return(reader.ReadString());
            }
        }
Пример #2
0
        /// <summary>
        /// Function to load an animation from a stream.
        /// </summary>
        /// <param name="stream">Stream to load from.</param>
        /// <returns>The animation in the stream.</returns>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="stream"/> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.ArgumentException">Thrown when the stream parameter does not contain a Gorgon animation file.
        /// <para>-or-</para>
        /// <para>Thrown when the name of the animation is already present in the controller animation collection.</para>
        /// <para>-or-</para>
        /// <para>Thrown when a track type cannot be associated with a property on the object type that the controller was declared with.</para>
        /// </exception>
        /// <exception cref="System.InvalidCastException">Thrown when the animation being loaded is for a different type than the controller was declared with.</exception>
        public GorgonAnimation <T> FromStream(Stream stream)
        {
            GorgonAnimation <T> animation;

            GorgonDebug.AssertNull(stream, "stream");

            using (var chunk = new GorgonChunkReader(stream))
            {
                // Get the header.
                chunk.Begin(AnimationVersion);

                chunk.Begin("ANIMDATA");
                // Get the type data.
                string typeString = chunk.ReadString();

                if (typeString != AnimatedObjectType.FullName)
                {
                    throw new InvalidCastException(string.Format(Resources.GORANM_ANIMATION_TYPE_MISMATCH, typeString,
                                                                 AnimatedObjectType.FullName));
                }

                // Get the name.
                string animationName = chunk.ReadString();
                if (Contains(animationName))
                {
                    throw new ArgumentException(string.Format(Resources.GORANM_ANIMATION_ALREADY_EXISTS, animationName),
                                                "stream");
                }

                animation = new GorgonAnimation <T>(this, animationName, chunk.ReadFloat())
                {
                    IsLooped = chunk.ReadBoolean()
                };

                chunk.End();

                // Get all the tracks.
                while (chunk.HasChunk("TRCKDATA"))
                {
                    chunk.Begin("TRCKDATA");

                    string trackName = chunk.ReadString();                                      // Get the name of the track.

                    if (!animation.Tracks.Contains(trackName))
                    {
                        throw new ArgumentException(
                                  string.Format(Resources.GORANM_TRACK_TYPE_DOES_NOT_EXIST, trackName, AnimatedObjectType.FullName), "stream");
                    }

                    animation.Tracks[trackName].FromChunk(chunk);

                    chunk.End();
                }
            }

            Add(animation);

            return(animation);
        }
Пример #3
0
        /// <summary>
        /// Function to read the track data from a data chunk.
        /// </summary>
        /// <param name="chunk">Chunk to read.</param>
        internal void FromChunk(GorgonChunkReader chunk)
        {
            InterpolationMode = chunk.Read <TrackInterpolationMode>();

            // Load all key frames from this track.
            while (chunk.HasChunk("KEYFRAME"))
            {
                IKeyFrame key = MakeKey();

                chunk.Begin("KEYFRAME");
                key.FromChunk(chunk);
                chunk.End();

                KeyFrames.Add(key);
            }
        }
Пример #4
0
        /// <summary>
        /// Function to load a version 1.x Gorgon sprite.
        /// </summary>
        /// <param name="graphics">The graphics interface used to create states.</param>
        /// <param name="reader">Binary reader to use to read in the data.</param>
        /// <param name="overrideTexture">The texture to assign to the sprite instead of the texture associated with the name stored in the file.</param>
        /// <returns>The sprite from the stream data.</returns>
        private static GorgonSprite LoadSprite(GorgonGraphics graphics, GorgonChunkReader reader, GorgonTexture2DView overrideTexture)
        {
            var sprite = new GorgonSprite();

            if (!reader.HasChunk(FileHeader))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GOR2DIO_ERR_INVALID_HEADER);
            }

            reader.Begin(FileHeader);
            reader.Begin(SpriteDataChunk);

            sprite.Anchor = reader.Read <DX.Vector2>();
            sprite.Size   = reader.Read <DX.Size2F>();
            sprite.Anchor = new DX.Vector2(sprite.Anchor.X / sprite.Size.Width, sprite.Anchor.Y / sprite.Size.Height);

            sprite.HorizontalFlip = reader.ReadBoolean();
            sprite.VerticalFlip   = reader.ReadBoolean();

            // Read vertex colors.
            sprite.CornerColors.UpperLeft  = reader.Read <GorgonColor>();
            sprite.CornerColors.UpperRight = reader.Read <GorgonColor>();
            sprite.CornerColors.LowerLeft  = reader.Read <GorgonColor>();
            sprite.CornerColors.LowerRight = reader.Read <GorgonColor>();

            // Write vertex offsets.
            sprite.CornerOffsets.UpperLeft  = new DX.Vector3(reader.Read <DX.Vector2>(), 0);
            sprite.CornerOffsets.UpperRight = new DX.Vector3(reader.Read <DX.Vector2>(), 0);
            sprite.CornerOffsets.LowerLeft  = new DX.Vector3(reader.Read <DX.Vector2>(), 0);
            sprite.CornerOffsets.LowerRight = new DX.Vector3(reader.Read <DX.Vector2>(), 0);

            reader.End();

            // Read rendering information.
            reader.Begin(RenderDataChunk);

            // Culling mode is not per-sprite anymore.
            reader.SkipBytes(Unsafe.SizeOf <CullingMode>());
            sprite.AlphaTest = reader.Read <GorgonRangeF>();

            // Blending values are not per-sprite anymore.
            // Depth/stencil values are not per-sprite anymore.
            reader.SkipBytes(91);
            reader.End();

            // Read texture information.
            reader.Begin(TextureDataChunk);
            GorgonColor borderColor = reader.Read <GorgonColor>();

            TextureWrap         hWrap       = ConvertV2TextureWrapToTextureAddress(reader.Read <int>());
            TextureWrap         vWrap       = ConvertV2TextureWrapToTextureAddress(reader.Read <int>());
            SampleFilter        filter      = ConvertV2TextureFilterToFilter(reader.Read <TextureFilter>());
            string              textureName = reader.ReadString();
            GorgonTexture2DView textureView;

            // Bind the texture (if we have one bound to this sprite) if it's already loaded, otherwise defer it.
            if ((!string.IsNullOrEmpty(textureName)) && (overrideTexture == null))
            {
                GorgonTexture2D texture = graphics.LocateResourcesByName <GorgonTexture2D>(textureName).FirstOrDefault();

                // If we used the editor build to sprite, the path to the texture is stored in the name instead of just the name.
                // So let's try and strip out the path information and extension and try again.
                if (texture == null)
                {
                    textureName = Path.GetFileNameWithoutExtension(textureName);
                    texture     = graphics.LocateResourcesByName <GorgonTexture2D>(textureName).FirstOrDefault();
                }

                textureView = texture?.GetShaderResourceView();
            }
            else
            {
                textureView = overrideTexture;
            }

            sprite.TextureRegion = reader.ReadRectangleF();

            if (textureView != null)
            {
                // V2 used black transparent by default, so convert it to our default so we can keep from creating unnecessary states.
                if (borderColor == GorgonColor.BlackTransparent)
                {
                    borderColor = GorgonColor.White;
                }

                sprite.Texture        = textureView;
                sprite.TextureSampler = CreateSamplerState(graphics, filter, borderColor, hWrap, vWrap);
            }

            reader.End();
            reader.End();

            return(sprite);
        }
Пример #5
0
        /// <summary>
        /// Function to read the renderable data from a stream.
        /// </summary>
        /// <param name="stream">Open file stream containing the renderable data.</param>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="stream" /> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="System.IO.IOException">Thrown when the stream parameter is not opened for reading data.</exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the data in the stream does not contain valid renderable data, or contains a newer version of the renderable than Gorgon can handle.</exception>
        void IPersistedRenderable.Load(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (!stream.CanRead)
            {
                throw new IOException(Resources.GOR2D_STREAM_WRITE_ONLY);
            }

            GorgonChunkReader chunk = null;

            // Read the sprite in.
            try
            {
                chunk = new GorgonChunkReader(stream);

                if (!chunk.HasChunk(FileHeader))
                {
                    // The old format doesn't use the chunker.
                    chunk.Dispose();
                    chunk = null;

                    // Check to see if it's an older version of the Gorgon sprite data.
                    using (var oldReader = new GorgonBinaryReader(stream, true))
                    {
                        GorgonV1SpriteReader.LoadSprite(this, oldReader);

                        return;
                    }
                }

                // Read in the file header.
                chunk.Begin(FileHeader);

                chunk.Begin("SPRTDATA");
                Anchor         = chunk.Read <Vector2>();
                Size           = chunk.Read <Vector2>();
                HorizontalFlip = chunk.ReadBoolean();
                VerticalFlip   = chunk.ReadBoolean();

                // Read vertex colors.
                for (int i = 0; i < Vertices.Length; i++)
                {
                    Vertices[i].Color = chunk.Read <GorgonColor>();
                }

                // Write vertex offsets.
                chunk.ReadRange(_offsets);
                chunk.End();

                // Read rendering information.
                chunk.Begin("RNDRDATA");
                CullingMode                               = chunk.Read <CullingMode>();
                AlphaTestValues                           = chunk.Read <GorgonRangeF>();
                Blending.AlphaOperation                   = chunk.Read <BlendOperation>();
                Blending.BlendOperation                   = chunk.Read <BlendOperation>();
                Blending.BlendFactor                      = chunk.Read <GorgonColor>();
                Blending.DestinationAlphaBlend            = chunk.Read <BlendType>();
                Blending.DestinationBlend                 = chunk.Read <BlendType>();
                Blending.SourceAlphaBlend                 = chunk.Read <BlendType>();
                Blending.SourceBlend                      = chunk.Read <BlendType>();
                Blending.WriteMask                        = chunk.Read <ColorWriteMaskFlags>();
                DepthStencil.BackFace.ComparisonOperator  = chunk.Read <ComparisonOperator>();
                DepthStencil.BackFace.DepthFailOperation  = chunk.Read <StencilOperation>();
                DepthStencil.BackFace.FailOperation       = chunk.Read <StencilOperation>();
                DepthStencil.BackFace.PassOperation       = chunk.Read <StencilOperation>();
                DepthStencil.FrontFace.ComparisonOperator = chunk.Read <ComparisonOperator>();
                DepthStencil.FrontFace.DepthFailOperation = chunk.Read <StencilOperation>();
                DepthStencil.FrontFace.FailOperation      = chunk.Read <StencilOperation>();
                DepthStencil.FrontFace.PassOperation      = chunk.Read <StencilOperation>();
                DepthStencil.DepthBias                    = chunk.ReadInt32();
                DepthStencil.DepthComparison              = chunk.Read <ComparisonOperator>();
                DepthStencil.StencilReference             = chunk.ReadInt32();
                DepthStencil.IsDepthWriteEnabled          = chunk.ReadBoolean();
                DepthStencil.StencilReadMask              = chunk.ReadByte();
                DepthStencil.StencilReadMask              = chunk.ReadByte();
                chunk.End();

                // Read collider information.
                if (chunk.HasChunk("COLLIDER"))
                {
                    chunk.Begin("COLLIDER");
                    Type colliderType = Type.GetType(chunk.ReadString());
                    Debug.Assert(colliderType != null, "Collider is NULL!!");
                    var collider = (Gorgon2DCollider)Activator.CreateInstance(colliderType);
                    collider.ReadFromChunk(chunk);
                    chunk.End();
                }

                // Read texture information.
                chunk.Begin("TXTRDATA");
                TextureSampler.BorderColor        = chunk.Read <GorgonColor>();
                TextureSampler.HorizontalWrapping = chunk.Read <TextureAddressing>();
                TextureSampler.VerticalWrapping   = chunk.Read <TextureAddressing>();
                TextureSampler.TextureFilter      = chunk.Read <TextureFilter>();
                DeferredTextureName = chunk.ReadString();
                TextureRegion       = chunk.ReadRectangleF();
            }
            finally
            {
                if (chunk != null)
                {
                    chunk.Dispose();
                }
            }
        }