XNA 3.1到4.0需要不断重绘或显示紫色屏幕

Mik*_*ing 6 xna xna-4.0

对于我游戏中的菜单,我将它们绘制到屏幕一次,然后只有在被认为是脏的时才重绘.每当用户执行应该导致重绘的操作时,都会通过布尔值设置为true来处理,然后绘制循环将在绘制菜单之前检查该值.这种逻辑在3.1中完美运行,但在4.0中菜单会闪烁(绘制1帧)然后显示紫色屏幕,直到再次绘制.

我在4.0中创建了一个非常简单的测试游戏来演示如下所示的问题.您会注意到屏幕看起来只是紫色.如果将行设置_isDirty删除为false,您将看到矢车菊蓝色背景.

public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    bool _isDirty = true;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
    }
    protected override void Draw(GameTime gameTime)
    {
        if (_isDirty)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            _isDirty = false;
        }
        base.Draw(gameTime);
    }
}
Run Code Online (Sandbox Code Playgroud)

我如何从XNA 3.1获取行为?我见过几个人提到PreserveContents,但这似乎没有任何影响4.0,除非我错误地应用它.

And*_*ell 13

以下是XNA游戏中调用内容的概述:

Update
BeginDraw
Draw
EndDraw
Run Code Online (Sandbox Code Playgroud)

EndDraw最终调用的默认实现GraphicsDevice.Present.打开双缓冲后,可以交换前后缓冲区.

所以发生的事情是:

  • 第一次:你将你的场景绘制到后台缓冲区,然后让XNA将它交换到前面.

  • 第二次:你没有画任何东西,让表面充满了DirectX初始化这些表面的紫色,然后将交换到前面!

  • 随后的时间:你什么都没画,所以你会看到这两个表面之间的显示闪烁.

有几种方法可以抑制XNA中的绘图.我在这个问题的答案中回过头来看看.在该答案中,我建议您覆盖BeginDraw,如下所示:

protected override bool BeginDraw()
{
    if(_isDirty)
        return base.BeginDraw();
    else
        return false;
}
Run Code Online (Sandbox Code Playgroud)

BeginDraw返回false,DrawEndDraw(等Present)不会被调用该帧.什么都不会画,前/后缓冲区不会交换.