【问题标题】:How can I optimize this bottleneck Draw call?如何优化这个瓶颈 Draw call?
【发布时间】:2014-05-13 17:57:58
【问题描述】:

我分析了我的应用程序(一个游戏),我注意到这个功能是一个(!)瓶颈。特别是,这个函数被大量调用是因为它的含义:它绘制了我的游戏摩天大楼的窗户。游戏是水平流动的,所以每次生成新的摩天大楼并且必须绘制窗口。

方法很简单:我只加载一个窗口的一个图像,然后像“模板”一样使用它来绘制每个窗口,同时计算它在摩天大楼上的位置。

  • position_ 是起始位置,基于我要开始绘制的左上角
  • n_horizontal_windows_n_vertical_windows_ 是不言自明的,它是在构造函数中生成的
  • skipped_lights_bool 的矩阵,表示该特定灯是打开还是关闭(关闭意味着不绘制窗口)
  • delta_x 就像填充,一个窗口与另一个窗口之间的距离。
  • w_window是窗口的宽度(每个窗口都一样)

    public override void Draw(SpriteBatch spriteBatch)
    {
        Vector2 tmp_pos = position_;
        float default_pos_y = tmp_pos.Y;
    
        for (int r = 0; r < n_horizontal_windows_; ++r)
        {
            for (int c = 0; c < n_vertical_windows; ++c)
            {
                if (skipped_lights_[r, c])
                {
                    spriteBatch.Draw(
                        window_texture_,
                        tmp_pos,
                        overlay_color_);
                }
    
                tmp_pos.Y += delta_y_;
            }
            tmp_pos.X += delta_x_ + w_window_;
            tmp_pos.Y = default_pos_y;
        }
    
    }
    

如您所见,位置是在循环内计算的。

只是一个结果示例(如您所见,我创建了三层摩天大楼):

如何优化这个功能?

【问题讨论】:

标签: c# optimization xna draw xna-4.0


【解决方案1】:

您始终可以将每个建筑物渲染到一个纹理并在它显示在屏幕上时对其进行缓存。这样,您只需为每个建筑物绘制一次窗户。缓存后,您将在一次调用中绘制整个建筑物,从而避免您在每一帧中逐个构建它。它应该防止你得到每一帧的大量过度绘制。不过,它会消耗一些内存。

【讨论】:

  • 问题是每栋建筑都是随机生成的(在宽度和高度上)每次我需要画一个!
  • 我假设建筑物一旦出现在屏幕上就不会改变。您将有一个代表每个建筑物的“建筑”类。当一个新建筑物需要在屏幕上滚动时,您可以使用参数创建它,然后将其渲染为您在 Building 类中缓存的纹理。您可以使用现有的绘图代码来绘制此纹理。现在,当您要绘制城市景观时,您只需遍历所有建筑物并绘制它们的缓存纹理,而不是逐个渲染它。当建筑物滚出屏幕时,您需要销毁该建筑物实例并释放它的缓存。
  • 这是一个关于在 XNA 中渲染到纹理的好教程。riemers.net/eng/Tutorials/XNA/Csharp/Series3/…
  • 太棒了!我获得了 7% 的速度!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
  • 2019-08-03
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多