0

这是一个 XNA 问题...

我的游戏中有大量的 DrawableGameComponents 对象,它们都共享相同的 SpriteBatch。但是,我每次都必须调用 SpriteBatch.Begin() 和 .End() 来绘制每个组件。我想在一个批次中绘制所有内容以获得更好的性能,但我不知道 .Begin() 和 .End() 可以去哪里,因为 .Draw() 被自动调用(因为它们是 DrawableGameComponents)

有谁知道我可以做些什么来使它们都在单个 .Begin() 和 .End() 调用之间绘制,同时将它们保持为 DrawableGameComponents?

编辑:

好吧,从这个网站http://www.progware.org/Blog/post/XNA-Game-Development-(Decentralize).aspx我想它是在主游戏循环的 base.Draw() 调用中调用的......所以我可以用 Begin 和 End 方法包装它

protected override void Draw(GameTime gameTime) {
    if (Cell.Cell.CellSpriteBatch != null) {
        Cell.Cell.CellSpriteBatch.Begin(
            SpriteSortMode.BackToFront, BlendState.AlphaBlend, 
            SamplerState.AnisotropicClamp, null, null, null,
            gamePlay.Camera.GetTransformation()
        );
    }

    base.Draw(gameTime);

    if (Cell.Cell.CellSpriteBatch != null) {
        Cell.Cell.CellSpriteBatch.End();
    }
}

现在可以了,但是这样做似乎意味着我想在不同的 SpriteBatch 中绘制的所有其他内容将始终绘制在此下方(因为它们是首先绘制的),因为此 SpriteBatch 的 .End() 始终是最后调用。

有什么解决办法吗?

4

1 回答 1

0

首先,除非您已经知道您是批量受限的,否则可能不值得这样做。如果每个 .Draw 调用都是从同一个纹理中提取的,那么您可能会看到一些加速。如果它们是不同的纹理,那么切换到单个 Begin/End 将没有区别。无论如何,SpriteBatch 都会中断您的绘图调用。

正如您发现的那样,这样做也会使您的代码非常混乱 - 您必须在组件之间进行跟踪。

当前问题的唯一解决方案是使 SpriteBatch 立即进行,以便它在您调用绘制调用时绘制,而不是在结束调用时绘制。但是,这会杀死您的性能,因为根本没有进行批处理。

就个人而言,我会坚持每个组件的开始/结束,直到你遇到性能问题。假设您没有 5000 个组件,在这种情况下,您可能需要稍微不同地构建事物。

于 2010-12-28T02:26:47.927 回答