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