2012-06-15 3 views
10

Я пишу 2D-платформерную игру, используя SDL с C++. Однако я столкнулся с огромной проблемой, связанной с масштабированием до разрешения. Я хочу, чтобы игра выглядела хорошо в полном HD, поэтому все изображения для игры были созданы так, чтобы естественное разрешение игры было 1920x1080. Однако я хочу, чтобы игра уменьшалась до правильного разрешения, если кто-то использует меньшее разрешение или масштабируется больше, если кто-то использует большее разрешение.Как масштабировать до разрешения в SDL?

Проблема заключается в том, что я не смог найти эффективный способ сделать это. Я начал с использования библиотеки SDL_gfx для предварительного масштабирования всех изображений, но это не сработает, так как оно создает много отключений - одни ошибки, когда один пиксель теряется. И поскольку мои анимации содержатся в одном изображении, когда анимация будет воспроизводиться, анимация будет слегка перемещаться вверх или вниз по каждому кадру.

Затем, после некоторого оглядки, я попытался использовать opengl для обработки масштабирования. В настоящее время моя программа рисует все изображения на SDL_Surface, которая составляет 1920x1080. Затем он преобразует эту поверхность в текстуру opengl, масштабирует эту текстуру до разрешения экрана, затем рисует текстуру. Это прекрасно работает визуально, но проблема в том, что он неэффективен вообще. В настоящее время я получаю максимальный фпс 18 :(

Так что мой вопрос кто-нибудь знает эффективный способ масштабирования на SDL дисплей с разрешением экрана?

+1

Вы рисуете, конвертируете и масштабируете на лету, когда используете opengl ?? – silent

+0

Также попросите ребят на форуме gamedev, они должны быть в состоянии помочь вам. – silent

+0

Да, вот почему это так неэффективно. Но в настоящее время я не могу найти другого способа сделать это, что работает. Нормально будет делать. –

ответ

10

Это неэффективно, поскольку OpenGL не был разработан, чтобы работать, что . способ Основные проблемы с производительностью текущего проекта:

  • Первая проблема:.. вы программное растрирование с СВД Извините, но независимо от того, что вы делаете с этой конфигурацией, что не будет узким местом при разрешении 1920х1080, у вас есть 2073,600 пикселей для цвета. Предполагая, что вам нужно 10 тактов, чтобы затенять каждый 4-канальный пиксель, на процессоре 2 ГГц вы используете максимум из 96,4 fps. Это не звучит плохо, кроме вас, возможно, не может пикселей, которые быстро, и вы все еще не сделали AI, ввод пользователя, игровые механики, звук, физику и все остальное, и вы, вероятно, прорисовывая несколько пикселей хотя бы один раз. SDL_gfx может быть быстрым, но для больших разрешений процессор просто полностью перегружен.
  • Вторая проблема: каждый кадр, вы копируете данные через графическую шину на графический процессор. Это самая медленная вещь, которую вы можете сделать с графикой. Данные изображения, вероятно, являются наихудшими из , что, потому что их обычно так много. В принципе, каждый кадр, который вы сообщаете графическому процессору, копирует два миллиона некоторых пикселей из ОЗУ в VRAM. Согласно Wikipedia, вы можете ожидать, что для 2 073 600 пикселей по 4 байта каждый, не более 258,9 кадров в секунду, что опять не звучит плохо, пока вы не вспомните все остальное, что вам нужно сделать.

Рекомендация: полностью переключите приложение на OpenGL. Это устраняет необходимость визуализации текстуры и копирования на экран - просто визуализируйте непосредственно на экран! Кроме того, масштабирование обрабатывается автоматически по вашей матрице представлений (glOrtho/gluOrtho2D для 2D), поэтому вам не нужно заботиться о проблеме масштабирования вообще - ваш видовой экран будет просто показывать все в одном масштабе. Это идеальное решение вашей проблемы.

Теперь у него есть один главный недостаток, который нужно перекодировать с помощью команд рисования OpenGL (что работает, но не слишком сложно, особенно в конечном итоге). Кроме того, вы можете попробовать следующие идеи для повышения скорости:

  • PBOs.Объекты пиксельных буферов могут использоваться для решения проблемы два, заставляя текстуру загружать/копировать асинхронную.
  • Многопоточность рендеринга. Большинство процессоров имеют как минимум два ядра, а на более новых чипах можно сохранить два состояния регистров для одного ядра (Hyperthreading). Вы по сути дублируете то, как GPU решает проблему рендеринга (имеет много потоков). Я не уверен, насколько безопасен поток SDL_gfx, но я уверен, что что-то может быть разработано, особенно если вы работаете одновременно с разными частями изображения.
  • Удостоверьтесь, что вы обращаете внимание на то, в каком месте ваша поверхность вытягивания находится в SDL. Вероятно, это должно быть SDL_SWSURFACE (потому что вы используете CPU).
  • Удалить VSync. Это может повысить производительность, даже если вы не работаете на частоте 60 Гц.
  • Убедитесь, что вы рисуете исходную текстуру - НЕ масштабируйте ее вверх или вниз до новой. Нарисуйте его в другом размере, и пусть растеризатор выполнит работу!
  • Спорадическое обновление: обновлять только половину изображения за раз. Вероятно, это близко к удвоению вашей частоты кадров, и это (обычно) не заметно.
  • Аналогичным образом обновляйте только изменяющиеся части изображения.

Надеюсь, что это поможет.

+0

SDL 2.0 теперь выключен, и он использует 3D-ускорение под водой. Возможно, это может помочь вашей работе? –

Смежные вопросы