예제 #1
0
        public APNGHelper(Game game, string pngFile)
        {
            this.game = game;

            var image = new APNG(pngFile);

            numPlays  = (int)image.acTLChunk.NumPlays;
            baseFrame = new APNGFrame(game, image.DefaultImage);

            if (image.IsSimplePNG)
            {
                CurrentFrame = baseFrame.FrameTexture;
            }
            else
            {
                numPlays = (int)image.acTLChunk.NumPlays;

                foreach (Frame frame in image.Frames)
                {
                    frameList.Add(new APNGFrame(this.game, frame));
                }

                sb = new SpriteBatch(this.game.GraphicsDevice);

                RenderEachFrame();

                CurrentFrame = renderedTextureList[0];
            }
        }
예제 #2
0
        public APNGHelper(Game game, string pngFile)
        {
            this.game = game;

            var image = new APNG(pngFile);
            numPlays = (int)image.acTLChunk.NumPlays;
            baseFrame = new APNGFrame(game, image.DefaultImage);

            if (image.IsSimplePNG)
            {
                CurrentFrame = baseFrame.FrameTexture;
            }
            else
            {
                numPlays = (int)image.acTLChunk.NumPlays;

                foreach (Frame frame in image.Frames)
                {
                    frameList.Add(new APNGFrame(this.game, frame));
                }

                sb = new SpriteBatch(this.game.GraphicsDevice);

                RenderEachFrame();

                CurrentFrame = renderedTextureList[0];
            }
        }
예제 #3
0
        private void RenderEachFrame()
        {
            for (int crtIndex = 0; crtIndex < frameList.Count; crtIndex++)
            {
                var currentTexture = new RenderTarget2D(
                    game.GraphicsDevice,
                    baseFrame.Width,
                    baseFrame.Height);

                game.GraphicsDevice.SetRenderTarget(currentTexture);
                game.GraphicsDevice.Clear(Color.Transparent);

                // if this is the first frame, just draw.
                if (crtIndex == 0)
                {
                    goto LABEL_DRAW_NEW_FRAME;
                }

                // Restore previous texture
                sb.Begin();
                sb.Draw(renderedTextureList[crtIndex - 1], Vector2.Zero, Color.White);
                sb.End();

                APNGFrame crtFrame = frameList[crtIndex - 1];

                switch (crtFrame.DisposeOp)
                {
                // Do nothing.
                case DisposeOps.APNGDisposeOpNone:
                    break;

                // Set current Rectangle to transparent.
                case DisposeOps.APNGDisposeOpBackground:
LABEL_APNG_DISPOSE_OP_BACKGROUND:
                    var t2 = new Texture2D(game.GraphicsDevice, 1, 1);
                    sb.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
                    sb.Draw(
                        t2,
                        new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height),
                        Color.White);
                    sb.End();
                    break;

                // Rollback to previous frame.
                case DisposeOps.APNGDisposeOpPrevious:
                    // If the first `fcTL` chunk uses a `dispose_op` of APNG_DISPOSE_OP_PREVIOUS
                    // it should be treated as APNG_DISPOSE_OP_BACKGROUND.
                    if (crtIndex - 1 == 0)
                    {
                        goto LABEL_APNG_DISPOSE_OP_BACKGROUND;
                    }

                    APNGFrame prevFrame = frameList[crtIndex - 2];

                    sb.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
                    sb.Draw(
                        prevFrame.FrameTexture,
                        new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height),
                        new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height),
                        Color.White);
                    sb.End();
                    break;
                }

LABEL_DRAW_NEW_FRAME:
                // Now let's look at the new frame.
                if (crtIndex == 0)
                {
                    crtFrame = frameList[0];
                }
                else
                {
                    crtFrame = crtIndex < frameList.Count
                                   ? frameList[crtIndex]
                                   : frameList[0];
                }

                switch (crtFrame.BlendOp)
                {
                // Do not apply alpha
                case BlendOps.APNGBlendOpSource:
                    sb.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
                    sb.Draw(
                        crtFrame.FrameTexture,
                        new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height),
                        Color.White);
                    sb.End();
                    break;

                // Apply alpha
                case BlendOps.APNGBlendOpOver:
                    sb.Begin();
                    sb.Draw(
                        crtFrame.FrameTexture,
                        new Rectangle(crtFrame.X, crtFrame.Y, crtFrame.Width, crtFrame.Height),
                        Color.White);
                    sb.End();
                    break;
                }

                renderedTextureList.Add(currentTexture);
            }

            // Okay it's all over now
            game.GraphicsDevice.SetRenderTarget(null);
        }