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






TopList
Delphi+DirectX7,8.
Картинки с прозрачным фоном
:

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

Logo
Рис 1. Фон

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

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

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

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

Итак, приступим к кодингу. Открывай пример из предыдущей статьи и читай дальше (или качай пример в конце этой статьи и читай дальше, чтобы разобраться с происходящим). Для начала нам понадобится несколько новых переменных. В разделе private добавь следующее:

 private
  { Private declarations }
  //Новые переменные
  FTransparentImage : IDirectDrawSurface7;
  MouseX, MouseY    : Integer;
  //Дальше идут объявления уже использованных нами переменных
  FDirectDraw : IDirectDraw7;
  FPrimarySurface   : IDirectDrawSurface7;
  FBackGround       : IDirectDrawSurface7;
  //И так далее

FTransparentImage - эта поверхность будет использоваться для хранения картинки с рисунка 2.

MouseX и MouseY - эти переменные будут хранить текущее положение курсора.

Теперь в самом начале обработчика события OnCreate нужно обнулить все новые переменные:

 FTransparentImage := nil;
 MouseX:=0;
 MouseY:=0;

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

 //Это у тебя уже должно быть. Этот текст я просто для напоминания.
 //Здесь мы получали вторичную поверхность.
 FillChar(fcaps, SizeOf(fcaps), 0);
 fcaps.dwCaps := DDSCAPS_BACKBUFFER;
 hRet := FPrimarySurface.GetAttachedSurface(fcaps, FBackGround);
 if hRet <> DD_OK then
  begin
   ErrorOut(hRet);
   Close;
   Exit;
  end;

 //А вот дальше идёт новый текст.

//Это я загружаю вторую картинку. Это делается так же, как я загружал фон.
 FTransparentImage := DDLoadBitmap(FDirectDraw, 'bart.bmp', 0, 0);
 if FTransparentImage = nil then
  begin
   ErrorOut(hRet);
   Close;
   Exit;
  end;

 //Устанавливаю прозрачный цвет.
 DDSetColorKey (FTransparentImage, RGB(255, 0, 255));
 if hRet <> DD_OK then
  begin
   ErrorOut(hRet);
  end;
 //Прячу курсор. Функции для работы с курсором
 //описаны в этом же номере в статье "WinAPI".
 ShowCursor(false);

Здесь есть одна новая функция - DDSetColorKey. Она устанавливает прозрачный цвет в картинке. Первым параметром передаётся поверхность содержащая картинку. Второй параметр - цвет, который будет использоватся в качестве прозрачного. Я его задаю в качестве трёх составляющих: RGB(Красный, Зелёный, Голубой).

В обработчике события OnDestroy нужно добавить уничтожение поверхности второй картинки и снова показать курсор:

procedure TForm1.FormDestroy(Sender: TObject);
begin
 //Уничтожаю вторую картинку.
 if Assigned(FTransparentImage) then FTransparentImage := nil;
 //Далее всё уже знакомо.
 if Assigned(FImageSurface) then FImageSurface := nil;
 if Assigned(FBackGround) then FBackGround := nil;
 if Assigned(FPrimarySurface) then FPrimarySurface := nil;
 if Assigned(FDirectDraw) then FDirectDraw := nil;
 //Включаю курсор.
 ShowCursor(true);
end;

И вот тут мы подошли к самому вкусненькому - рисование. Заходим в обработчик события OnPaint. Там у нас сейчас должно быть следующее:

 //В начале идёт закрашивание экрана и проверка на потерянность 
 //поверхностей.
 //Не забудь добавить восстановление поверхности со второй картинкой. 
 //Я это опускаю, потому что это делается так же, как и с первой.

 //Это вывод на экран фона (первый рисунок)
 FBackGround.BltFast (175, 75, FImageSurface, nil, DDBLTFAST_WAIT);

 //Переключение поверхности
 FPrimarySurface.Flip(nil, DDFLIP_WAIT);
end;

После вывода фона и перед переключением поверхности нам нужно вывести нашу вторую картинку, чтобы она оказалась наверху:

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

 //Выводим вторую картинку.
 FBackGround.BltFast(mouseX-20, mouseY-47, FTransparentImage, nil,
                  DDBLTFAST_WAIT or DDBLTFAST_SRCCOLORKEY);
 FPrimarySurface.Flip(nil, DDFLIP_WAIT);
end;

Для вывода второй картинки я использую ту же функцию BltFast. Я её уже расписывал. Единственное, что изменилось - в флагах добавился параметр DDBLTFAST_SRCCOLORKEY. Он говорит о том, что нужно учитывать прозрачный цвет источника. В качестве источника используется FTransparentImage (вторая картинка), значит именно её прозрачный цвет (который мы установили в обработчике OnCreate) не будет копироватся.

Вот и всё. Осталось только добавить обработчик события OnMouseMove:

 mouseX := X;
 mouseY := Y;
 FormPaint(nil);
Logo
Рис 3. Результат

Здесь я запоминаю текущую позицию курсора и заставляю перерисовать сцену с помощью вызова функции FormPaint(nil).

Вот и всё. Можешь запустить прогу и подёргать мышкой. На рисунке 3. ты можешь видеть результат сегодняшней работы. Как видешь вторая картинка скопировалась на экран без своего фона (розовый цвет).

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

На сегодня всё.

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

Для примера нужны новые заголовочные файлы, в которых уже прописана поддержка интерфейсов DirectX7. Я эти файлы разместил в разделе "Скачать".


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