2010-01-28 2 views
4

Я новичок в C++ и DirectX, я родом из XNA. Я разработал игру вроде Fly The Copter. То, что я сделал, создано классом Wall. Пока игра бежит, я рисую все стены. В XNA я сохранил стены в ArrayList, а на C++ я использовал вектор. В XNA игра проходит быстро и на C++ очень медленная. Вот C++ код:Slow C++ DirectX 2D Game

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). Это единственные коды, которые запускаются в игровом цикле. Я знаю, что это плохой код, если у вас есть идея его улучшить, пожалуйста, помогите. Спасибо и извините за мой английский.

+0

Код здесь выглядит разумно умным. Проблема, скорее всего, заключается в фреймах конвейера рендеринга и оптимизации. – aramadia

+1

Я бы сказал, что вы не включили флаги оптимизации. – AraK

+0

может быть полезно знать, насколько медленнее. мы говорим о половинной скорости или порядках? –

ответ

8

Попробуйте заменить все вхождения на() оператором []. Например:

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()'? EDIT: О, просто нашел ответ: 'at()' проверяет границы. – dreamlax

+1

Нет реальной разницы, [] работает перегружен, поэтому его просто сокращает. Кроме того, я проигнорирован, потому что этот вид оптимизации() vs [] тривиален. – aramadia

+8

Существует разница - at() делает проверку диапазона, которая требует времени и бессмысленна, если вам это не нужно. И эффект оператора inlining [] (или at(), подходит к этому) может быть очень заметным. – 2010-01-28 21:44:44

2

Пытаться сужать причину проблемы производительности (также называется профилирование). Я попытался бы рисовать только один объект, продолжая обновлять все объекты. Если его внезапно ускорить, то это проблема с рисованием DirectX.

В противном случае попробуйте рисовать все объекты, но обновляйте только одну стену. Если он быстрее, то функция update() может быть слишком дорогостоящей.

0

Вы пробовали несколько буферов (a.k.a. Двойная буферизация) для растровых изображений?

Типичный сценарий состоит в том, чтобы нарисовать один буфер, а затем, когда первый буфер скопирован на экран, нарисуйте второй буфер.

Другая техника - иметь огромный «логический» экран в памяти. Часть рисунка на физическом дисплее - вид или вид в маленькую область в логический экран. Для перемещения фона (или экрана) требуется только копия со стороны графического процессора.

0

Вы можете помочь в доработке вызовов рисования спрайтов. Предположительно, ваш вызов draw вызывает ваш единственный экземпляр ID3DXSprite :: Draw с соответствующими параметрами.

Вы можете получить значительно улучшенную производительность, выполнив вызов ID3DXSprite :: Begin (с установленным флагом D3DXSPRITE_SORT_TEXTURE), а затем вызывая ID3DXSprite :: End, когда вы выполнили весь рендеринг. Затем ID3DXSprite сортирует все ваши вызовы спрайтов по текстуре, чтобы уменьшить количество переключателей текстуры и пакетные соответствующие вызовы. Это значительно улучшит производительность.

Сложно сказать больше, однако, не видя внутренних компонентов ваших вызовов «Обновить» и «Рисовать». Вышеизложенное является лишь предположением ...

0

Чтобы нарисовать каждую стену с другим призывом рисования, это плохая идея.Попытайтесь объединить данные в один буфер буфера/индекса вершин и отправить их в одну ничью. Это более разумная идея.

В любом случае, чтобы получить представление о том, ПОЧЕМУ, он медленно пытается использовать некоторые CPU и GPU (PerfHud, Intel GPA и т. Д.), Чтобы знать, прежде всего, что это узкое место (если процессор или графический процессор). И тогда вы можете бороться, чтобы облегчить проблему.

1
  • Как быстро «быстро»?
  • Насколько медленный «медленный»?
  • Сколько спрайтов вы рисуете?
  • Насколько велика каждая в качестве файла изображения, а в пикселях - на экране?
  • Как изменяется масштаб производительности (в XNA/C++) при изменении количества рисованных спрайтов?
  • Какая разница вы получите, если вы рисуете без обновления, или наоборот
1

Может быть, вы просто забыли включить режим выпуска :) У меня были некоторые проблемы с ним в прошлом, - я думал, что мой код был очень медленный из-за режима отладки. Если это не так, у вас может быть проблема с частью рендеринга или с огромным количеством объектов. Код, который вы предоставили, выглядит хорошо ...

0

Поиск в вашем списке стен вряд ли станет источником вашего замедления. Стоимость рисования объектов в 3D обычно будет ограничивающим фактором.

Важными частями являются код рисования, флаги, которые вы использовали для создания устройства DirectX, и флаги, используемые для создания ваших текстур. Мой удар в темноте ... проверьте, что вы инициализируете устройство как HAL (аппаратное 3D), а не REF (программное обеспечение 3d).

Кроме того, сколько спрайтов вы рисуете? Каждый призыв к розыгрышу имеет достаточное количество накладных расходов. Если вы сделаете больше пары сотен за фрейм, это будет вашим ограничивающим фактором.