在XNA WP7中平滑淡出/转换2个纹理

时间:2011-04-05 12:43:40

标签: c# windows-phone-7 xna

我有2个纹理800x480(前景/背景),它们是XNA Windows Phone 7应用程序中的.png文件。 我想淡出/转换前景以显示背景。我的表现存在很大问题。我的想法只是在一个Alpha中设置Texture2D频道,因此我创建了这样的代码:

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

private Texture2D _background, _foreground;
private BlendState _blendState;
private uint[] _pixelsForeground;
private uint[] _pixelsBackground;

public Game1()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";

    TargetElapsedTime = TimeSpan.FromTicks(333333);

    graphics.IsFullScreen = true;
    graphics.SupportedOrientations = DisplayOrientation.Portrait;
    graphics.PreferredBackBufferHeight = 840;
    graphics.PreferredBackBufferWidth = 480;
}

protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);

    _background = this.Content.Load<Texture2D>(@"background");
    _foreground = this.Content.Load<Texture2D>(@"foreground");

    _pixelsForeground = new uint[_foreground.Width * _foreground.Height];
    _pixelsBackground = new uint[_foreground.Width * _foreground.Height];

    _background.GetData(_pixelsBackground);
    _foreground.GetData(_pixelsForeground);

    _blendState = new BlendState
    {
        AlphaBlendFunction = BlendFunction.Add,
        ColorBlendFunction = BlendFunction.Add,
        AlphaSourceBlend = Blend.SourceAlpha,
        ColorSourceBlend = Blend.SourceAlpha,
        AlphaDestinationBlend = Blend.InverseSourceAlpha,
        ColorDestinationBlend = Blend.InverseSourceAlpha
    };
}

protected override void Update(GameTime gameTime)
{
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();

    this.GraphicsDevice.Textures[0] = null;

    for (int x = 0; x < _foreground.Width; x++)
    {
        for (int y = 0; y < _foreground.Height; y++)
        {
            uint pixelCanvas = _pixelsForeground[y * _foreground.Width + x];
            uint newPixelCanvas = pixelCanvas - 0x05000000;
            _pixelsForeground[y*_foreground.Width + x] = newPixelCanvas;
            _pixelsForeground[y * _foreground.Width + x] = (newPixelCanvas & 0xFF000000) > (pixelCanvas & 0xFF000000)
                                                                                ? pixelCanvas & 0x00FFFFFF
                                                                                : newPixelCanvas;
        }
    }

    Rectangle rect = new Rectangle(0, 0, _foreground.Width, _foreground.Height);
    _foreground.SetData<uint>(0, rect, _pixelsForeground, 0, _foreground.Height * _foreground.Width);

    base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    spriteBatch.Begin(SpriteSortMode.FrontToBack, _blendState);
    spriteBatch.Draw(_foreground, Vector2.One, null, Color.White);
    spriteBatch.Draw(_background, Vector2.One, null, Color.White);
    spriteBatch.End();

    base.Draw(gameTime);
}

问题是由于以下原因导致性能下降:

_foreground.SetData<uint>(...)

我可以用什么技术来更好地管理它? 我宁愿将Alpha通道的操作用于其他目的。 请记住,前景像素在启动像透明点时可能已经有不同的alpha通道。

1 个答案:

答案 0 :(得分:5)

这绝对是解决这个问题的错误方法。你想要做的是将Color传递给具有相应alpha通道的sprite批处理Draw方法。

int alpha = 150;
spriteBatch.Draw(tex, pos, new Color(255,255,255,alpha));

这样,GPU代表您处理alpha混合,并且您的性能问题消失: - )