Codesnippets > 2D-snippets

Very fast floodfill

(1/6) > >>

fuzzy70:
No idea what site the algorithm came from but found it as a text file on my HD, all I do know was it was a very long time ago so I just converted the pseudo code into a GLB function using types & MEM2SPRITE etc.

I made it so it can be used for floodfills on a whole screen or just a sprite & even on my lowly system its very very quick (millsecs rather than seconds  =D )

Lee


--- Code: (glbasic) ---// --------------------------------- //
// Project: fastfloodfill
// Start: Wednesday, October 31, 2012
// IDE Version: 10.283


// FREE-VERSION:
// Need Premium for Features:
// 3D Graphics
// Network Commands
// INLINE C/C+++ code

SETCURRENTDIR("Media") // go to media files
SETSCREEN 800,600,0
SYSTEMPOINTER TRUE
SEEDRND GETTIMERALL()

TYPE Fillpixel
x%
y%
ENDTYPE

GLOBAL pixels%[]

LOCAL mx%,my%,b1%,b2%,col%,sx%,sy%

GETSCREENSIZE sx,sy

LOADSPRITE "grab.png",0 // Load an image as CBA to write a filled circle function at present to test non-square borders ;)
//GRABSPRITE 0,0,0,sx,sy
REPEAT
MOUSESTATE mx, my, b1, b2
IF MOUSEAXIS(3)
col = RGB(255,255,255)
FillFast(mx,my,sx,sy,col,0)
ENDIF
DRAWSPRITE 0,0,0
SHOWSCREEN
UNTIL KEY(57)
END


FUNCTION FillFast: startx%,starty%,width%,height%,fillcol%,id%

LOCAL i[]  AS Fillpixel
LOCAL newi AS Fillpixel
LOCAL newx%,newy%,dir%
LOCAL fillover%,fillcolour%
LOCAL fillmap%[]
LOCAL red%,green%,blue%,alpha%

IF startx<0 OR starty<0 OR startx>=width% OR starty>=height
DEBUG "Out of area."
RETURN
        ENDIF

SPRITE2MEM (pixels[],id)

// Convert the fill colour to SPRITEMEM format.
fillcolour=bOR(fillcol, ASL(255, 24))

// Get the colour that will be filled over.
red=bAND(pixels[startx+starty*width%], 0xff)
green=bAND(ASR(pixels[startx+starty*width%],8), 0xff)
blue=bAND(ASR(pixels[startx+starty*width%],16), 0xff)
alpha=bAND(ASR(pixels[startx+starty*width%],24), 0xff)
fillover=bOR(RGB(red,green,blue), ASL(alpha, 24))

// If the fill pixel is same colour as then abort.
IF fillover=fillcolour THEN RETURN

// Set the start position.
newi.x=startx
newi.y=starty
pixels[startx+starty*width%]=fillcolour
DIMPUSH i[],newi

// Reset the fill check map.
DIM fillmap[width%][height]
fillmap[startx][starty]=1

FOREACH pixel IN i[]

// New test position based on the direction.
FOR dir=0 TO 3

SELECT dir

CASE 0 // Right
newx=pixel.x+1
newy=pixel.y
CASE 1 // Down
newx=pixel.x
newy=pixel.y+1
CASE 2 // Left
newx=pixel.x-1
newy=pixel.y
CASE 3 // Up
newx=pixel.x
newy=pixel.y-1
ENDSELECT


IF newx>=0 AND newy>=0 AND newx<width% AND newy<height // Make sure the new position is in the boundaries of the screen/sprite.
IF fillmap[newx][newy]=0 // If not already checked continue
fillmap[newx][newy]=1 // Flag this pixel as now checked
IF pixels[newx+newy*width%]=fillover // Check pixel colour is the correct fill over colour.
pixels[newx+newy*width%]=fillcolour // Fill and make a new pixel.
newi.x=newx
newi.y=newy
DIMPUSH i[],newi
ENDIF
ENDIF
ENDIF
NEXT
DELETE pixel // Remove pixel from list
NEXT

MEM2SPRITE (pixels[],id,width%,height)

DIM fillmap[0][0]
ENDFUNCTION

--- End code ---
   

[attachment deleted by admin]

Hemlos:
very awesome, love it..

to use this with other size images you need to use this:

GETSPRITESIZE 0,sx,sy

fuzzy70:
Originally I just made it for full screen fills then decided to add a width & height parameters to the function to give it a bit more flexibility.

Glad you like it :)).

Next step is gradient fills but don't hold your breath lol

Lee

Sent from my GT-I5700 using Tapatalk 2

Hemlos:
Cool stuff  :good:

The reason you need to use the sprite size is because the program will crash if the sprite is smaller than the screensize.

Perhaps theres is another solution you can work into the original algorithm.

fuzzy70:
I think the algorithm is not a problem, perhaps more checks in the function for sizes passed to it or similar may be required.

Will play around later when back home.

Lee

Btw thanks for moving it to the correct location ^-^
Sent from my GT-I5700 using Tapatalk 2

Navigation

[0] Message Index

[#] Next page

Go to full version