2

背景:我正在使用 DirectX 的 SlimDX C# 包装器,并且正在使用 Sprite 类(传统上来自底层 dll 中的 Direct3DX 扩展)绘制许多 2D 精灵。我一次在屏幕上绘制了数百个精灵,性能非常棒——在我的四核上,它在我的整个游戏中使用了大约 3-6% 的处理器,包括 10,000 多个对象的逻辑,ai第二个线程上的例程等。所以很明显,精灵正在使用全硬件加速进行绘制,一切都应该是这样。

问题:当我开始引入对 Line 类的调用时,问题就出现了。一旦我画了 4 条线(用于拖动选择框),处理器使用率就会飙升至 13-19%。这只有四行!

我尝试过的事情:

  1. 关闭和打开线抗锯齿。
  2. 关闭和打开 GLLines。
  3. 围绕我的绘图调用手动调用 line.begin 和 line.end。
  4. 省略对 line.begin 和 line.end 的所有调用。
  5. 确保我对 line.draw 的调用不在 sprite.begin / sprite.end 块内。
  6. 在 sprite.begin / sprite.end 块内调用 line.draw。
  7. 渲染 4 行,或渲染 300。
  8. 关闭所有精灵和文本渲染,只保留 4 行的线渲染(看看这是否是某种模式更改问题)。
  9. 以上的大多数组合。

一般来说,这些都不会对性能产生重大影响。#3 将处理器使用率降低了大约 2%,但即便如此,它仍然比应有的水平高出 8% 或更多。最奇怪的是,上面的#7 对性能的影响绝对为零——4 行和 300 行一样慢。我唯一能想到的是,由于某种原因,这是在软件中运行的,和/或它导致图形卡在某种绘图模式之间不断来回切换。

矩阵法:

如果有人知道上述问题的任何解决方法,那么我很想听听!

但是我假设这可能只是directx内部的一个问题,所以我一直在追求另一条路线——制作我自己的基于精灵的线。本质上,我有一个 1px 的白色图像,我使用漫反射颜色和变换来绘制线条。这在性能方面很有效——画出 300 条这样的“线”使我处于我在四核上寻找的 3-6% 的处理器利用率性能范围内。

我的像素拉伸线技术有两个问题,我希望对变换更了解的人可以帮助我。这是我当前的水平线代码:

    public void DrawLineHorizontal( int X1, int X2, int Y, float HalfHeight, Color Color )
    {
        float width = ( X2 - X1 ) / 2.0f;
        Matrix m = Matrix.Transformation2D( new Vector2( X1 + width, Y ), 0f, new Vector2( width, HalfHeight ),
            Vector2.Zero, 0, Vector2.Zero );
        sprite.Transform = m;

        sprite.Draw( this.tx, Vector3.Zero, new Vector3( X1 + width, Y, 0 ), Color );
    }

这是可行的,因为它在屏幕上大部分正确的位置绘制了大部分正确大小的线条。然而,事情似乎向右移动,这很奇怪。我不太确定我的矩阵方法是否正确:我只想将 1x1 精灵水平缩放一些像素,垂直缩放不同的像素。然后我需要能够定位它们——在中心点很好,我认为这就是我必须做的,但如果我能把它定位在左上角那就更好了。这似乎是一个简单的问题,但我对矩阵的了解很薄弱。

这将使纯水平线和纯垂直线对我有用,这是战斗的大部分内容。我可以忍受这一点,并在我目前使用斜线的位置使用其他类型的图形。但是,如果我有一种方法可以使用这种拉伸像素方法绘制有角度的线条,那就太好了。换句话说,例如,从 1,1 到 7,19 画一条线。使用矩阵旋转等,这似乎是可行的,但除了猜测和检查之外,我什至不知道从哪里开始,这将花费很长时间。

非常感谢任何和所有帮助!

4

2 回答 2

1

听起来像是管道停顿。您正在渲染精灵和渲染线之间切换某种模式,这会强制显卡在开始使用新图元之前清空其管道。

在你添加线条之前,这些精灵是你渲染的,还是屏幕上还有其他元素,已经使用其他模式?

于 2009-03-11T15:16:50.023 回答
0

好的,经过大量实验,我设法使水平线工作。这在没有我以前看到的奇怪偏移的情况下有效;同样的原理也适用于垂直线。这比line类的性能要好得多,所以这就是我将用于水平和垂直线的方法。这是代码:

    public void DrawLineHorizontal( int X1, int X2, int Y, float HalfHeight, Color Color )
    {
        float width = ( X2 - X1 );
        Matrix m = Matrix.Transformation2D( new Vector2( X1, Y - HalfHeight ), 0f, new Vector2( width, HalfHeight * 2 ),
            Vector2.Zero, 0, Vector2.Zero );
        sprite.Transform = m;

        sprite.Draw( this.tx, Vector3.Zero, new Vector3( X1, Y - HalfHeight, 0 ), Color );
    }

我想要一个版本,它也适用于角度线(如上所述)。对此有什么建议吗?

于 2009-03-11T17:56:41.057 回答