Results 1 to 2 of 2

Thread: Speeding up a rotate/alpha routine

  1. #1
    Co-Founder / PGD Elder WILL's Avatar
    Join Date
    Apr 2003
    Location
    Canada
    Posts
    6,107
    Blog Entries
    25

    Speeding up a rotate/alpha routine

    ok boys, here's the code. I have yet to find a ay of increading the speed on this bad-boy beyond using the cos/sin lookup tables and moving the

    [pascal] RX := SX - OX;
    RY := SY - OY;
    NX := Round(mx + RX * aSin + RY * aCos); //
    NY := Round(my + RY * aSin - RX * aCos); //[/pascal]
    portion inside of the

    [pascal] if ((DX > 0) and (DX < MAXX)) and
    ((DY > 0) and (DY < MAXY)) then
    begin[/pascal]
    conditional statement.



    Have a look and let me know what you think:

    [pascal]procedure SDL_RotateDeg_Alpha3(DstSurface, SrcSurface: PSDL_Surface; SrcRect: PSDL_Rect;
    DestX, DestY, OffsetX, OffsetY: Integer; Angle: Integer;
    Alpha: UInt;
    var
    aSin, aCos: Single;
    MX, MY, DX, DY, NX, NY, SX, SY, OX, OY, Width, Height, TX, TY, RX, RY, ROX, ROY: Integer;
    SrcColor, DstColor: UInt32;
    srcRR, srcGG, srcBB, dstRR, dstGG, dstBB: UInt8;
    Color, TempTransparentColour: UInt32;
    MAXX, MAXY: Integer;

    begin
    // Rotate the surface to the target surface.
    TempTransparentColour := SrcSurface.format.colorkey;
    if (srcRect.w > srcRect.h) then
    begin
    Width := srcRect.w;
    Height := srcRect.w;
    end
    else
    begin
    Width := srcRect.h;
    Height := srcRect.h;
    end;

    maxx := DstSurface.w;
    maxy := DstSurface.h;
    aCos := degCOS[Angle];
    aSin := degSIN[Angle];

    Width := round(abs(srcrect.h * acos) + abs(srcrect.w * asin));
    Height := round(abs(srcrect.h * asin) + abs(srcrect.w * acos));

    OX := Width shr 1;
    OY := Height shr 1;
    MX := (srcRect.x + (srcRect.x + srcRect.w)) shr 1;
    MY := (srcRect.y + (srcRect.y + srcRect.h)) shr 1;
    ROX := (-(srcRect.w shr 1)) + Offsetx;
    ROY := (-(srcRect.h shr 1)) + OffsetY;
    Tx := ox + round(ROX * aSin - ROY * aCos);
    Ty := oy + round(ROY * aSin + ROX * aCos);
    SX := 0;
    for DX := DestX - TX to DestX - TX + (width) do
    begin
    inc(SX);
    SY := 0;
    for DY := DestY - TY to DestY - TY + (Height) do
    begin
    if ((DX > 0) and (DX < MAXX)) and
    ((DY > 0) and (DY < MAXY)) then
    begin
    RX := SX - OX;
    RY := SY - OY;
    NX := mx + Round(RX * aSin + RY * aCos); //
    NY := my + Round(RY * aSin - RX * aCos); //

    // Used for testing only
    //SDL_PutPixel(DestSurface.SDLSurfacePointer,DX,DY,0 );

    if (NX >= srcRect.x) and (NX <= srcRect.x + srcRect.w) then
    begin
    if (NY >= srcRect.y) and (NY <= srcRect.y + srcRect.h) then
    begin
    SrcColor := SDL_GetPixel(SrcSurface, NX, NY);
    if (SrcColor <> TempTransparentColour) then
    begin
    SDL_GetRGB(SrcColor, SrcSurface.format, @srcRR, @srcGG, @srcBB);

    DstColor := SDL_GetPixel(DstSurface, DX, DY);
    SDL_GetRGB(DstColor, DstSurface.format, @dstRR, @dstGG, @dstBB);

    Color := SDL_MapRGB(DstSurface.format,
    Round((Alpha * (srcRR - dstRR)) shr 8 + dstRR),
    Round((Alpha * (srcGG - dstGG)) shr 8 + dstGG),
    Round((Alpha * (srcBB - dstBB)) shr 8 + dstBB));

    SDL_PutPixel(DstSurface, DX, DY, Color);
    end;
    end;
    end;
    end;
    inc(SY);
    end;
    end;
    end;[/pascal]
    Jason McMillen
    Pascal Game Development
    Co-Founder





  2. #2

    Speeding up a rotate/alpha routine

    You should switch X and Y loop places to make memory access more sequential. As rounding is not fast, you could make aSin and aCos into integers (to give them some resolution multiply them by a power of two before rounding and then in loops just use shifts). You should also consider inlineing those SDL functions, and maybe also assume some limitations like not supporting 8bit color.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •