Чтение онлайн

на главную - закладки

Жанры

Графика DirectX в Delphi

Краснов Михаил

Шрифт:

FDDSImage := DDLoadBitmap (FDD, szBitmap, 0, 0); // Укороченный код

if FDDSImage = nil then begin // Произошла ошибка

ErrorOut (hRet, ' DDLoadBitmap' ) ;

Exit

end;

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

Вспомогательная

поверхность носит имя FDDSBack и в начале и конце работы приложения "обнуляется" самой первой. Ее размеры задаются равными размерам первичной поверхности:

FillChar (ddsd, SizeOf (ddsd) , 0) ; with ddsd do begin

dwSize := SizeOf (ddsd) ;

dwFlags := DDSD_CAPS or DDSD_HEIGHT or DDSD_WIDTH;

ddsCaps . dwCaps := DDSCAPS_OFFSCREENPLAIN;

dwWidth := ScreenWidth;

dwHeight := ScreenHeight; end;

hRet := FDD. CreateSur face (ddsd, FDDSBack, nil); if hRet <> DD_OK then begin

ErrorOut (hRet, 'Create Back Surface');

Exit

end;

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

ZeroMemory(@ddbltfx, SizeOf (ddbltfx) ) ; ddbltfx.dwSize := SizeOf (ddbltfx) ; ddbltfx. dwFillColor := 0;

while True do begin // Закрашиваем фон вторичной поверхности черным hRet := FDDSBack. Bit (nil, nil, nil, DDBLT COLORFILL or DDBLT WAIT, @ddbltfx) ;

// Внеэкранная поверхность также может быть потеряна

if hRet = DDERR^SURFACELOST then begin if Failed (RestoreAll) then Exit;

end

else Break; end;

// Помещаем растр на вспомогательную поверхность while True do begin

hRet := FDDSBack.BltFast (1ft, 112, FDDSImage, nil, DDBLTFAST_WAIT);

if hRet = DDERR_SURFACELOST then begin if Failed (RestoreAll) then Exit;

end

else Break; end;

// Вспомогательная поверхность заполнена, блиттинг производится //на первичную while True do begin

hRet := FDDSPrimary.BltFast (0, 0, FDDSBack, nil, DDBLTFAST_WAIT);

if hRet = DDERR_SURFACELOST then begin if Failed (RestoreAll) then Exit;

end

else Break;

end;

Функция восстановления поверхности использует вспомогательную функцию перезагрузки растра DDReLoadBitmap модуля DDUtil:

function TfrmDD.RestoreAll : HRESULT; begin

Result = DD_FALSE;

if Succeeded (FDDSPrimary._Restore) then begin if Failed (FDDSImage._Restore) then Exit;

// Рекомендуется перезагрузить растр после восстановления if Failed (DDReLoadBitmap(FDDSImage, szBitmap)) then Exit;

// Добавилось восстановление еще одной вспомогательной поверхности

if Failed (FDDSBack.^Restore) then Exit;

Result := DD_OK;

end;

end;

Протестируйте приложение: никаких полос не возникает, все выглядит прекрасно. DirectDraw

предлагает автоматизированный механизм двойной буферизации, аналогичный проделанному нами вручную. Посмотрим на примере проекта каталога Ех1б, как это делается. При создании первичной поверхности указываем количество задних буферов. Вместо одной константы у нас появилась комбинация нескольких флагов. Создаваемая поверхность является комплексной, состоящей из двух поверхностей - первичной и присоединенной к ней вторичной поверхности заднего буфера. Чтобы оговорить то, что "перебрасывание" (flipping) содержимого заднего буфера на первичную поверхность будет осуществляться DirectDraw без нашего участия, необходимо добавить флаг DDSCAPS_FLIP:

FillChar (ddsd, SizeOf(ddsd), 0);

ddsd.dwSize := SizeOf(ddsd);

// Сообщаем, что надо учесть наши пожелания о буфер заднего плана

ddsd.dwFlags := DDSD_CAPS or DDSD_BACKBUFFERCOUNT;

ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE or DDSCAPS_FLIP or

DDSCAPS_COMPLEX; // + комплексная поверхность + разрешить перебрасывание

ddsd.dwBackBufferCount := 1; // У поверхности есть один задний буфер

hRet := FDD.CreateSurface(ddsd, FDDSPrimary, nil);

if hRet <> DD_OK then begin

ErrorOut(hRet, 'Create Primary Surface');

Exit;

end;

Поверхность заднего буфера нам создавать не нужно, она появится без нашего участия, но для осуществления вывода на нее необходимо связать нашу переменную FDDSBack, для чего предназначен метод поверхности GetAttachedSurface. Первый аргумент метода - запись типа TDDSCaps2. С таким типом мы встречались, он является частью структуры TDDSurfaceDesc2. Здесь же указываем, что нам требуется адрес поверхности заднего буфера:

FillChar(ddscaps, SizeOf(ddscaps), 0); // Обнуляем все поля записи

// Оговариваем, что требуется адрес поверхности заднего буфера

ddscaps.dwCaps := DDSCAPS_BACKBUFFER;

// Получаем адрес присоединенной поверхности

hRet := FDDSPrimary.GetAttachedSurface(ddscaps, FDDSBack);

if hRet <> DD_OK then begin

ErrorOut(hRet, 'GetAttachedSurface');

Exit;

end;

Код воспроизведения изменился только в финальной части, вместо использования метода BitFast первичной поверхности вызываем ее метод Flip:

while True do begin

hRet := FDDSPrimary.Flip(nil, DDFLIP_WAIT) ;_

if hRet = DDERR_SURFACELOST then begin if Failed (RestoreAll) then Exit;

end

else Break;

end;

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

Присоединенная поверхность не требует отдельного восстановления, она будет восстановлена как часть первичной, комплексной поверхности.

Поделиться:
Популярные книги

Дракон - не подарок

Суббота Светлана
2. Королевская академия Драко
Фантастика:
фэнтези
6.74
рейтинг книги
Дракон - не подарок

Бастард Императора. Том 8

Орлов Андрей Юрьевич
8. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 8

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Эра Мангуста. Том 2

Третьяков Андрей
2. Рос: Мангуст
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эра Мангуста. Том 2

Идеальный мир для Лекаря 14

Сапфир Олег
14. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 14

Один на миллион. Трилогия

Земляной Андрей Борисович
Один на миллион
Фантастика:
боевая фантастика
8.95
рейтинг книги
Один на миллион. Трилогия

Помещицы из будущего

Порохня Анна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Помещицы из будущего

Шлейф сандала

Лерн Анна
Фантастика:
фэнтези
6.00
рейтинг книги
Шлейф сандала

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

Император

Рави Ивар
7. Прометей
Фантастика:
фэнтези
7.11
рейтинг книги
Император

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Князь Серединного мира

Земляной Андрей Борисович
4. Страж
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Князь Серединного мира

Чайлдфри

Тоцка Тала
Любовные романы:
современные любовные романы
6.51
рейтинг книги
Чайлдфри