代码之家  ›  专栏  ›  技术社区  ›  Adir

慢速C++ DirectX 2D游戏

  •  4
  • Adir  · 技术社区  · 16 年前

    我是C++和DirectX的新手,我来自XNA。 我开发了一个类似的游戏 Fly The Copter . 我所做的是创建一个名为wall的类。 当比赛进行的时候,我画了所有的墙。 在XNA中,我把墙存储在一个数组中,在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;
        }
    }
    

    在更新方法中,我将x值减少4。 在draw方法中,我称为sprite->draw(direct3dxsprite)。 这是唯一在游戏循环中运行的代码。 我知道这是一个坏代码,如果你有改进的想法,请帮助。 谢谢,对我的英语感到抱歉。

    8 回复  |  直到 16 年前
        1
  •  8
  •   anon    16 年前

    尝试将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;
     }
    
        2
  •  2
  •   aramadia    16 年前

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

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

        3
  •  1
  •   Mr. Boy    16 年前
    • “快”有多快?
    • “真的慢”有多慢?
    • 你画了多少精灵?
    • 每个图像文件有多大,以屏幕上绘制的像素为单位?
    • 当你改变精灵的数量时,性能规模(在xNa/c++中)是如何变化的?
    • 如果你不更新就画画,或者相反,你会有什么不同呢
        4
  •  1
  •   chris    16 年前

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

        5
  •  0
  •   Thomas Matthews    16 年前

    你试过多个缓冲器吗(A.K.A. 双缓冲 )对于位图?

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

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

        6
  •  0
  •   Goz    16 年前

    您可以帮助批处理sprite draw调用。假设您的draw调用使用相关参数调用ID3DxPrite::draw的唯一实例。

    通过调用id3dxsprite::begin(使用d3dxsprite_sort_texture标志集),然后在完成所有渲染后调用id3dxsprite::end,可以大大提高性能。ID3DXSPRITE将按纹理对所有sprite调用进行排序,以减少纹理开关的数量,并将相关调用批处理在一起。这将大大提高性能。

    但是,如果没有看到更新和draw调用的内部结构,就很难说得更多。以上只是猜测…

        7
  •  0
  •   feal87    16 年前

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

    不管怎样,为了弄清楚为什么它会慢慢地运行,首先尝试使用一些CPU和GPU(PerfHud、Intel GPA等)来了解瓶颈是什么(如果是CPU或GPU)。然后你可以努力减轻这个问题。

        8
  •  0
  •   Alan    16 年前

    查看你的墙列表不太可能是你减速的原因。在3D中绘制对象的成本通常是限制因素。

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

    还有,你画了多少精灵?每次抽奖都有相当数量的管理费用。如果你每帧超过两百,那将是你的限制因素。