1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
procedure TMainForm.DoLightmap(aSrc, aDst: TBZBitmap; aVO: Byte; aAR, aHR, aHP: Single; ClrLight : TBZColor);
var
pSrcX, pSrcY : PBZColor; //PByte;
pDstX, pDstY : PBZColor;
OutColor, ClrOmbre : TBZColor;
//ClrLight : TBZColor;
x, y, W, H, dZ, Zo, Zr, HR : Integer;
z_step, z_origine, z_rayon: single;
function ControlCouleur(const AC, AX: Byte): Byte; inline;
begin
if (255 - AC) > AX then
Result := (AC + AX)
else
Result := 255;
End;
begin
// dXSrc := aSrc.RawImage.Description.BitsPerPixel div 8;
FStopWatch.Start();
W := aDst.MaxWidth;
H := aDst.MaxHeight;
ClrOmbre.Create(aVo,aVo,aVo);
//ClrLight.Create(79,79,79);
// Calcul du pas en z pour chaque rayon
//z_step := abs(1 / tan(DegToRadian(AAR)));
dz := round( 65280.0*Math.cotan(DegToRadian(aAR))/aHP);
HR := round((65280.0*aHR)/aHP);
aDst.Clear(ClrOmbre);
// Lancement des rayons dans le sens horizontal et de gauche a droite.
Bar.Max := H ;
for y := 0 to H do
begin
Bar.Position := y;
pDstY := aDst.GetScanLine(y);
pSrcY := aSrc.GetScanLine(y);
// Lancements des rayons pour chaque hauteur en remontant suivant l'axe z
//z_origine := 0.0;
Zo := 0;
while Zo < HR do
//while Z_Origine < aHR do
begin // Lancement de rayon.
Zr := Zo;
pSrcX := pSrcY;
pDstX := pDstY;
//z_rayon := z_origine;
for x := 0 to W do
begin
if ((pSrcX^.Red shl 8) >= Zr) then
//if (((pSrcX^.Red * _FloatColorRatio ) * aHP ) >= z_rayon) then
begin
if chkExpMode.Checked then
begin
asm // Exponentielle (mettre ClrLight.int à -1)
mov r8, pDstX // en 1 - e^(-nb_impacts)
pxor xmm0, xmm0
movd xmm2, ClrLight
movd xmm1, [r8]
punpcklbw xmm2, xmm0 // xmm2 = ClrLight en 16 bits
punpcklbw xmm1, xmm0 // xmm1 = pDstXo^ en 16 bits
psubw xmm2, xmm1 // xmm2 = ClrLight-pDstXo^ (par composante)
psraw xmm2, 2 // xmm3 =(ClrLight-pDstXo^)/2^n (par composante)
paddw xmm1, xmm2 // xmm1 = ClrLight+(pDstXo^-ClrLight)/16 (par comp)
packuswb xmm1, xmm0
movd [r8], xmm1
end;
end
else
begin
asm // Linéaire selon nb_impacts
mov r8, pDstX
movd xmm2, ClrLight
movd xmm1, [r8]
paddusb xmm2, xmm1
movd [r8], xmm2
end;
//OutColor.Red := ControlCouleur(pDstX^.Red, ClrLight.Red);
//OutColor.Green := ControlCouleur(pDstX^.Green, ClrLight.Green);
//OutColor.Blue := ControlCouleur(pDstX^.Blue, ClrLight.Blue);
//OutColor.Alpha := 255;
//pDstx^:= OutColor;
end;
break;
End;
inc(pSrcX);
inc(pDstX);
Zr := Zr - dZ;
//z_rayon := z_rayon - z_step;
end;
//z_origine := z_origine + z_step;
Zo := Zo + dZ;
end;
end;
FStopWatch.Stop;
if chkBlur.Checked then FBmpDst.BlurFilter.BoxBlur(Round(spinBlurFactor.Value)); // .GaussianBoxBlur(spinBlurFactor.Value);
pnlViewDest.Invalidate;
Caption := 'Temps : '+FStopWatch.getValueAsMilliSeconds;
Bar.Position := 0;
end; |
Partager