DirectX Графика в проектах Delphi

       

Цветовой ключ текстур



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

Рис. 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;

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


Содержание раздела