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
| type
// Quad.......................................//
TxRGB = packed record // Idem TRGB mais étendu à 4 octets
case integer of // composantes.
0 : (Color : TRGBQuad);
1 : (B, G, R, z : Byte); // Ordre z R G B différent de TColor
2 : (int : Integer);
3 : (rgb : TRGBTriple; z3 : byte);
end;
PxRGB = ^TxRGB;
// . . .
//__________________________________________________________________________________________________
procedure TMainForm.DoLightmap(aSrc, aDst: TBitmap; aVO: integer; aAR, aHR, aHP: Single);
var
pSrcX, pSrcY : PByte;
pDstX, pDstY : PxRGB;
ClrOmbre, ClrLight : TxRGB;
dXSrc, dYSrc, dYDst : Integer;
x, y, W, H, dZ, Zo, Zr, HR : Integer;
begin
dXSrc := aSrc.RawImage.Description.BitsPerPixel >> 3;
W := aDst.Width;
H := aDst.Height;
ClrLight.int := Integer($FF4F4F4F);
ClrOmbre.int := -1;
ClrOmbre.R := aVo;
ClrOmbre.G := aVo - (aVo >> 3);
ClrOmbre.B := aVo - (aVo >> 2);
// Calcul du pas en z pour chaque rayon.......//
dZ := round( 65280.0*cotan(DegToRad(aAR))/aHP);
HR := round((65280.0*aHR)/aHP);
aDst.BeginUpdate(False);
dYSrc := aSrc.RawImage.Description.BytesPerLine;
dYDst := aDst.RawImage.Description.BytesPerLine >> 2; // Nbr de points par ligne (4 o/point)
pSrcY := PByte(aSrc.RawImage.GetLineStart(0)); // Pointeurs sur mêmes lignes des bmps
pDstY := PxRGB(aDst.RawImage.GetLineStart(0));
FillDWord(pDstY^, aDst.RawImage.DataSize >> 2, DWORD(ClrOmbre));
// Lancement des rayons dans le sens horizontal et de gauche a droite.
for y := 0 to H - 1 do begin
// Lancements des rayons pour chaque hauteur en remontant suivant l'axe z
Zo := 0;
while Zo < HR do begin // Lancement de rayon.
Zr := Zo;
pSrcX := pSrcY;
pDstX := pDstY;
for x := 0 to W -1 do begin
if Integer(pSrcX^) << 8 >= Zr then begin
//pDstX^ := ClrLight; // Blanc (mettre ClrLight.int à -1)
asm // Linéaire selon nb_impacts
mov r8, pDstX // (mettre ClrLight.int à $FF4F4F4F)
movd xmm2, ClrLight
movd xmm1, [r8]
paddusb xmm2, xmm1
movd [r8], xmm2
end;
// 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;
break;
end;
inc(pSrcX, dXSrc);
inc(pDstX);
Zr -= dZ;
end;
Zo += dZ;
end;
inc(pSrcY, dYSrc);
inc(pDstY, dYDst);
end;
aDst.EndUpdate(True);
end; |