Собственно сабж.
Функция на Delphi, которая способна наложить одно изображение на другое, используя Alpha константу.
Ограничения:
1. оба буффера — 16 бит IDirectDrawSurface7 со стандартным для Windows форматом 565.
2. прозрачный цвет — черный.
3. Никаких MMX и прочих приколов, так что работать будет везде..
procedure AlphaDraw16(Dst, Src: IDirectDrawSurface7; Left, Top, Alpha: integer);
var
SBuff1: Pointer;
Buff1: Pointer;
BuffPtr1: integer absolute Buff1;
Wdt1: integer;
SBuff2: Pointer;
Buff2: Pointer;
BuffPtr2: integer absolute Buff2;
Start: integer;
Wdt2: integer;
W, H: integer;
SD: TDDSurfaceDesc2;
begin
try
SD.dwSize := sizeof(SD);
hr := Src.Lock(nil, SD, LockFlags or DDLOCK_READONLY , 0);
if (hr <> DD_OK) then
raise Exception.Create(DDErrorString(hr));
try
Buff1 := SD.lpSurface;
Wdt1 := SD.lPitch;
W := SD.dwWidth;
H := SD.dwHeight;
hr := Dst.Lock(nil, SD, LockFlags, 0);
if hr <> DD_OK then
raise Exception.Create(DDErrorString(hr));
try
Buff2 := SD.lpSurface;
Wdt2 := SD.lPitch;
Start := Wdt2 * Top + Left * 2;
asm
PUSHFD
PUSH EAX
PUSH EBX
PUSH ECX
PUSH EDX
PUSH EDI
PUSH ESI
CLD
MOV EDI, BuffPtr2
ADD EDI, Start
MOV ESI, BuffPtr1
MOV EDX, H
@@L1:
PUSH EDX
MOV ECX, W
@@L2:
PUSH ECX
LODSW
OR AX, AX
JNE @@DoMake_Alpha
INC EDI
INC EDI
JMP @@NO_Alpha
@@DoMake_Alpha:
// STOSW //comment
// JMP @@No_Alpha //comment
MOV BX, WORD PTR [EDI]
MOV EDX, Alpha
INC DL
@@Make_Alpha:
@@SrcColor_Red:
PUSH AX
PUSH DX
SHR AX, 11
AND AX, $1F
MUL DL
SHR AX, 8
AND AX, $1F
SHL AX, 11
MOV CX, AX
POP DX
POP AX
@@SrcColor_Green:
PUSH AX
PUSH DX
SHR AX, 5
AND AX, $3F
MUL DL
SHR AX, 8
AND AX, $3F
SHL AX, 5
OR CX, AX
POP DX
POP AX
@@SrcColor_Blue:
PUSH DX
AND AX, $1F
MUL DL
SHR AX, 8
AND AX, $1F
OR CX, AX
SHL ECX, 16
POP DX
OR BX, BX
JNE @@MakeDst
SHR ECX, 16
MOV AX, CX
JMP @@NoDst
@@MakeDst:
NEG DL
MOV AX, BX
@@DstColor_Red:
PUSH AX
PUSH DX
SHR AX, 11
AND AX, $1F
MUL DL
SHR AX, 8
AND AX, $1F
SHL AX, 11
MOV CX, AX
POP DX
POP AX
@@DstColor_Green:
PUSH AX
PUSH DX
SHR AX, 5
AND AX, $3F
MUL DL
SHR AX, 8
AND AX, $3F
SHL AX, 5
OR CX, AX
POP DX
POP AX
@@DstColor_Blue:
AND AX, $1F
MUL DL
SHR AX, 8
AND AX, $1F
OR CX, AX
MOV AX, CX
SHR ECX, 16
ADD AX, CX
@@NoDst:
STOSW
@@NO_Alpha:
POP ECX
DEC ECX
JE @@L2E
JMP @@L2
@@L2E:
SUB EDI, W
SUB EDI, W
ADD EDI, Wdt2
SUB ESI, W
SUB ESI, W
ADD ESI, Wdt1
POP EDX
DEC EDX
JE @@End
JMP @@L1
@@End:
POP ESI
POP EDI
POP EDX
POP ECX
POP EBX
POP EAX
POPFD
end;
finally
Dst.Unlock(nil);
end;
finally
Src.Unlock(nil);
end;
except
on E: Exception do
begin
OutputDebugString(E.Message);
end;
end;
end;
Кстати, в процессе тестирования была использована для отображения полноэкранного изображения (640х480). На GeForce 2MX — 2 FPS, на S3 Savage 8MB — 35 FPS.
OutputDebugString — своя функция, которая вызывает стандартнуюю OutputDebugString + пишет ошибки в файл
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))