2

我一直在尝试以每秒 60 次的速度更新 PictureBox 的 BMP,其线条模式会随着每次更新而改变。发生的情况是图像在屏幕刷新之间进行了部分更新。所以,你看到的是一种模式的一部分,也是下一种模式的一部分。每次屏幕刷新时,我都需要精确更新一次。理想情况下,我的目标是更新后缓冲区,然后将其复制到前缓冲区。我听说您可以在游戏中使用 vsync 来锁定前端缓冲区,以便屏幕仅在屏幕刷新后立即更新。如果我可以利用这种锁定,它可以让我在每次刷新时精确更新一次。但我还没有弄清楚该怎么做。

有任何想法吗?

我确实尝试在 Windows 窗体中使用 DoubleBuffering = true 属性。但它可能不适用于 PictureBox。我使用 CopyMemory(本机 dll 调用)将新模式复制到 PictureBox 中的位图中。

在上一段中,我还尝试使用具有相同技术的 WriteableBitmap,但由于某种原因,后缓冲区从未复制到前缓冲区,即使我按照其他人在堆栈交换中建议的方式进行了操作。我试了几个小时左右。使用该技术,图像从未在屏幕上更新。

4

1 回答 1

0

我找到了自己问题的解决方案。最好的方法是创建一个 XNA 2D 应用程序。我在我的显卡设置中强制使用 vsync。然后我在 XNA 应用程序中打开了这个属性。在游戏构造函数中,我使用了这个: this.IsFixedTimeStep = true;

public Game1()
{
    this.IsFixedTimeStep = true;
    this.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 1000 / 60);//60 times per second
    graphics = new GraphicsDeviceManager(this)
    {
        PreferredBackBufferWidth = 800,
        PreferredBackBufferHeight = 600,
        SynchronizeWithVerticalRetrace = true,
    };

    graphics.ApplyChanges();
    Content.RootDirectory = "Content";
}

然后声明一个全局变量: bool _IsDirty = true; 并声明以下函数:

protected override bool BeginDraw()
{
    if (_IsDirty)
    {
        _IsDirty = false;
        base.BeginDraw();
        return true;
    }
    else
        return false;
}
protected override void EndDraw()
{
    if (!_IsDirty)
    {
        base.EndDraw();
        _IsDirty = true;
    }
}

protected override void Draw(GameTime gameTime)
{
    //graphics.GraphicsDevice.Clear(Color.Black);

    // Draw the sprite.
    spriteBatch.Begin();
    spriteBatch.Draw(textureImg, new Rectangle(0, 0, 800, 600), Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
}
于 2013-04-02T17:34:05.573 回答