VR
Virtual Reality On-line   DirectX
Новости   |     Журнал    |    Хаkер   |     Магазин   |   Проекты
[   Вход    ]
[Kарта сайтa]
[ Download  ]
[  Конкурс  ]
[  Анекдоты ]
[  Ссылки   ]
[  Реклама  ]
[ Почтальон ]
[ О проекте ]






TopList
DirectX.
Улучшенные спрайты
:

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

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

Logo
Рисунок 1. Фон

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

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

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

Logo
Рисунок 2. Прозрачная картинка

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

FTransImageSurface : IDirectDrawSurface7;

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


 FTransImageSurface := DDLoadBitmap(FDirectDraw, '2.bmp', 0, 0);
 DDSetColorKey(FTransImageSurface, RGB(255, 0, 255));

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

Во второй строке этого кода я указываю для поверхности FTransImageSurface цвет прозрачности с помощью функции DDSetColorKey. У нее два параметра:

1. Поверхность, у которой надо установить цвет прозрачности. Нам надо здесь указать FTransImageSurface.

2. Значение цвета, который будет использоваться в качестве прозрачного. Чтобы указать цвет, я использую функцию RGB(Красный, Зеленый, Синий). У этой функции три параметра, которые указывают красную, зеленую и синюю составляющую цвета. Каждая составляющая изменяется от 0 до 255. Если у тебя в качестве прозрачности используется красный цвет, то нужно указать RGB(255, 0, 0).

Лично я люблю использовать цвет с значениями RGB(255, 0, 255).

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

Напоминаю, что картинку фона мы выводили с помощью метода BltFast следующим образом:

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

Этот код копирует содержимое поверхности FimageSurface (указана в качестве третьего параметра) в вторичный буфер - FPrimarySurface. Первые два параметра указывают на левую и верхнюю позицию картинки. В последнем параметре мы указывали только DDBLTFAST_WAIT - если вывод сейчас невозможен, то необходимо ожидание возможности вывода.

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

Вот пример вывода нашей картинки, который надо вставить сразу после вывода фона:


 srcrect:=Rect(0,0,180,90);
 FPrimarySurface.BltFast (200, 200, FTransImageSurface, @srcrect, 
    DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY);

Заметь, что при вызове BltFast в качестве четвертого параметра указана переменная srcrect. Точнее сказать, тут используется только адрес структуры @srcrect в памяти. Значок @ указывает на то, что нужно использовать не саму переменную, а только ее адрес.

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

Теперь допустим, что у тебя есть какая-то переменная (любого типа) размером с пару мегабайт. Когда ты вызываешь какую-то процедуру и передаешь ей эту переменную, то все содержимое переменной записывается в стек, что отнимает много времени и расходует лишнюю память. Чтобы не делать такого бессмысленного копирования, ты должен всего лишь передать в процедуру указатель на переменную в памяти. Любой указатель занимает всего 4 байта и только они будут копироваться в стек. После того, как процедура начнет свое выполнение, она прочитает указатель и спокойно по нему найдет нужные данные в системной памяти.

Итак, чтобы получить адрес любой переменной нужно писать так: "@Переменная" (без кавычек конечно же). Чтобы увидеть содержимое находящееся по определенному адресу (иногда еще говорят "указатель", потому что адресная переменная указывает на данные в памяти) нужно написать так "Адрес^" (после переменной указателя поставить значок ^).

Теперь разберемся с четвертым параметром метода BltFast. Как ты уже понял, там передается указатель на структуру srcrect. Сама структура объявлена в разделе var следующим образом.


var
 srcrect:TRect;

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

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

srcrect:=Rect(0,0,180,90);

Здесь выполняется функция Rect у которой есть четыре параметра: левая, верхняя, правая и нижняя позиции необходимые для структуры. Результат выполнения этой функции - проинициализированная структура, которая записывается в нашу переменную srcrect.

Результат работы проги ты можешь увидеть на рисунке 3. Как видишь, на этом скрине рисунок 2 нарисован поверх рисунка 1, при этом цвет фона отсутствует.

Logo
Рисунок 3. Результат

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

 Исходники примера забирай здесь


Copyright©: Horrific aka Флёнов Михаил
Design by FMk group©