我有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通道。
答案 0 :(得分:5)
这绝对是解决这个问题的错误方法。你想要做的是将Color
传递给具有相应alpha通道的sprite批处理Draw方法。
int alpha = 150;
spriteBatch.Draw(tex, pos, new Color(255,255,255,alpha));
这样,GPU代表您处理alpha混合,并且您的性能问题消失: - )