Читаем Графика DirectX в Delphi полностью

При каждой перерисовке экрана отображается текущее состояние системы:

function TfrmDD.UpdateFraine : HRESULT;

var

hRet : HRESULT;

begin

Result := DD_FALSE;

PS.Calculate; // Пересчитываем положения частиц

// Воспроизведение состояния системы

hRet := PS.Render;

if Failed (hRet) then begin

Result := hRet;

Exit;

end;

Time := Time + 1; // Простейший эмулятор таймера

if Time > 15 then begin // Прошел срок существования системы

PS.Init(DEFAULT_SIZE, DEFAULT_POWER); // Вспышка в новом месте

Time := 0;

end;

Result := DD_OK;

end;

Полупрозрачность

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

В общем случае формула вычисления значения цветовых компонентов выглядит так:

Result = Alpha * srcColor + (1 - Alpha) * destColor

Здесь Alpha - коэффициент прозрачности, принимающий вещественное значение в пределах от нуля до единицы; srcColor - цвет источника; destColor - цвет приемника.

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

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

Result = Alpha * srcColor + destColor - Alpha * destColor

ИЛИ

Result = Alpha * (srcColor - destColor) + destColor

Коэффициент прозрачности имеет смысл представлять целым, чтобы все вычисления производить только с целыми числами. Считая Alpha целым в интервале 0 - 256, окончательную формулу расчета составляющей запишем так:

Result = (Alpha * (srcColor - destColor)) / 256 + destColor

Все предваряющие слова сказаны, можем перейти к иллюстрации - проекту каталога Ех18, при работе которого по знакомому фону перемещается полупрозрачный образ насекомого (рис. 3.8).

Массив Pict содержит битовую карту растра:

const

imageWidth = 84;

imageHeight = 80;

Alpha = 127; var

Pict : Array [0..imageWidth - 1, 0..imageHeight - 1] of Word;

ColorKey : Word; // Вспомогательный цветовой ключ

Поверхность образа не выводится на экран, а служит только для заполнения массива pict:

function TfrmDD.Prepare : HRESULT;

var

desc : TDDSURFACEDESC2;

i, j : Integer;

hRet : HRESULT; begin

Result := DD_FALSE;

ZeroMemory (@desc, SizeOf(desc) );

desc.dwSize := SizeOf(desc);

hRet := FDDSImage.Lock (nil, desc, DDLOGK_WAIT, 0);

if Failed (hRet) then begin Result := hRet;

Exit;

end;

// Заполнение массива Pict

for i := 0 to imageWidth - 1 do

for j := 0 to imageHeight - 1 do

Pict [i, j] := PWORD (Integer (desc.IpSurface) + j * desc.lPitch + i * (ScreenBitDepth div 8))^;

ColorKey := Pict [0,0]; // Определяемся с цветовым ключом

Result := FDDSImage.Unlock (nil);

end;

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

function TfrmDD.UpdateFrame : HRESULT;

var

X, Y : Integer; wrkRect : TRECT; hRet : HRESULT;

begin

ThisTickCount := GetTickCount;

if ThisTickCount - LastTickCount > 60 then begin X := 288 + trunc (cos(Angle) * 150);

Y := 208 + trunc (sin(Angle) * 150);

// Старая позиция образа

SetRect (wrkRect, X, Y, X + imageWidth, Y + imageHeight);

Angle := Angle + 0.05;

if Angle > 2 * Pi then Angle := Angle -2 * Pi;

// Вывод полупрозрачного образа в задний буфер

hRet := Blend (288 + trunc (cos(Angle) * 150),

208 + trunc (sin(Angle) * 150)); if Failed (hRet) then begin Result := hRet;

Exit;

end;

// Переключаем страницы hRet := FlipPages;

if Failed (hRet) then begin Result := hRet;

Exit;

end;

// Стираем образ в заднем буфере

hRet := FDDSBack.Blt (@wrkrect, FDDSBackGround, SwrkRect,

DDBLT_WAIT, nil); if Failed (hRet) then begin

Result := hRet;

Exit;

end;

LastTickCount := GetTickCount;

end;

Result := DD_OK;

end;

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

function TfrmDD.Blend (const X, Y : Integer) : HRESULT;

var

desc : TDDSURFACEDESC2; i, j : Integer;

wrkPointer : PWORD;

sTemp, dTemp : WORD;

sb, db, sg, dg, sr, dr : Byte;

blue, green, red : Byte;

hRet : HRESULT;

begin

ZeroMemory (@desc, SizeOf (desc) ) ; desc.dwSize := SizeOf(desc);

hRet := FDDSBack.Lock (nil, desc, DDLOCK_WAIT, 0) ;

if Failed (hRet) then begin Result := hRet;

Exit;

end;

for i := 0 to imageWidth - 1 do

for j := 0 to imageHeight - 1 do

// Только для точек с цветом, отличным от цвета фона if Pict [i, j] <> ColorKey then begin

wrkPointer := PWORD (Integer(desc.IpSurface) +

(Y + j) * desc.lPitch + (X + i) * (ScreenBitDepth div 8));

sTemp := Pict [i, j]; // Пиксел источника, точка образа

dTemp := wrkPointer^; // Приемник, фоновая картинка

sb = sTemp and $lf; // Синий цвет источника

db = dTemp and $lf; // Синий цвет приемника

sg = (sTemp shr 5) and $3f; // Зеленый цвет источника

dg = (dTemp shr 5) and $3f; // Зеленый цвет приемника

sr = (sTemp shr 11) and $lf; // Красный цвет источника

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных