2013-04-21 98 views
0

因此,我正在为XNA开发一个GUI库,并且遇到了一个我找不到解决方案的问题。我正在使用rendertargets很多,这本身很烦人,但我有一个非常奇怪和具体的问题。当游戏最小化时RenderTarget内容发生变化

在我的ProgressBar类中,当元素是Validated且对象大小已更改时,我绘制了各个组件。如果对象是有效的,但对象大小没有改变,我使用填充的rendertargets作为纹理将最终产品绘制到缓冲区纹理(也是rendertarget)上。现在,无论何时我最小化应用程序并再次选项卡,进度条的背景层都会在其上方具有条纹纹理的印记。 rendertargets被设置为保留内容,我确信设置了正确的rendertargets。也清除graphicsDevice(在“实际绘图”行下面)不会执行任何操作。为什么?

所以基本上游戏会创建该区域的截图,并将其绘制到我的纹理中。我勒个去?

下面是进度代码:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
namespace PixLib 
{ 
    public class ProgressBar : UIElement 
    { 
     private float stripeThickness = 5; 
     private float stripeGapFactor = 3f; 
     private float animationSpeed = 1f; 
     private float at = 0; 
     private RenderTarget2D stripesBg, stripes; 
     private Coordinate2 lastSize; 
     protected override Coordinate2 InnerArea 
     { 
      get { return Coordinate2.Zero; } 
     } 
     protected Color color; 
     public Color Color 
     { 
      get 
      { 
       return color; 
      } 
      set 
      { 
       color = value; 
       Invalidate(); 
      } 
     } 
     protected float value; 
     public float Value 
     { 
      get 
      { 
       return value; 
      } 
      set 
      { 
       float t = Math.Min(1, Math.Max(0, value)); 
       if (t != this.value) 
       { 
        this.value = t; 
        Invalidate(); 
       } 

      } 
     } 
     public ProgressBar(string name,Color color, Rectangle elementRect, bool localPos = true) 
      : base(name, elementRect, localPos) 
     { 
      lastSize = new Coordinate2(); 
      this.color = color; 
      value = 0; 
      at = 0; 
     } 
     protected override void OnUpdate(MouseState mouseState, KeyboardState keyboardState) 
     { 

     } 
     protected override void OnInit() 
     { 

     } 
     protected override void Redraw(SpriteBatch spriteBatch) 
     { 

      if (lastSize.X != Width || lastSize.Y != Height) 
      { 

       Console.WriteLine("Redrawing Progressbar"); 
       //redraw textures! 
       stripesBg = new RenderTarget2D(graphicsManager.GraphicsDevice, Width, Height, false, graphicsManager.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24, 1, RenderTargetUsage.PreserveContents); 
       stripes = new RenderTarget2D(graphicsManager.GraphicsDevice, Width, Height * 2, false, graphicsManager.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24, 1, RenderTargetUsage.PreserveContents); 

       spriteBatch.Begin(); 
       spriteBatch.Draw(pixel, new Rectangle(0, 0, Width, Height), Color.White); 
       spriteBatch.End(); 

       SetRenderTarget(stripesBg); 
       spriteBatch.Begin(); 
       spriteBatch.Draw(pixel, new Rectangle(0, 0, Width, Height), Color.White); 
       spriteBatch.End(); 

       /*SetRenderTarget(border); 
       spriteBatch.Begin(); 
       int si = (int)(stripeThickness*0.5f + 0.5f); 
       DrawLine(new Coordinate2(si, 0), new Coordinate2(Width, 0), spriteBatch, Color.White, si); 
       DrawLine(new Coordinate2(si, Height - si), new Coordinate2(Width, Height - si), spriteBatch, Color.White, si); 
       DrawLine(new Coordinate2(si, 0), new Coordinate2(si, Height), spriteBatch, Color.White, si); 
       DrawLine(new Coordinate2(Width, 0), new Coordinate2(Width, Height - si), spriteBatch, Color.White, si); 
       spriteBatch.End();*/ 

       SetRenderTarget(stripes); 
       spriteBatch.Begin(); 
       int fy = (int)(stripeThickness +0.5f); 
       int s = (Height + fy) * 2; 
       int fx = -s; 
       at = 0; 
       while (fx < Width + stripeThickness * stripeGapFactor) 
       { 

        DrawLine(new Coordinate2(fx, -fy), new Coordinate2(fx+s, s-fy), spriteBatch, Color.White, stripeThickness); 
        fx += (int)(stripeThickness * stripeGapFactor); 
       } 
       spriteBatch.End(); 


       SetRenderTarget(null); 


       lastSize.X = Width; 
       lastSize.Y = Height; 
      } 

      //actual drawing 
      spriteBatch.Begin(); 
      spriteBatch.Draw(pixel, SizeRect, Darken(color, 2)); 
      int cv = (int)(Value * Width + 0.5f); 
      spriteBatch.Draw(stripesBg, new Rectangle(cv - Width, 0, Width, Height), Darken(Color)); 
      graphicsManager.GraphicsDevice.Clear(Color.Transparent); 
      spriteBatch.Draw(stripes, new Rectangle(cv - Width, -(int)(at + 0.5f), Width, Height * 2), color); 
      spriteBatch.End(); 

      at += animationSpeed; 
      if (at >= Height) 
       at -= Height - (int)(stripeThickness + .5f); 
     } 
    } 
} 

回答

0

好吧,看来,要解决这个问题是使rendertargets跟不上他们的内容,并重新划分了整个该死的东西只要内容是丢失。

if (lastSize.X != Width || lastSize.Y != Height || stripesBg.IsContentLost || stripes.IsContentLost) 
      { 

       Console.WriteLine("Redrawing Progressbar"); 
       //redraw textures! 
       //stripesBg = new RenderTarget2D(graphicsManager.GraphicsDevice, Width, Height, false, graphicsManager.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24, 1, RenderTargetUsage.PreserveContents); 
       //stripes = new RenderTarget2D(graphicsManager.GraphicsDevice, Width, Height * 2, false, graphicsManager.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24, 1, RenderTargetUsage.PreserveContents); 
       stripesBg = new RenderTarget2D(graphicsManager.GraphicsDevice, Width, Height); 
       stripes = new RenderTarget2D(graphicsManager.GraphicsDevice, Width, Height * 2); 
[...] 
相关问题