[英]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.