2010-01-28 118 views
4

我是C++和DirectX的新手,我来自XNA。 我开发了一款类似Fly The Copter的游戏。 我所做的是创建了一个名为Wall的类。 游戏运行时,我画了所有的墙。 在XNA中,我将墙存储在一个ArrayList中,并在C++中使用了vector。 在XNA中,游戏运行速度很快,在C++中速度非常慢。 这里的C++代码:缓慢的C++ DirectX 2D游戏

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; 
    } 
} 

在更新方法我通过4. 减少的X值在Draw方法我打电话sprite->绘制(Direct3DXSprite)。 这是在游戏循环中运行的唯一代码。 我知道这是一个不好的代码,如果你有一个想法来改进它,请帮助。 感谢和抱歉我的英语。

+0

这里的代码看起来相当聪明。问题很可能在于渲染管线和优化标志。 – aramadia 2010-01-28 21:44:14

+1

我会说你没有打开优化标志。 – AraK 2010-01-28 21:53:05

+0

知道慢多少可能会有用。我们说半速还是数量级? – 2010-01-29 10:16:11

回答

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; 
} 
+0

'[]'和'at()'之间的主要区别是什么?编辑:哦,刚刚找到答案:'at()'检查边界。 – dreamlax 2010-01-28 21:40:13

+1

没有真正的区别,[]操作超负荷,所以它只是速记。此外,我低估了,因为这种优化()vs []是微不足道的。 – aramadia 2010-01-28 21:42:33

+8

有一个区别 - at()做范围检查,如果你不需要它,这需要时间并且毫无意义。内联运算符[](或at())的效果可以非常明显。 – 2010-01-28 21:44:44

2

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

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

0

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

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

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

0

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

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

但是,如果没有看到更新和绘制调用的内部函数,很难说更多。以上只是一个猜测...

0

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

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

1
  • '快'有多快?
  • 速度有多慢会“很慢”?
  • 你绘制了多少个精灵?
  • 每个图像文件的大小和屏幕上的像素大小是多少?
  • 当您更改绘制的精灵数量时,性能如何缩放(在XNA/C++中)?
  • 你什么区别,如果你画不更新,反之亦然
1

也许你只是忘记打开释放模式:)我在过去的一些问题 - 我想我的代码是由于调试模式非常缓慢。如果不是这样,则可能会出现渲染部件或对象数量过大的问题。你提供的代码看起来不错...

0

查看到你的墙上列表不太可能是你的放缓的源头。以3D绘制对象的成本通常会成为限制因素。

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

另外,你绘制了多少个精灵?每次平局呼叫都有相当的开销。如果你每帧制作超过几百帧,那将是你的限制因素。