对于我游戏中的菜单,我将它们绘制到屏幕一次,然后只有在被认为是脏的时才重绘.每当用户执行应该导致重绘的操作时,都会通过布尔值设置为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,Draw和EndDraw(等Present)不会被调用该帧.什么都不会画,前/后缓冲区不会交换.