end;
end;
Обратите внимание на дополнительную проверку положения курсора, о ней я говорил при описании предыдущего примера. Данный пример безболезненно воспринимает "уход" курсора с клиентской области окна приложения.
Поскольку изменения вносятся в текстуру, воспроизводимую второй текстурой, то узор остается только на одной из них, и при переключении порядка их воспроизведения нарисованный узор как-будто не проявляется. Но в точках пересечения двух независимых узоров, нанесенных на разные текстуры, пикселы обеих текстур становятся прозрачными, и в этих местах проступает белый цвет, которым закрашивается задний буфер.Думаю, мы достаточно подробно разобрали пример использования нескольких текстур, и мне остается только предложить вам посмотреть работу приложения, когда значение альфа-составляющей для всех пикселов обеих текстур с самого начала равно 127. В этом случае на экране проступают два образа одновременно, а картинка, выводимая последней, выглядит чуть "плотнее" первой.
Цветовой ключ текстур
С помощью манипулирования значения альфа-составляющей пикселов текстуры можно добиться прозрачности ее участков, окрашенных в цвет заднего плана, и применить цветовой ключ.
В очередном примере, проекте каталога Ех14, рисуется дерево на фоне кирпичной стены, участки растра с изображением дерева, имеющие чистый белый цвет, прозрачны (рис. 8.12).
Аналогично предыдущим примерам, используются два объекта текстур:
FD3TextBrick : IDIRECT3DTEXTURE8; // Кирпичная кладка
FD3TextBmp : IDIRECT3DTEXTURE8; // Дерево
Размеры обоих растров установлены 128x128 пикселов. Координаты вершин квадрата, на который накладываются последовательно обе текстуры, установлены в единицы, чтобы закрыть весь экран.
функция инициализации текстуры из растра отличается тем, что в нее передается значение цветового ключа. При заполнении текстуры пикселы, имеющие такой цвет, делаются полностью прозрачными:
function TfrmD3D.InitTexture (const FileName : String;
const keyR, keyG, keyB : Byte) : HRESULT;
var
hRet : HRESULT;
d3dlr : TD3DLOCKED_RECT;
dwDstPitch : DWORD;
X, Y : DWORD; Bmp : tBitmap;
R, G, В : Byte;
begin
Bmp := TBitmap.Create;
Bmp.LoadFromfile (FileName);
hRet := FDSDDevice.CreateTexture (Bmp.Width, Bmp.Height, 0, 0,
D3DFMT_A8R8G8B8, D3DPOOLJ4ANAGED, FDSTextBmp);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
hRet := FDSTextBmp.LockRect(0, d3dlr, nil, 0) ;
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
dwDstPitch := d3dlr.Pitch;
for Y := 0 to Bmp.Height - 1 do
for X := 0 to Bmp.Width - 1 do begin
R := GetRValue (Bmp.Canvas.Pixels [X, DWORD (Bmp.Height - 1) - Y]);
G := GetGValue (Bmp.Canvas.Pixels [X, DWORD (Bmp.Height - 1) - Y]);
В := GetBValue (Bmp.Canvas.Pixels [X, DWORD (Bmp.Height - 1) - Y[):
//Сравнение цвета пиксела с цветовым ключом
if (R = keyR) and (G = keyG) and (B = keyB)
then PDWORD (DWORD(d3dlr.pBits) + Y * dwDstPitch + X * 4)^:=
D3DCOLOR_ARGB(0, R, G, В) // Такой пиксел
// должен стать прозрачным
else PDWORD (DWORD(d3dlr.pBits) + Y * dwDstPitch + X * 4)^ :=
D3DCOLOR_ARGB(255, R, G, B); // Все остальные пикселы
// непрозрачны
end;
Bmp. Free ;
Result := FDSTextBmp.UnlockRect(0);
end;
Кирпичная кладка создается "вручную", дополнительные растры не используются:
function TfrmDSD.MakeBrick : HRESULT;
var
hRet : HRESULT;
d3dlr : TD3DLOCKED_RECT;
dwDstPitch : DWORD;
X, Y, wrkStep : DWORD;
begin
wrkStep := 0;
hRet := FDSDDevice.CreateTexture (128, 128, 0, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, FD3TextBrick);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
hRet := FD3TextBrick.LockRect(0, d3dlr, nil, 0);
if FAILED(hRet) then begin
Result := hRet;
Exit;
end;
dwDstPitch := d3dlr.Pitch;
for Y := 0 to 127 do for X := 0 to 127 do
// Горизонтальные полоски - через каждые 10 пикселов
if Y mod 10 = 0 then begin // Полоски сероватого цвета
PDWORD (DWORD(d3dlr.pBits) + Y * dwDstPitch + X * 4)^ :=
D3DCOLOR_XRGB(200 + random (30), 200+ random (30), 200+ random (30)) ;
Inc (wrkStep); // Сдвиг для вертикальных полосок
end else
// Вертикальные полоски сдвигаются через каждый ряд кладки
if (X + wrkStep) mod 20 = 0
then PDWORD (DWORD(d3dlr.pBits) + Y * dwDstPitch + X * 4)^ :=
D3DCOLOR_XRGB(200 + random (30), 200+ random (30), 200+ random (30))
// Собственно кирпичи
else PDWORD (DWORD(d3dlr.pBits) + Y * dwDstPitch + X * 4)^ :=
D3DCOLOR_XRGB{150 + Random(lOO), 80, 10);
Result := FD3TextBrick.UnlockRect(0);
end;
Квадрат воспроизводится дважды. При наложении второй текстуры включаем альфа-смешение. Все сопутствующие действия аналогичны уже рассмотренным примерам.
Спрайты в DirectSD
Итак, мы знаем все, чтобы познакомиться с альтернативным DirectDraw способом создания настоящих 2О-приложений, являющихся частным случаем ЗВ-графики. Спрайты теперь представляются в виде примитивов, на которые накладывается текстура.
В проекте каталога Ех15 реализована несложная иллюстрация такого подхода, во время работы ее по экрану меланхолично проплывают рыбки (рис. 8.13).
Как обычно для многих примеров этой книги, массив объектов предопределенного размера содержит объекты отдельных изображений:
Читать дальше
Конец ознакомительного отрывка
Купить книгу