Changeset 10 for trunk/UCore.pas


Ignore:
Timestamp:
Mar 19, 2011, 4:30:27 PM (14 years ago)
Author:
george
Message:
  • Modified: Optimized resampling of bitmap to higher resolution.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UCore.pas

    r8 r10  
    77uses
    88  Dialogs, Classes, SysUtils, Contnrs, Graphics, SpecializedMatrix, SpecializedList,
    9   IntfGraphics, FPImage, LCLType, SpecializedBitmap, GraphType;
     9  IntfGraphics, FPImage, LCLType, SpecializedBitmap, GraphType, Math;
    1010
    1111const
     
    115115  end;
    116116
     117  TFastBitmapPixelComponents = packed record
     118    B, G, R, A: Byte;
     119  end;
     120
    117121const
    118122  SurfaceMatterColors: array[TSurfaceMatter] of TColor = (clBlack, $0756b0,
     
    127131  Engine: TEngine;
    128132
     133function SwapBRComponent(Value: Integer): Integer; inline;
     134
    129135implementation
     136
     137function SwapBRComponent(Value: Integer): Integer;
     138begin
     139//  Result := (Value and $00ff00) or ((Value shr 16) and $ff) or ((Value and $ff) shl 16);
     140  Result := Value;
     141  TFastBitmapPixelComponents(Result).R := TFastBitmapPixelComponents(Value).B;
     142  TFastBitmapPixelComponents(Result).B := TFastBitmapPixelComponents(Value).R;
     143end;
    130144
    131145{ TTank }
     
    635649  I: Integer;
    636650  X, Y: Integer;
    637   H, W: Integer;
    638   Ratio: Single;
     651  PixelX, PixelY: Integer;
     652  SubPixelPtr: PInteger;
     653  SubPixelRowPtr: PInteger;
     654  SubPixelSizeX: Integer;
     655  SubPixelSizeY: Integer;
    639656  PixelPtr: PInteger;
    640657  PixelRowPtr: PInteger;
     658  BytePerPixel: Integer;
     659  BytePerRow: Integer;
    641660  RawImage: TRawImage;
    642   BytePerPixel: Integer;
    643   P: Integer;
    644 begin
    645   if FRedrawPending then begin
    646     FBitmapLower.FillAll(0);
     661  Color: Integer;
     662  Shift: TPoint;
     663  XDiv, XMod, XAcc: Integer;
     664  YDiv, YMod, YAcc: Integer;
     665  Ratio: Real;
     666  TargetHeight: Integer;
     667  TargetWidth: Integer;
     668begin
     669  if FRedrawPending then
     670  begin
     671    FRedrawPending := False;
     672    //FBitmapLower.FillAll(0);
    647673    for I := 0 to Players.Count - 1 do begin
    648674      TPlayer(Players[I]).Paint;
    649675    end;
    650     if Assigned(FBitmap) then try
    651       Bitmap.BeginUpdate(False);
     676    if Assigned(FBitmap) then
     677    try
     678      Bitmap.BeginUpdate;
    652679      RawImage := Bitmap.RawImage;
    653       PixelRowPtr := PInteger(RawImage.Data);
    654680      BytePerPixel := RawImage.Description.BitsPerPixel div 8;
    655       if (IntfImage.Width <> FBitmap.Width) or (IntfImage.Height <> FBitmap.Height) then
    656         IntfImage.SetSize(FBitmap.Width, FBitmap.Height);
     681      BytePerRow := RawImage.Description.BytesPerLine;
     682      FillChar(RawImage.Data^, Bitmap.Height * BytePerRow, 0);
     683
    657684      if (FBitmap.Width / FBitmapLower.Width) < (FBitmap.Height / FBitmapLower.Height) then
    658685        Ratio := FBitmap.Width / FBitmapLower.Width
    659686        else Ratio := FBitmap.Height / FBitmapLower.Height;
    660       for Y := 0 to Trunc(FBitmapLower.Height * Ratio) - 1 do begin
    661         PixelPtr := PixelRowPtr;
    662         for X := 0 to Trunc(FBitmapLower.Width * Ratio) - 1 do begin
    663           P := FBitmapLower.Pixels[Trunc(X / Ratio), Trunc(Y / Ratio)];
    664           PixelPtr^ := ((P and $ff) shl 16) or (P and $00ff00) or ((P shr 16) and $ff);
    665           Inc(PByte(PixelPtr), BytePerPixel);
     687
     688      // Preserve aspect ratio
     689      TargetWidth := Trunc(FBitmapLower.Width * Ratio);
     690      TargetHeight := Trunc(FBitmapLower.Height * Ratio);
     691
     692      Shift.X := Trunc((Bitmap.Width - TargetWidth) / 2);
     693      Shift.Y := Trunc((Bitmap.Height - TargetHeight) / 2);
     694
     695      XDiv := TargetWidth div FBitmapLower.Width;
     696      XMod := TargetWidth mod FBitmapLower.Width;
     697      YDiv := TargetHeight div FBitmapLower.Height;
     698      YMod := TargetHeight mod FBitmapLower.Height;
     699
     700      PixelRowPtr := PInteger(RawImage.Data + BytePerRow * Shift.Y);
     701      YAcc := FBitmapLower.Height div 2;
     702      for Y := 0 to FBitmapLower.Height - 1 do begin
     703        SubPixelSizeY := YDiv;
     704        Inc(YAcc, YMod);
     705        if YAcc >= FBitmapLower.Height then begin
     706          Dec(YAcc, FBitmapLower.Height);
     707          Inc(SubPixelSizeY);
    666708        end;
    667         Inc(PByte(PixelRowPtr), RawImage.Description.BytesPerLine);
     709
     710        PixelPtr := PixelRowPtr + Shift.X;
     711        XAcc := FBitmapLower.Width div 2;
     712        for X := 0 to FBitmapLower.Width - 1 do begin
     713          SubPixelSizeX := XDiv;
     714          Inc(XAcc, XMod);
     715          if XAcc >= FBitmapLower.Width then begin
     716            Dec(XAcc, FBitmapLower.Width);
     717            Inc(SubPixelSizeX);
     718          end;
     719
     720          Color := SwapBRComponent(FBitmapLower.Pixels[X, Y]);
     721
     722          // Draw large pixel
     723          SubPixelRowPtr := PixelPtr;
     724          for PixelY := 0 to SubPixelSizeY - 1 do begin
     725            SubPixelPtr := SubPixelRowPtr;
     726            for PixelX := 0 to SubPixelSizeX - 1 do begin
     727              SubPixelPtr^ := Color;
     728              Inc(PByte(SubPixelPtr), BytePerPixel);
     729            end;
     730            Inc(PByte(SubPixelRowPtr), BytePerRow);
     731          end;
     732          Inc(PByte(PixelPtr), BytePerPixel * SubPixelSizeX);
     733        end;
     734        Inc(PByte(PixelRowPtr), BytePerRow * SubPixelSizeY);
    668735      end;
    669736    finally
    670       FBitmap.EndUpdate(False);
    671     end;
    672     FRedrawPending := False;
     737      FBitmap.EndUpdate;
     738    end;
    673739  end;
    674740end;
Note: See TracChangeset for help on using the changeset viewer.