Changeset 472 for GraphicTest/Packages/bgrabitmap/bgrapolygonaliased.pas
- Timestamp:
- Apr 9, 2015, 9:58:36 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/bgrabitmap/bgrapolygonaliased.pas
r452 r472 2 2 3 3 {$mode objfpc}{$H+} 4 5 {$i bgrasse.inc} 4 6 5 7 interface … … 12 14 13 15 uses 14 Classes, SysUtils, BGRABitmapTypes, BGRAFillInfo, BGRA Polygon, BGRASSE;16 Classes, SysUtils, BGRABitmapTypes, BGRAFillInfo, BGRASSE; 15 17 16 18 type … … 29 31 { TPolygonLinearColorGradientInfo } 30 32 31 TPolygonLinearColorGradientInfo = class(T FillPolyInfo)33 TPolygonLinearColorGradientInfo = class(TOnePassFillPolyInfo) 32 34 protected 33 35 FColors: array of TColorF; 36 procedure SetIntersectionValues(AInter: TIntersectionInfo; AInterX: Single; AWinding, 37 ANumSegment: integer; dy: single; AData: pointer); override; 34 38 public 35 39 constructor Create(const points: array of TPointF; const Colors: array of TBGRAPixel); 36 40 function CreateSegmentData(numPt,nextPt: integer; x,y: single): pointer; override; 37 41 function CreateIntersectionInfo: TIntersectionInfo; override; 38 procedure ComputeIntersection(cury: single;39 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;40 42 end; 41 43 … … 61 63 { TPolygonPerspectiveColorGradientInfo } 62 64 63 TPolygonPerspectiveColorGradientInfo = class(T FillPolyInfo)65 TPolygonPerspectiveColorGradientInfo = class(TOnePassFillPolyInfo) 64 66 protected 65 67 FColors: array of TColorF; 66 68 FPointsZ: array of single; 69 procedure SetIntersectionValues(AInter: TIntersectionInfo; AInterX: Single; AWinding, 70 ANumSegment: integer; dy: single; AData: pointer); override; 67 71 public 68 72 constructor Create(const points: array of TPointF; const pointsZ: array of single; const Colors: array of TBGRAPixel); 69 73 function CreateSegmentData(numPt,nextPt: integer; x,y: single): pointer; override; 70 74 function CreateIntersectionInfo: TIntersectionInfo; override; 71 procedure ComputeIntersection(cury: single;72 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;73 75 end; 74 76 … … 96 98 { TPolygonLinearTextureMappingInfo } 97 99 98 TPolygonLinearTextureMappingInfo = class(T FillPolyInfo)100 TPolygonLinearTextureMappingInfo = class(TOnePassFillPolyInfo) 99 101 protected 100 102 FTexCoords: array of TPointF; 101 103 FLightnesses: array of Word; 104 procedure SetIntersectionValues(AInter: TIntersectionInfo; AInterX: Single; AWinding, 105 ANumSegment: integer; dy: single; AData: pointer); override; 102 106 public 103 107 constructor Create(const points: array of TPointF; const texCoords: array of TPointF); … … 105 109 function CreateSegmentData(numPt,nextPt: integer; x,y: single): pointer; override; 106 110 function CreateIntersectionInfo: TIntersectionInfo; override; 107 procedure ComputeIntersection(cury: single;108 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;109 111 end; 110 112 … … 140 142 { TPolygonPerspectiveTextureMappingInfo } 141 143 142 TPolygonPerspectiveTextureMappingInfo = class(T FillPolyInfo)144 TPolygonPerspectiveTextureMappingInfo = class(TOnePassFillPolyInfo) 143 145 protected 144 146 FTexCoords: array of TPointF; 145 147 FPointsZ: array of single; 146 148 FLightnesses: array of Word; 149 procedure SetIntersectionValues(AInter: TIntersectionInfo; AInterX: Single; AWinding, 150 ANumSegment: integer; dy: single; AData: pointer); override; 147 151 public 148 152 constructor Create(const points: array of TPointF; const pointsZ: array of single; const texCoords: array of TPointF); … … 150 154 function CreateSegmentData(numPt,nextPt: integer; x,y: single): pointer; override; 151 155 function CreateIntersectionInfo: TIntersectionInfo; override; 152 procedure ComputeIntersection(cury: single;153 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;154 156 end; 155 157 156 158 { TPolygonPerspectiveMappingShaderInfo } 157 159 158 TPolygonPerspectiveMappingShaderInfo = class(T FillPolyInfo)160 TPolygonPerspectiveMappingShaderInfo = class(TOnePassFillPolyInfo) 159 161 protected 160 162 FTexCoords: array of TPointF; 161 163 FPositions3D, FNormals3D: array of TPoint3D_128; 164 procedure SetIntersectionValues(AInter: TIntersectionInfo; AInterX: Single; AWinding, 165 ANumSegment: integer; dy: single; AData: pointer); override; 162 166 public 163 167 constructor Create(const points: array of TPointF; const points3D: array of TPoint3D; const normals: array of TPoint3D; const texCoords: array of TPointF); … … 165 169 function CreateSegmentData(numPt,nextPt: integer; x,y: single): pointer; override; 166 170 function CreateIntersectionInfo: TIntersectionInfo; override; 167 procedure ComputeIntersection(cury: single;168 var inter: ArrayOfTIntersectionInfo; var nbInter: integer); override;169 171 end; 170 172 … … 192 194 { Aliased round rectangle } 193 195 procedure BGRARoundRectAliased(dest: TBGRACustomBitmap; X1, Y1, X2, Y2: integer; 194 DX, DY: integer; BorderColor, FillColor: TBGRAPixel; FillTexture: IBGRAScanner = nil); 196 DX, DY: integer; BorderColor, FillColor: TBGRAPixel; FillTexture: IBGRAScanner = nil; ADrawMode: TDrawMode = dmDrawWithTransparency; 197 skipFill: boolean = false); 195 198 196 199 implementation … … 199 202 200 203 { TPolygonPerspectiveColorGradientInfo } 204 205 procedure TPolygonPerspectiveColorGradientInfo.SetIntersectionValues( 206 AInter: TIntersectionInfo; AInterX: Single; AWinding, ANumSegment: integer; 207 dy: single; AData: pointer); 208 var 209 info: PPerspectiveColorInfo; 210 begin 211 AInter.SetValues(AInterX,AWinding,ANumSegment); 212 info := PPerspectiveColorInfo(AData); 213 TPerspectiveColorGradientIntersectionInfo(AInter).coordInvZ := dy*info^.InvZSlope + info^.InvZ; 214 TPerspectiveColorGradientIntersectionInfo(AInter).ColorDivZ := info^.ColorDivZ + info^.ColorSlopesDivZ*dy; 215 end; 201 216 202 217 constructor TPolygonPerspectiveColorGradientInfo.Create( … … 266 281 end; 267 282 268 procedure TPolygonPerspectiveColorGradientInfo.ComputeIntersection(269 cury: single; var inter: ArrayOfTIntersectionInfo; var nbInter: integer);270 var271 j: integer;272 dy: single;273 info: PPerspectiveColorInfo;274 begin275 if length(FSlices)=0 then exit;276 277 while (cury < FSlices[FCurSlice].y1) and (FCurSlice > 0) do dec(FCurSlice);278 while (cury > FSlices[FCurSlice].y2) and (FCurSlice < high(FSlices)) do inc(FCurSlice);279 with FSlices[FCurSlice] do280 if (cury >= y1) and (cury <= y2) then281 begin282 for j := 0 to nbSegments-1 do283 begin284 dy := cury - segments[j].y1;285 inter[nbinter].interX := dy * segments[j].slope + segments[j].x1;286 inter[nbinter].winding := segments[j].winding;287 info := PPerspectiveColorInfo(segments[j].data);288 TPerspectiveColorGradientIntersectionInfo(inter[nbinter]).coordInvZ := dy*info^.InvZSlope + info^.InvZ;289 TPerspectiveColorGradientIntersectionInfo(inter[nbinter]).ColorDivZ := info^.ColorDivZ + info^.ColorSlopesDivZ*dy;290 Inc(nbinter);291 end;292 end;293 end;294 295 283 { TPolygonLinearColorGradientInfo } 284 285 procedure TPolygonLinearColorGradientInfo.SetIntersectionValues( 286 AInter: TIntersectionInfo; AInterX: Single; AWinding, ANumSegment: integer; 287 dy: single; AData: pointer); 288 var 289 info: PLinearColorInfo; 290 begin 291 AInter.SetValues(AInterX,AWinding,ANumSegment); 292 info := PLinearColorInfo(AData); 293 TLinearColorGradientIntersectionInfo(AInter).color := info^.Color + info^.ColorSlopes*dy; 294 end; 296 295 297 296 constructor TPolygonLinearColorGradientInfo.Create( … … 343 342 begin 344 343 Result:= TLinearColorGradientIntersectionInfo.Create; 345 end;346 347 procedure TPolygonLinearColorGradientInfo.ComputeIntersection(cury: single;348 var inter: ArrayOfTIntersectionInfo; var nbInter: integer);349 var350 j: integer;351 dy: single;352 info: PLinearColorInfo;353 begin354 if length(FSlices)=0 then exit;355 356 while (cury < FSlices[FCurSlice].y1) and (FCurSlice > 0) do dec(FCurSlice);357 while (cury > FSlices[FCurSlice].y2) and (FCurSlice < high(FSlices)) do inc(FCurSlice);358 with FSlices[FCurSlice] do359 if (cury >= y1) and (cury <= y2) then360 begin361 for j := 0 to nbSegments-1 do362 begin363 dy := cury - segments[j].y1;364 inter[nbinter].interX := dy * segments[j].slope + segments[j].x1;365 inter[nbinter].winding := segments[j].winding;366 info := PLinearColorInfo(segments[j].data);367 TLinearColorGradientIntersectionInfo(inter[nbinter]).color := info^.Color + info^.ColorSlopes*dy;368 Inc(nbinter);369 end;370 end;371 344 end; 372 345 … … 389 362 r,g,b,a: integer; 390 363 end; 391 {$IFDEF CPUI386} c: TBGRAPixel; {$ENDIF}364 {$IFDEF BGRASSE_AVAILABLE} c: TBGRAPixel; {$ENDIF} 392 365 begin 393 366 t := ((ix1+0.5)-x1)/(x2-x1); … … 396 369 pdest := bmp.ScanLine[yb]+ix1; 397 370 398 {$IFDEF CPUI386} {$asmmode intel}371 {$IFDEF BGRASSE_AVAILABLE} {$asmmode intel} 399 372 If UseSSE then 400 373 begin … … 499 472 { TPolygonLinearTextureMappingInfo } 500 473 474 procedure TPolygonLinearTextureMappingInfo.SetIntersectionValues( 475 AInter: TIntersectionInfo; AInterX: Single; AWinding, ANumSegment: integer; 476 dy: single; AData: pointer); 477 var 478 info: PLinearTextureInfo; 479 begin 480 AInter.SetValues(AInterX,AWinding,ANumSegment); 481 info := PLinearTextureInfo(AData); 482 TLinearTextureMappingIntersectionInfo(AInter).texCoord := info^.TexCoord + info^.TexCoordSlopes*dy; 483 if FLightnesses<>nil then 484 TLinearTextureMappingIntersectionInfo(AInter).lightness := round(info^.lightness + info^.lightnessSlope*dy) 485 else 486 TLinearTextureMappingIntersectionInfo(AInter).lightness := 32768; 487 end; 488 501 489 constructor TPolygonLinearTextureMappingInfo.Create(const points: array of TPointF; 502 490 const texCoords: array of TPointF); … … 585 573 begin 586 574 result := TLinearTextureMappingIntersectionInfo.Create; 587 end;588 589 procedure TPolygonLinearTextureMappingInfo.ComputeIntersection(cury: single;590 var inter: ArrayOfTIntersectionInfo; var nbInter: integer);591 var592 j: integer;593 dy: single;594 info: PLinearTextureInfo;595 begin596 if length(FSlices)=0 then exit;597 598 while (cury < FSlices[FCurSlice].y1) and (FCurSlice > 0) do dec(FCurSlice);599 while (cury > FSlices[FCurSlice].y2) and (FCurSlice < high(FSlices)) do inc(FCurSlice);600 with FSlices[FCurSlice] do601 if (cury >= y1) and (cury <= y2) then602 begin603 for j := 0 to nbSegments-1 do604 begin605 dy := cury - segments[j].y1;606 inter[nbinter].interX := dy * segments[j].slope + segments[j].x1;607 inter[nbinter].winding := segments[j].winding;608 info := PLinearTextureInfo(segments[j].data);609 TLinearTextureMappingIntersectionInfo(inter[nbinter]).texCoord := info^.TexCoord + info^.TexCoordSlopes*dy;610 if FLightnesses<>nil then611 TLinearTextureMappingIntersectionInfo(inter[nbinter]).lightness := round(info^.lightness + info^.lightnessSlope*dy)612 else613 TLinearTextureMappingIntersectionInfo(inter[nbinter]).lightness := 32768;614 Inc(nbinter);615 end;616 end;617 575 end; 618 576 … … 637 595 z,invZ,InvZStep: single; 638 596 r,g,b,a: integer; 639 {$IFDEF CPUI386}minVal,maxVal: single;597 {$IFDEF BGRASSE_AVAILABLE}minVal,maxVal: single; 640 598 cInt: packed record 641 599 r,g,b,a: integer; … … 657 615 {$DEFINE PARAM_USEZBUFFER} 658 616 zbufferpos := zbuffer + yb*bmp.Width + ix1; 659 {$IFDEF CPUI386}617 {$IFDEF BGRASSE_AVAILABLE} 660 618 If UseSSE then 661 619 begin … … 679 637 end else 680 638 begin 681 {$IFDEF CPUI386}639 {$IFDEF BGRASSE_AVAILABLE} 682 640 If UseSSE then 683 641 begin … … 846 804 {From LazRGBGraphics} 847 805 procedure BGRARoundRectAliased(dest: TBGRACustomBitmap; X1, Y1, X2, Y2: integer; 848 DX, DY: integer; BorderColor, FillColor: TBGRAPixel; FillTexture: IBGRAScanner = nil); 806 DX, DY: integer; BorderColor, FillColor: TBGRAPixel; FillTexture: IBGRAScanner = nil; ADrawMode: TDrawMode = dmDrawWithTransparency; 807 skipFill: boolean = false); 849 808 var 850 809 CX, CY, CX1, CY1, A, B, NX, NY: single; … … 858 817 LX, LY: integer; 859 818 RowStart,RowEnd: integer; 860 eBorderColor,eFillColor: TExpandedPixel; 819 PixelProc: procedure (x, y: int32or64; c: TBGRAPixel) of object; 820 skipBorder: boolean; 861 821 862 822 procedure AddEdge(X, Y: integer); … … 891 851 Dec(y2); 892 852 893 eBorderColor := GammaExpansion(BorderColor);894 eFillColor := GammaExpansion(FillColor);895 896 853 if (X1 = X2) and (Y1 = Y2) then 897 854 begin 898 dest.DrawPixel(X1, Y1, eBorderColor);855 dest.DrawPixel(X1, Y1, BorderColor, ADrawMode); 899 856 Exit; 900 857 end; … … 902 859 if (X2 - X1 = 1) or (Y2 - Y1 = 1) then 903 860 begin 904 dest.FillRect(X1, Y1, X2 + 1, Y2 + 1, BorderColor, dmDrawWithTransparency);861 dest.FillRect(X1, Y1, X2 + 1, Y2 + 1, BorderColor, ADrawMode); 905 862 Exit; 906 863 end; … … 908 865 if (LX > X2 - X1) or (LY > Y2 - Y1) then 909 866 begin 910 dest.Rectangle(X1, Y1, X2 + 1, Y2 + 1, BorderColor, dmDrawWithTransparency); 911 if FillTexture <> nil then 912 dest.FillRect(X1 + 1, Y1 + 1, X2, Y2, FillTexture, dmDrawWithTransparency) else 913 dest.FillRect(X1 + 1, Y1 + 1, X2, Y2, FillColor, dmDrawWithTransparency); 867 dest.Rectangle(X1, Y1, X2 + 1, Y2 + 1, BorderColor, ADrawMode); 868 if not skipFill then 869 if FillTexture <> nil then 870 dest.FillRect(X1 + 1, Y1 + 1, X2, Y2, FillTexture, ADrawMode) else 871 dest.FillRect(X1 + 1, Y1 + 1, X2, Y2, FillColor, ADrawMode); 914 872 Exit; 915 873 end; … … 977 935 end; 978 936 937 case ADrawMode of 938 dmSetExceptTransparent: begin PixelProc := @dest.SetPixel; skipBorder:= BorderColor.alpha <> 255; end; dmDrawWithTransparency: begin PixelProc := @dest.DrawPixel; skipBorder:= BorderColor.alpha = 0; end; 939 dmXor: begin PixelProc := @dest.XorPixel; skipBorder:= DWord(BorderColor) = 0; end; 940 dmLinearBlend: begin PixelProc := @dest.FastBlendPixel; skipBorder:= BorderColor.alpha = 0; end; 941 else 942 begin PixelProc := @dest.SetPixel; skipBorder := false; end; 943 end; 944 979 945 J := 0; 980 946 while J < Length(EdgeList) do … … 982 948 if (J = 0) and (Frac(CY) > 0) then 983 949 begin 950 if not skipBorder then 984 951 for I := EdgeList[J].X to EdgeList[J].Y do 985 952 begin 986 dest.DrawPixel(Floor(CX) + I, Floor(CY) + J, eBorderColor);987 dest.DrawPixel(Ceil(CX) - Succ(I), Floor(CY) + J, eBorderColor);953 PixelProc(Floor(CX) + I, Floor(CY) + J, BorderColor); 954 PixelProc(Ceil(CX) - Succ(I), Floor(CY) + J, BorderColor); 988 955 end; 989 956 990 if FillTexture <> nil then 991 dest.DrawHorizLine(Ceil(CX) - EdgeList[J].X, Floor(CY) + J, Floor(CX) + 992 Pred(EdgeList[J].X), FillTexture) else 993 dest.DrawHorizLine(Ceil(CX) - EdgeList[J].X, Floor(CY) + J, Floor(CX) + 994 Pred(EdgeList[J].X), eFillColor); 957 if not SkipFill then 958 if FillTexture <> nil then 959 dest.HorizLine(Ceil(CX) - EdgeList[J].X, Floor(CY) + J, Floor(CX) + 960 Pred(EdgeList[J].X), FillTexture, ADrawMode) else 961 dest.HorizLine(Ceil(CX) - EdgeList[J].X, Floor(CY) + J, Floor(CX) + 962 Pred(EdgeList[J].X), FillColor, ADrawMode); 995 963 end 996 964 else … … 1002 970 S := -Succ(EdgeList[J].Y); 1003 971 972 if not skipBorder then 1004 973 for I := S to EdgeList[J].Y do 1005 974 begin 1006 dest.DrawPixel(Floor(CX) + I, Floor(CY) + J, eBorderColor);1007 dest.DrawPixel(Floor(CX) + I, Ceil(CY) - Succ(J), eBorderColor);975 PixelProc(Floor(CX) + I, Floor(CY) + J, BorderColor); 976 PixelProc(Floor(CX) + I, Ceil(CY) - Succ(J), BorderColor); 1008 977 end; 1009 978 end 1010 979 else 1011 980 begin 981 if not skipBorder then 1012 982 for I := EdgeList[J].X to EdgeList[J].Y do 1013 983 begin 1014 dest.DrawPixel(Floor(CX) + I, Floor(CY) + J, eBorderColor);1015 dest.DrawPixel(Floor(CX) + I, Ceil(CY) - Succ(J), eBorderColor);984 PixelProc(Floor(CX) + I, Floor(CY) + J, BorderColor); 985 PixelProc(Floor(CX) + I, Ceil(CY) - Succ(J), BorderColor); 1016 986 if Floor(CX) + I <> Ceil(CX) - Succ(I) then 1017 987 begin 1018 dest.DrawPixel(Ceil(CX) - Succ(I), Floor(CY) + J, eBorderColor);1019 dest.DrawPixel(Ceil(CX) - Succ(I), Ceil(CY) - Succ(J), eBorderColor);988 PixelProc(Ceil(CX) - Succ(I), Floor(CY) + J, BorderColor); 989 PixelProc(Ceil(CX) - Succ(I), Ceil(CY) - Succ(J), BorderColor); 1020 990 end; 1021 991 end; 1022 992 1023 RowStart := Ceil(CX) - EdgeList[J].X;1024 RowEnd := Floor(CX) + Pred(EdgeList[J].X);1025 if RowEnd >= RowStart then1026 begin1027 if FillTexture <> nilthen993 if not SkipFill then 994 begin 995 RowStart := Ceil(CX) - EdgeList[J].X; 996 RowEnd := Floor(CX) + Pred(EdgeList[J].X); 997 if RowEnd >= RowStart then 1028 998 begin 1029 dest.DrawHorizLine(RowStart, Floor(CY) + J, 1030 RowEnd, FillTexture); 1031 dest.DrawHorizLine(RowStart, Ceil(CY) - Succ(J), 1032 RowEnd, FillTexture); 1033 end else 1034 begin 1035 dest.DrawHorizLine(RowStart, Floor(CY) + J, 1036 RowEnd, eFillColor); 1037 dest.DrawHorizLine(RowStart, Ceil(CY) - Succ(J), 1038 RowEnd, eFillColor); 999 if FillTexture <> nil then 1000 begin 1001 dest.HorizLine(RowStart, Floor(CY) + J, 1002 RowEnd, FillTexture, ADrawMode); 1003 dest.HorizLine(RowStart, Ceil(CY) - Succ(J), 1004 RowEnd, FillTexture, ADrawMode); 1005 end else 1006 begin 1007 dest.HorizLine(RowStart, Floor(CY) + J, 1008 RowEnd, FillColor, ADrawMode); 1009 dest.HorizLine(RowStart, Ceil(CY) - Succ(J), 1010 RowEnd, FillColor, ADrawMode); 1011 end; 1039 1012 end; 1040 1013 end; 1014 1041 1015 end; 1042 1016 Inc(J);
Note:
See TracChangeset
for help on using the changeset viewer.