4

我是 C++ 和 DirectX 的新手,我来自 XNA。我开发了一款像Fly The Copter这样的游戏。我所做的是创建了一个名为 Wall 的类。在游戏运行时,我绘制了所有的墙壁。在 XNA 中,我将墙壁存储在 ArrayList 中,而在 C++ 中,我使用了向量。在 XNA 中游戏运行速度很快,而在 C++ 中运行速度非常慢。这是 C++ 代码:

void GameScreen::Update()
{
    //Update Walls
    int len = walls.size();
    for(int i = wallsPassed; i < len; i++)
    {
        walls.at(i).Update();
        if (walls.at(i).pos.x <= -40)
            wallsPassed += 2;
    }
}

void GameScreen::Draw()
{
    //Draw Walls
    int len = walls.size();
    for(int i = wallsPassed; i < len; i++)
    {
        if (walls.at(i).pos.x < 1280)
            walls.at(i).Draw();
        else
            break;
    }
}

在 Update 方法中,我将 X 值减少 4。在 Draw 方法中,我调用 sprite->Draw (Direct3DXSprite)。那是在游戏循环中运行的唯一代码。我知道这是一个糟糕的代码,如果您有改进的想法,请帮忙。谢谢和对不起我的英语。

4

8 回答 8

8

尝试用 [] 运算符替换所有出现的 at()。例如:

 walls[i].Draw();

然后打开所有优化。[] 和 at() 都是函数调用 - 要获得最大性能,您需要确保它们是内联的,这就是提高优化级别的作用。

您还可以对墙对象进行一些最小缓存 - 例如:

 for(int i = wallsPassed; i < len; i++)
 {
    Wall & w = walls[i]; 
    w.Update();
    if (w.pos.x <= -40)
        wallsPassed += 2;
 }
于 2010-01-28T21:36:49.440 回答
2

尝试缩小性能问题的原因(也称为分析)。我会尝试只绘制一个对象,同时继续更新所有对象。如果它突然更快,那么它的 DirectX 绘图问题。

否则尝试绘制所有对象,但只更新一堵墙。如果它更快,那么您的 update() 函数可能太贵了。

于 2010-01-28T21:46:42.233 回答
1
  • “快”有多快?
  • “真的很慢”有多慢?
  • 你画了多少个精灵?
  • 每个图像文件有多大,在屏幕上绘制的像素是多少?
  • 当您更改绘制的精灵数量时,性能如何扩展(在 XNA/C++ 中)?
  • 如果你在不更新的情况下绘制,你会得到什么不同,反之亦然
于 2010-01-29T10:16:23.527 回答
1

也许您只是忘记打开发布模式 :) 过去我遇到了一些问题 - 我认为由于调试模式,我的代码非常慢。如果不是这样,您可能会在渲染部分或大量对象时遇到问题。您提供的代码看起来不错...

于 2010-01-29T10:40:17.683 回答
0

您是否为位图尝试过多个缓冲区(又名双缓冲)?

典型的场景是在一个缓冲区中绘制,然后在将第一个缓冲区复制到屏幕时,在第二个缓冲区中绘制。

另一种技术是在内存中有一个巨大的“逻辑”屏幕。物理显示中绘制的部分是逻辑屏幕中小区域的视口视图。移动背景(或屏幕)只需要图形处理器的一部分。

于 2010-01-28T22:45:22.230 回答
0

您可以帮助精灵绘制调用的批处理。大概您的绘图调用使用相关参数调用您唯一的 ID3DXSprite::Draw 实例。

通过调用 ID3DXSprite::Begin(设置了 D3DXSPRITE_SORT_TEXTURE 标志),然后在完成所有渲染后调用 ID3DXSprite::End,可以大大提高性能。ID3DXSprite 然后将按纹理对所有精灵调用进行排序,以减少纹理切换的数量并将相关调用批处理在一起。这将大大提高性能。

但是,如果不了解 Update 和 Draw 调用的内部结构,就很难说得更多。以上只是猜测...

于 2010-01-29T08:48:45.613 回答
0

用不同的绘制调用绘制每一面墙是个坏主意。尝试将数据批处理到单个顶点缓冲区/索引缓冲区并将它们发送到单个绘制中。这是一个更理智的想法。

无论如何,为了了解为什么它会慢慢地尝试使用一些 CPU 和 GPU(PerfHud、Intel GPA 等),首先要知道瓶颈是什么(如果是 CPU 或 GPU)。然后你可以努力缓解这个问题。

于 2010-01-29T09:53:22.923 回答
0

查找您的墙壁列表不太可能是您减速的根源。以 3D 形式绘制对象的成本通常是限制因素。

重要的部分是您的绘制代码、用于创建 DirectX 设备的标志以及用于创建纹理的标志。我在黑暗中刺伤...检查您是否将设备初始化为 HAL(硬件 3d)而不是 REF(软件 3d)。

另外,你画了多少个精灵?每个绘图调用都有相当多的开销。如果您每帧的收入超过几百,那将是您的限制因素。

于 2010-01-29T20:04:06.630 回答