Программирование графики

Ускоренный DirectDraw

Xakep, номер #042, стр. 042-060-1

Horrific aka Фленов Михаил smirnandr@mail.ru www.cydsoft.com/vr-online

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

Эпизод 1

Для начала попробуем ускорить пример, написанный в прошлом номере Х. При выводе графики мы использовали очень быструю функцию BltFast, но она рисует прямо на первичной поверхности. Что же в этом страшного? Пока мы рисуем только одну картинку, ты не заметишь тормозов, но как только количество рисунков превысит 5, тормоза будут уже ощутимыми.

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

Эпизод 2

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

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

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

Да будет так!!!

Давай подкорректируем наш предыдущий пример, чтобы он отображал данные с помощью переключающихся экранов. Для этого в раздел var добавь объявление еще одной поверхности, которая будет вторичной:

FBackgroundSurface : IDirectDrawSurface7;

Теперь надо подкорректировать код, который создает главную поверхность, и указать, что нужно будет создавать и вторичную поверхность:

FillChar (SurfaceDesc, SizeOf(SurfaceDesc), 0); // Обнуляем структуру SurfaceDesc

Содержание  Вперед на стр. 042-060-2

ttfb: 846.3819026947 ms