Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Additives Alphablending (https://www.delphipraxis.net/183656-additives-alphablending.html)

Peter666 26. Jan 2015 17:12

Additives Alphablending
 
Hi,

hat jemand eine schnelle Routine bei der ich 2 RGBA Werte miteinander addieren kann? Ich bräuchte sowohl additives als auch normales Alphablending.
Bei OpenGL reicht ein:

Delphi-Quellcode:
 glEnable(GL_BLEND);
 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
allerdings hab ich bei dem Projekt hier einen Bildpointer und mache das komplett softwareseitig.

Peter

Medium 27. Jan 2015 01:27

AW: Additives Alphablending
 
Die mit schnellsten Routinen dafür habe ich in der Graphics32 Library gesehen. Dort wird mit MMX und/oder SSE gerechnet. Ich würde fast immer zur Benutzung der Lib raten (wirklich eine klasse Sache, das Ding kann natürlich noch viel viel mehr als nur Blending), aber zur Inspiration dürfte auch ein Blick in die Blending-Unit(s) nicht schaden. (Die Lib ist Open Source.)

Peter666 27. Jan 2015 10:21

AW: Additives Alphablending
 
Naja ich brauch die auch für ARM :)

Meine aktuelle Lösung schaut so aus:

Delphi-Quellcode:
function Scale32(scale, p: cardinal): cardinal;
var
  ag, rb: cardinal;
  sag, srb: cardinal;
begin
  ag := (p and $FF00FF00) shr 8;
  rb := p and $00FF00FF;

  sag := scale * ag;
  srb := scale * rb;

  sag := sag and $FF00FF00;
  srb := srb shr 8 and $00FF00FF;

  result := sag or srb;
end;

function blend_avg(source, target: cardinal): cardinal;
begin
  result := ((source and $FCFCFCFC) + (target and $FCFCFCFC)) shr 1;
end;

function blend_mul(source, target: cardinal): cardinal;
var
  sourcea, sourcer, sourceg, sourceb, targeta, targetr, targetg,
    targetb: integer;
begin
  sourcer := (source shr 0) and $FF;
  sourceg := (source shr 8) and $FF;
  sourceb := (source shr 16) and $FF;
  sourcea := (source shr 24) and $FF;

  targetr := (target shr 0) and $FF;
  targetg := (target shr 8) and $FF;
  targetb := (target shr 16) and $FF;
  targeta := (target shr 24) and $FF;

  targetr := (sourcer * targetr) shr 8;
  targetg := (sourceg * targetg) shr 8;
  targetb := (sourceb * targetb) shr 8;
  targeta := (sourcea * targeta) shr 8;

  result := (targetr shl 0) or (targetg shl 8) or (targetb shl 16) or
    (targeta shl 24);
end;

function blend_add(source, target: cardinal): cardinal;
const
  signmask = $80808080;
var
  t0, t1: cardinal;
begin
  t0 := (source xor target) and signmask;
  t1 := (source and target) and signmask;

  source := source and (not signmask);
  target := target and (not signmask);
  source := source + target;

  t1 := t1 or (t0 and source);
  t1 := (t1 shl 1) - (t1 shr 7);
  result := (source xor t0) or t1;
end;

function blend_alpha(src, tgt: cardinal): cardinal;
var
  alpha, invalpha: integer;
begin
  alpha := (tgt shr 24) and $FF;
  invalpha := $FF - alpha;

  result := Scale32(alpha, tgt) + Scale32(invalpha, src);
end;
Das klappt auch mit Alpha recht gut, aber addaptiv schaut nicht so aus wie es sollte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz