Xna 快速渲染

Xna 快速渲染,xna,Xna,我不知道我在哪里犯了错误。我在youtube上看过一些演示,实时渲染了大约100万个粒子(令人惊讶)。但是当我只想渲染2500个小面积(Texture2D)时,系统就会崩溃——一切都变得缓慢而急促。在这里,我按原样呈现循环-简单的瓦到瓦渲染。网格为50 x 50,纹理2D瓷砖仅为5x5大png图像和网格节点3x3。我在新华社很新,所以请不要打我太多…:-) 谁能告诉我,我做错了什么 很多 for (x = FromCol; x <= ToCol; x++) {

我不知道我在哪里犯了错误。我在youtube上看过一些演示,实时渲染了大约100万个粒子(令人惊讶)。但是当我只想渲染2500个小面积(Texture2D)时,系统就会崩溃——一切都变得缓慢而急促。在这里,我按原样呈现循环-简单的瓦到瓦渲染。网格为50 x 50,纹理2D瓷砖仅为5x5大png图像和网格节点3x3。我在新华社很新,所以请不要打我太多…:-)

谁能告诉我,我做错了什么

很多

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);
                }
用于(x=FromCol;x DisplayArea.Top)和(CoordY<(DisplayArea.Bottom-indent_y));
l=坐标x+缩进x;
t=坐标+缩进y;
r=l+(int)数学圆(ColWidth*ZoomingX);
b=t+(int)数学圆(行高*缩放);
如果(l(DisplayArea.Left+DisplayArea.Width))r=DisplayArea.Left+DisplayArea.Width;
如果(b>DisplayArea.Top+DisplayArea.Height)b=DisplayArea.Top+DisplayArea.Height;
绘制(瓷砖,新矩形(l,t,r-l,b-t),颜色);
if(dodraw)SpriteBatch.Draw(GridNode,newvector2(CoordX,CoordY),Color.White);
}

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


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

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


一次画1000个三角形要比1000次画一个三角形快得多。

赛斯的答案几乎是正确的。当你向GPU发送一个批处理时——当你绘制一些东西时——它会占用相当大的CPU时间。实际上,您被限制为每帧发送几百个批次-您的“批次限制”

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

这里几乎是最坏的情况:看起来你在交错纹理,迫使
SpriteBatch
为每个sprite启动一个新批。

因此,首先要做的是检查这是否是问题的真正原因。一种快速的方法是设置
SpriteSortMode.Texture
(在
SpriteBatch.Begin
)并查看性能是否有所提高。这将完全实现它听起来的效果-按绘制顺序按纹理对精灵进行分组,减少纹理更改的数量,从而减少批次

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

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

最后,我写了一篇更详细的文章



[1] 除了在使用SpriteSortMode时。立即

赛斯的回答几乎是正确的。当你向GPU发送一个批处理时——当你绘制一些东西时——它会占用相当大的CPU时间。实际上,您被限制为每帧发送几百个批次-您的“批次限制”

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

这里几乎是最坏的情况:看起来你在交错纹理,迫使
SpriteBatch
为每个sprite启动一个新批。

因此,首先要做的是检查这是否是问题的真正原因。一种快速的方法是设置
SpriteSortMode.Texture
(在
SpriteBatch.Begin
)并查看性能是否有所提高。这将完全实现它听起来的效果-按绘制顺序按纹理对精灵进行分组,减少纹理更改的数量,从而减少批次

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

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

最后,我写了一篇更详细的文章



[1] 除了在使用SpriteSortMode.Immediate时,但什么是渲染平铺的有效方法?是的,我叫SpriteBatch.Draw 2x2500在我的例子中,我认为它是渲染纹理2D对象的标准且快速的方法。我应该将其渲染为临时位图,然后使用spritebatch.draw渲染此位图吗?请给我一个提示。。。thanx.@Seth不太正确,因为
SpriteBatch.Draw
实际上并不画任何东西(通常)。请看我的答案。但什么是渲染瓷砖的有效方法?是的,我叫SpriteBatch.Draw 2x2500在我的例子中,我认为它是渲染纹理2D对象的标准且快速的方法。s