Code archives/Graphics/Correct Filled Polygon
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
![]() A quick and dirty way of building a filled polygon where FillPoly() provided by BlitzMAX makes a mess of it for concave angles. Does not require any additional libs, dlls, or mods. Any questions or comments, especially about the BlitzMAX commands or functions used in this code, please address them below. | |||||
' ___________________________________________
' // //
' // "Perfect" Filled Polygon //
' // Written by David W (dw817) 01/12/16 //
'//________________________________________//
' What's up ?? Added boundary check, thanks to Bobysait
Strict
SetGraphicsDriver(GLMax2DDriver()) ' no problems w intensive pixel reading
Graphics 640,480
SetBlend alphablend ' allow for transparency
Global vec$="3U^jV\lf]7RGN3P" ' all vector images are in 8x8 grid
Global typ
typ=0
' 0 (zero) to use my polygon plotter
' 1 (one) to use BlitzMAX's own flawed plotter
If typ=0 Then drawvec vec$
If typ=1 Then drawvec2 vec$
Flip
WaitKey
Function drawvec(t$)
Local x,y,x2,y2,p,a,i,j,k,m,z=Len(t$),ok,pic:TPixmap
For p=1 To z
a=Asc(Mid$(t$,p))-40 ' pull out a vector
x=a Mod 9*16 ' retrieve horizontal
y=a/9*16 ' retrieve vertical
If p>1 And p<z ' if not first iteration nor last, draw vector
DrawLine x2,y2,x,y
ElseIf p=z ' last iteration, let's do our fill
pic=GrabPixmap(0,0,128,128) ' grab image for massive pixel updates
WritePixel pic,x,y+8,$fffffffe ' +8 as paint vector falls on existing edge
' needs to be $fe to differentiate between edges that are $ff
Repeat
ok=1 ' flag that no changes have been made
For i=0 To 127 ' field of 8x8 grid, snap on 16
For j=0 To 127
If j+m>=0 And i+k>=0 ' confirm within range of screen
If ReadPixel(pic,j,i)=$fffffffe ' found our paint pixel
For k=-1 To 1
For m=-1 To 1
If j+m>=0 And i+k>=0 And j+m<=127 And i+k<=127 ' confirm within ange
If ReadPixel(pic,j+m,i+k)=$ff000000 And(k=0 Or m=0) ' ensure search is cross and not square
WritePixel pic,j+m,i+k,$fffffffe ' it's empty so fill it in
ok=0 ' flag for cannot exit just yet
EndIf
EndIf
Next
Next
EndIf
EndIf
Next
Next
Until ok ' no changes above means we're finally done
DrawPixmap pic,0,0 ' draw back the changes
EndIf
x2=x
y2=y
Next
EndFunction
Function drawvec2(t$) ' System's own polygon plotter
Local vec#[Len(t$)*2],a,i
For i=1 To Len(t$)
a=Asc(Mid$(t$,i))-40
vec#[i*2-2]=a Mod 9*16+20 ' store X
vec#[i*2-1]=a/9*16+20 ' store Y
Next
DrawPoly vec# ' use system's own plotter, flawed
EndFunction |
Comments
| ||
| Why pix-mapping it? I've the code to draw filled textured polygons with native openGL/DirectX functions. |
| ||
| I won't comment on the "writepixel" method, it can be usefull for writing concave polygons to textures. I just will mention this :
for i=1 To Len(t$)
a=Asc(Mid$(t$,i))-40
[...]
you'll get a more user-friendly syntax (and improved performances) by using the byte buffer attached to the string. For i = 0 Until t.length a = t[i] - 40; Next This will give the same result. ps : BTW, your code won't compile on debug because you try to write pixel outside of the pixmap range. For j = 0 to 127 For m = -1 to 1 ReadPixel(pic,j+m,i+k) -> your "j+m" so as the "i+k" coordinates are in the range [-1, 128] and it will crash on debug mode. |
| ||
| This is the ear-clipping method for filling a concave polygon It should computes polygons fast enough to be used in realtime. |
| ||
| Ok ... I am finally understanding what is going on here. You are taking my polygon image and 'shaping' it so the flawed DrawPoly() can finally draw it the correct way. You are essentially adding crutches, and - if that's what is needed. Quite a bit of work - nice job of that ! :) As for the coordinates, yes - I need to add a check boundaries. Corrected - Code Updated |
Code Archives Forum
