AlphaDraw16 for DirectDraw7
От: Hacker_Delphi Россия  
Дата: 29.01.03 06:51
Оценка: 1 (1)
Собственно сабж.
Функция на 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 + пишет ошибки в файл
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.