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

Ускоренный DirectDraw

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


SurfaceDesc.dwSize := SizeOf(SurfaceDesc); // Указываем ее размер (это обязательно)

SurfaceDesc.dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT;

SurfaceDesc.dwBackBufferCount := 1; //Указываем количество вторичных экранов

SurfaceDesc.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or

DDSCAPS_FLIP or DDSCAPS_COMPLEX;

FDirectDraw.CreateSurface(SurfaceDesc, FPrimarySurface, nil); //Создаем поверхность

Заметь, что в свойстве dwFlags структуры SurfaceDesc (SurfaceDesc.dwFlags) появился еще один флаг - DDSD_BACKBUFFERCOUNT. Этот флаг говорит о том, что в свойстве dwBackBufferCount будет указано количество дополнительных экранов. Если этот флаг не указать, то свойство dwBackBufferCount игнорируется.

Сколько поверхностей ты создашь, зависит только от твоей жадности и возможностей видюхи (точнее сказать, от ее памяти), но для большинства примеров достаточно 1 дополнительной поверхности. Если поверхность не поместится в памяти видюхи, то она будет создана в оперативке, но тут уже можно забыть о переключении. Так что я не советую сильно жадничать и использовать память по минимуму.

В параметре SurfaceDesc.ddsCaps.dwCaps я указал следующие флаги:

DDSCAPS_PRIMARYSURFACE - создаваемая поверхность будет первичной.

DDSCAPS_FLIP - поверхность должна поддерживать переключения.

DDSCAPS_COMPLEX - поверхности должны быть комплексными.

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

Чтобы получить доступ к вторичной поверхности, необходимо написать следующий код:

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

fcaps.dwCaps := DDSCAPS_BACKBUFFER; //Указываем, что нам нужна вторичная поверхность.

FPrimarySurface.GetAttachedSurface(fcaps, FBackgroundSurface); //Получаем ее.

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

Здесь я использую новую структуру fcaps, которую тоже надо добавить в раздел var:

var

fcaps : TDDSCaps2;

В этой структуре указывается, что именно мы хотим сделать при вызове метода GetAttachedSurface. Мы получаем доступ к вторичной поверхности, значит надо обязательно указать флаг DDSCAPS_BACKBUFFER.

Рисуем по-новому

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

FBackgroundSurface.BltFast (175, 75, FImageSurface, nil, DDBLTFAST_WAIT);

FPrimarySurface.Flip(nil, DDFLIP_WAIT);

Теперь я рисую с помощью функции BltFast на вторичной поверхности FBackgroundSurface. После этого я только вызываю метод главной поверхности Flip, и вторичная поверхность становится главной. В качестве второго параметра я указываю флаг DDFLIP_WAIT, что означает, что если сейчас переключение экрана невозможно, то дождаться разрешения.

Назад на стр. 042-060-1  Содержание  Вперед на стр. 042-060-3