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

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

Жанры

Графика DirectX в Delphi

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

Шрифт:

var

desc : TDDSURFACEDESC2;

i, j : Integer;

hRet : HRESULT; begin

ZeroMemory (@desc, SizeOf(desc));

desc.dwSize := SizeOf (desc);

hRet := FDDSZoom.Lock (nil, desc, DDLOCK_WAIT, 0); if Failed (hRet) then begin Result := hRet;

Exit;

end;

for i := 0 to 99 do // Цикл по всем точкам поверхности

for j := 0 to 99 do

// Выделяем точки, располагающиеся за пределами круга "лупы"

if sqr (i - 50} + sqr (j - 50) > 50 * 50 then // Заполняем черным

PWord (Integer(desc.IpSurface) + j * desc.lPitch + i * 2)^ := 0;

Result := FDDSZoom.Unlock (nil);

end;

При

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

// Квадрат, задающий степень увеличения

SetRect (wrkRect, mouseX + 25, mouseY + 25, mouseX + 75, mouseY + 75);

// Растягиваем участок фона

FDDSZoom.Bit (nil, FDDSBackGround, SwrkRect, DDBLT_WAIT, nil);

Circle; // Заполняем черным часть квадрата

// Выводим с цветовым ключом

FDDSBack.BltFast (mouseX, mouseY, FDDSZoom, nil,

DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY);

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

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

В проекте каталога Ех22 приведено другое решение задачи, менее элегантное, но работающее с любыми цветовыми ключами.

Здесь, помимо поверхности FDDSZoom, введена поверхность FDDSDouble. Для первой из них в качестве ключа взят чистый зеленый цвет, как отсутствующий на фоне. Вторая поверхность создается путем загрузки изображения-шаблона - зеленый квадрат с черным кругом посередине. Ключом для нее установлен черный цвет.

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

SetRect (wrkRect, mouseX + 25, mouseY + 25, mouseX + 75, mouseY +- 75);

// Растягиваем участок фона

FDDSZoom.Blt (nil, FDDSBackGround, @wrkRect, DDBLT_WAIT, nil);

// Вместо черных участков шаблона останется увеличенный фрагмент

FDDSZoom.BltFast (О, О, FDDSDouble, nil,

DDBLTFASTJMAIT or DDBLTFAST^SRCCOLORKEY);

// Зеленая канва не воспроизведется FDDSBack.BltFast (mouseX, mouseY, FDDSZoom, nil,

DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY);

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

Палитры

Для хранения отдельного набора цветовых составляющих палитры используется

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

В любой момент времени мы можем получить набор палитры и модифицировать его, как это делается в следующем нашем примере (проект каталога Ех23). За основу взят проект с перемещающимся драконом, но здесь с течением времени экран становится тусклым, имитируется суточная смена освещенности. Дойдя до некоторой фазы, восстанавливается первоначальная яркость. Такой эффект постепенного угасания называется fade (затухание). Разберем, как он создается.

Для хранения первоначальной палитры предназначен массив:

DefPal : Array[0..255] of TPaietteEntry;

Массив заполняется после загрузки палитры из растра, для чего вызывается

Метод Палитры GetEntries:

hRet := FDDpal.GetEntries(0, 0, 256, @DefPal);

if Failed (hRet) then ErrorOut(hRet, 'Palette GetEntries');

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

// Получаем составляющие текущей палитры экрана FDDpal.GetEntries(О, О, 256, @PalEntries) ;

for i := 0 to 255 do begin // Цикл по всем элементам палитры

if PalEntries[i].peRed > Step then PalEntries[i].peRed :=

PalEntries[i].peRed - Step;

if PalEntries[i].peGreen > Step then PalEntries[i].peGreen :=

PalEntries [i] .peGreen - Step

if PalEntries[i].peBlue > Step then PalEntries[i].peBlue :=

PalEntries[i].peBlue - Step;

end;

// Устанавливаем текущей палитру, образованную элементами массива

FDDPal.SetEntries(0, 0, 256, @PalEntries);

Timer := (Timer + 1) mod 100;

// Восстанавливаем первоначальную палитру

if Timer = 0 then FDDpal.SetEntries(0, 0, 256, @DefPal);

Эффект угасания часто применяется для необычного завершения работы приложения.

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

Рассмотрим простейший пример на эту тему - проект каталога Ех24. Фон представляет собой рисунок, построенный серией эллипсов, нарисованных оттенками серого; цвета повторяются в каждой серии (рис. 3.12).

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

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

Сын Тишайшего

Яманов Александр
1. Царь Федя
Фантастика:
попаданцы
альтернативная история
фэнтези
5.20
рейтинг книги
Сын Тишайшего

"Искажающие реальность" Компиляция. Книги 1-14

Атаманов Михаил Александрович
Искажающие реальность
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
рпг
5.00
рейтинг книги
Искажающие реальность Компиляция. Книги 1-14

Школа. Первый пояс

Игнатов Михаил Павлович
2. Путь
Фантастика:
фэнтези
7.67
рейтинг книги
Школа. Первый пояс

Невеста на откуп

Белецкая Наталья
2. Невеста на откуп
Фантастика:
фэнтези
5.83
рейтинг книги
Невеста на откуп

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Аргумент барона Бронина 4

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

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Измена. Право на обман

Арская Арина
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на обман

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

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

Жаба с кошельком

Донцова Дарья
19. Любительница частного сыска Даша Васильева
Детективы:
иронические детективы
8.26
рейтинг книги
Жаба с кошельком

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

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

Академия чаросвет. Тень

Ярошинская Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Академия чаросвет. Тень

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4