简体   繁体   English

Monogame RenderTarget2D填充图形卡内存

[英]Monogame RenderTarget2D filling up graphic card memory

I got a problem trying to create a Post processor class in Monogame. 尝试在Monogame中创建后处理器类时遇到问题。

The memory of my graphic card fills up in seconds and i don't get it why. 我的图形卡的内存在几秒钟内就满了,我不明白为什么。

I already postet the complete problem in the Monogame Community forum. 我已经在Monogame社区论坛上发布了完整的问题。 But maybe someone else could help me solving the problem. 但是也许其他人可以帮助我解决问题。

Reference to the Monogame Community post: http://community.monogame.net/t/problem-with-rendertarget2d-fills-up-the-graphic-card-memory/2730/3 参考Monogame社区帖子: http : //community.monogame.net/t/problem-with-rendertarget2d-fills-up-the-graphic-card-memory/2730/3

I described the problem already at the Monogame Community forum. 我已经在Monogame社区论坛上描述了这个问题。

I've solved my problem now my postprocessor looks like this: 我现在已经解决了我的问题,我的后处理器看起来像这样:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Brick
{
    class Postprocessor
    {
        private Effect CurrentEffect;
        private Effect DefaultEffect;
        private bool Multipass;

        private RenderTarget2D FinalImage;
        private RenderTarget2D EmptyTarget;

        public int Passescount
        {
            get 
            {
                return CurrentEffect.CurrentTechnique.Passes.Count;
            }
        }

        public Postprocessor(Effect EffectToUse, Effect StandardEffect)
        {
            if (!ChangeCurrentEffect(EffectToUse))
                return;
            DefaultEffect = StandardEffect;
            EmptyTarget = new RenderTarget2D(DefaultEffect.GraphicsDevice, GameSettings.WindowWidth, GameSettings.WindowHeight);
        }
        public bool ChangeCurrentEffect(Effect EffectToUse)
        {
            CurrentEffect = EffectToUse;
            if (CurrentEffect.CurrentTechnique.Passes.Count > 1)
                Multipass = true;
            else
                Multipass = false;
            return true;
        }

        private bool CheckIfParameterExist(string Name)
        {
            foreach (EffectParameter parameter in CurrentEffect.Parameters)
            {
                if (parameter.Name == Name)
                    return true;
            }
            return false;
        }

        public void Update(GameTime gametime, Vector2 MousePosition)
        {
            SetParameters((float)gametime.TotalGameTime.TotalSeconds, MousePosition);
        }

        private void SetParameters(float gametime, Vector2 MousePosition)
        {
            if (CheckIfParameterExist("GameTime"))
                CurrentEffect.Parameters["GameTime"].SetValue(gametime);
            if (CheckIfParameterExist("MousePosition"))
                CurrentEffect.Parameters["MousePosition"].SetValue(MousePosition);
        }

        public void Draw(GraphicsDevice graphics, RenderTarget2D Target, SpriteBatch SB)
        {
            if (Multipass)
            {
                FinalImage = MultiCallPostprocess(graphics, SB, Target);
            }
            else
            {
                FinalImage = SinglePostprocessCall(graphics, SB, Target, 0);
            }
            graphics.Clear(Color.Transparent);
            DefaultEffect.CurrentTechnique.Passes[0].Apply();
            SB.Draw(FinalImage, new Rectangle(0, 0, FinalImage.Width, FinalImage.Height), Color.White);
        }

        private RenderTarget2D MultiCallPostprocess(GraphicsDevice graphics, SpriteBatch SB, RenderTarget2D DrawTarget)
        {
            for (int i = 0; i < CurrentEffect.CurrentTechnique.Passes.Count; i++)
            {
                DrawTarget = SinglePostprocessCall(graphics, SB, DrawTarget, i);
            }
            return DrawTarget;
        }

        private RenderTarget2D SinglePostprocessCall(GraphicsDevice graphics, SpriteBatch SB, RenderTarget2D DrawTarget, int PassPosition)
        {
            EmptyTarget.Dispose();
            EmptyTarget = new RenderTarget2D(graphics, DrawTarget.Width, DrawTarget.Height);
            if (CurrentEffect.CurrentTechnique.Passes.Count >= PassPosition)
            {
                graphics.SetRenderTarget(EmptyTarget);
                graphics.Clear(Color.Transparent);
                CurrentEffect.CurrentTechnique.Passes[PassPosition].Apply();
                SB.Draw(DrawTarget, new Rectangle(0, 0, DrawTarget.Width, DrawTarget.Height), Color.White);
                graphics.SetRenderTarget(null);
            }
            else
            {
                EmptyTarget = DrawTarget;
            }
            return CloneRenderTarget(EmptyTarget);
        }
        private RenderTarget2D CloneRenderTarget(RenderTarget2D target)
        {
            var clone = new RenderTarget2D(target.GraphicsDevice, target.Width,
                target.Height, target.LevelCount > 1, target.Format,
                target.DepthStencilFormat, target.MultiSampleCount,
                target.RenderTargetUsage);

            for (int i = 0; i < target.LevelCount; i++)
            {
                double rawMipWidth = target.Width / Math.Pow(2, i);
                double rawMipHeight = target.Height / Math.Pow(2, i);

                // make sure that mipmap dimensions are always > 0.
                int mipWidth = (rawMipWidth < 1) ? 1 : (int)rawMipWidth;
                int mipHeight = (rawMipHeight < 1) ? 1 : (int)rawMipHeight;

                var mipData = new Color[mipWidth * mipHeight];
                target.GetData(i, null, mipData, 0, mipData.Length);
                clone.SetData(i, null, mipData, 0, mipData.Length);
            }

            return clone;
        }

    }
}

The important funtion is "CloneRenderTarget" seems like creating a new RenderTarget2D from an old one without this function it just creates a pointer so if you dispose the copy the original get disposed as well. 重要的功能是“ CloneRenderTarget”似乎是从旧版本创建一个新的RenderTarget2D而没有此功能,它只会创建一个指针,因此,如果您处置副本,则原始副本也会被处置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM