XNA生涩渲染

时间:2012-09-01 02:52:23

标签: xna

我不知道我哪里弄错了。我在youtube上看过一些演示,实时渲染大约1百万个粒子(太棒了)。但是当我只想渲染2500个小平方(Texture2D)时,系统会跪在地上 - 一切都变得缓慢而且生涩。在这里,我按原样呈现循环 - 简单的平铺到平铺渲染。网格为50 x 50,Texture2D Tile仅为5x5大png图像和GridNode 3x3。我是XNA的新手,所以请不要打扰我太多......: - )

任何人都可以告诉我,我做错了什么?

Thanx很多

for (x = FromCol; x <= ToCol; x++)
            {
                for (y = FromRow; y <= ToRow; y++)
                {
                    Color aColor = new Color((byte)(x * 20), (byte)(y * 15), (byte)(60 + x));

                    CoordX = DisplayArea.Left + (int)Math.Round((x - FromCol) * zoomWidth - (restCol * ZoomingX) - indent_x);//
                    CoordY = DisplayArea.Top + (int)Math.Round((y - FromRow) * zoomHeight - (restRow * ZoomingY) - indent_y);//

                    dodraw = ((CoordX) > DisplayArea.Left) & (CoordX < (DisplayArea.Right - indent_x)) & ((CoordY) > DisplayArea.Top) & (CoordY < (DisplayArea.Bottom-indent_y));


                    l = CoordX + indent_x;
                    t = CoordY + indent_y; 
                    r = l + (int)Math.Round(ColWidth * ZoomingX);
                    b = t + (int)Math.Round(RowHeight * ZoomingY);

                    if (l < DisplayArea.Left) l = DisplayArea.Left;
                    if (t < DisplayArea.Top)  t = DisplayArea.Top;
                    if (r > (DisplayArea.Left + DisplayArea.Width)) r = DisplayArea.Left + DisplayArea.Width;
                    if (b > DisplayArea.Top + DisplayArea.Height) b = DisplayArea.Top + DisplayArea.Height;

                    SpriteBatch.Draw(Tile, new Rectangle(l, t, r - l, b - t), aColor);

                    if (dodraw) SpriteBatch.Draw(GridNode, new Vector2(CoordX, CoordY), Color.White);
                }

2 个答案:

答案 0 :(得分:4)

赛斯的回答几乎是正确的。当您向GPU发送批处理时 - 当您绘制某些东西时 - 它会占用相对大量的CPU时间。有效地,你只能在每帧发送几百个批次 - 你的“批量限制”。

SpriteBatch通过将尽可能多的精灵打包到一个批次中来解决这个问题。它实际上只是在End() [1] 中绘制内容。但是,如果它们共享纹理,它只能将精灵一起批处理。

你在这里遇到了最糟糕的情况:看起来你正在交织纹理,迫使SpriteBatch为每个精灵开始一个新的批处理。

所以要做的第一件事就是检查这是实际问题的原因。快速执行此操作的方法是设置SpriteSortMode.Texture(在SpriteBatch.Begin中)并查看效果是否有所改善。这将完全听起来像 - 按绘制顺序按纹理对精灵进行分组,减少纹理变化的次数,从而减少批次。

然后,您可以开始解决问题。如果您可以继续使用SpriteSortMode.Texture,那就没关系了。您还可以将循环转换为两个单独的循环。或者你可以在一个循环中填充两个单独的SpriteBatch个对象 - 因为SpriteBatch基本上充当缓冲区 [1]

或者,如果您确实需要交错这些纹理,请使用精灵表

最后,我写了this rather popular answer on the GameDev site,更详细地介绍了这个主题。


[1]除了使用SpriteSortMode.Immediate

答案 1 :(得分:1)

您正在对Draw方法进行2500次调用。每当你告诉CPU向GPU发出指令时,都会产生巨大的处理开销。这就是为什么你的表现比在一次抽奖中抽取一百万个粒子的游戏更差

一次绘制1000个三角形比绘制1个三角形1000倍快得多。