This isn't so much a game question as a graphics question. Could someone suggest an efficient method to produce geometry (I hope this can be done in terms of geometry and not pixels) for thick curved lines like Photoshop and Flash can draw?
My current approach is to create a triangle strip following the curve but at large thickness + quick direction changes, it produces very ugly artifacts as the vertex sets on either side of the curve overlap other nearby vertex sets.
Rendering thick curved lines
- netmaestro
- PureBasic Bullfrog

- Posts: 8452
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
I apologize for the sloppy coding, I just threw this together. It's taking 2.5 milliseconds on average here to render a curve 10 pixels wide on the 640*480 screen. If 2.5 ms is fast enough for your purposes, this should work:
Code: Select all
OpenLibrary(1, "msimg32.dll")
CreateImage(0, 640,480,32)
Macro ARGB(RGB=0,Transparency=255) ; by einander
Blue(RGB)|Green(RGB)<<8|Red(RGB)<<16|Transparency<<24
EndMacro
Structure POINTF
x.f
y.f
EndStructure
Global Dim PointArray.POINTF(100)
For i=0 To 100
PointArray(i)\x = 30*i+0.5*i
pointArray(i)\y = 50+i*1.1*i
Next
Global *token, *surface, *redpen5
CompilerIf Defined(GdiplusStartupInput, #PB_Structure) = 0
Structure GdiplusStartupInput
GdiPlusVersion.l
*DebugEventCallback.Debug_Event
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
CompilerEndIf
Procedure DrawCurve()
hdc = StartDrawing(ImageOutput(0))
Box(0,0,640,480,#Black)
CallFunction(0, "GdipCreateFromHDC", hdc, @*surface)
CallFunction(0, "GdipDrawCurve", *surface, *redpen5, PointArray(), 100)
CallFunction(0, "GdipDeleteGraphics", *surface)
StopDrawing()
dc = GetWindowDC_(#Null)
imagedc = CreateCompatibleDC_(dc)
SelectObject_(imagedc, ImageID(0))
hdc = StartDrawing(ScreenOutput())
CallFunction(1, "TransparentBlt", hdc, 0, 0, 640,480, imagedc, 0, 0, 640,480,0)
StopDrawing()
ReleaseDC_(0, dc)
DeleteDC_(imagedc)
EndProcedure
input.GdiplusStartupInput
input\GdiPlusVersion = 1
OpenLibrary(0, "gdiplus.dll")
CallFunction(0, "GdiplusStartup", @*token, @input, #Null)
CallFunction(0, "GdipCreatePen1", ARGB(#Red, 180), 10.0, 2, @*redpen5)
InitSprite()
OpenWindow(0,0,0,640,480,"gdiplus curves",$CA0001)
OpenWindowedScreen(WindowID(0), 0,0,640,480,0,0,0)
Repeat
EventID = WindowEvent()
ClearScreen(#Black)
DrawCurve()
FlipBuffers()
Delay(1)
Until EventID = #WM_CLOSE
CallFunction(0, "GdipDeletePen", *redpen5)
CallFunction(0, "GdiplusShutdown", *token)
CloseLibrary(0)
CloseLibrary(1)
Last edited by netmaestro on Sat Aug 11, 2007 3:36 am, edited 2 times in total.
BERESHEIT
-
Antithesis
- New User

- Posts: 5
- Joined: Sat Aug 04, 2007 3:39 pm
- netmaestro
- PureBasic Bullfrog

- Posts: 8452
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
- Kaeru Gaman
- Addict

- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
I have no idea how "thick curved lines like Photoshop and Flash can draw" look,
but I would suggest using a circle to plot.
like this:
the rounded shape of the circle keeps the artifacts low.
[edit]
if you want some lightning-effekt, use a sprite.
take this one
and save it as a BMP in the same directory you saved the demo-code.
but I would suggest using a circle to plot.
like this:
Code: Select all
InitSprite()
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Plot")
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)
radius = 7
StartDrawing(ScreenOutput())
For n=-radius To 639+radius
x.f = n
y.f = 240 + 200 * Sin(x/40)
Circle(x,y,7,$F0A040)
Next
StopDrawing()
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow[edit]
if you want some lightning-effekt, use a sprite.
take this one
and save it as a BMP in the same directory you saved the demo-code.
Code: Select all
InitSprite()
OpenWindow(0, #PB_Ignore, #PB_Ignore, 640, 480, "Plot")
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)
TransparentSpriteColor(-1,0)
LoadSprite(0,"ball.bmp")
radius = 7
For n=-radius To 639+radius
x.f = n
y.f = 240 + 200 * Sin(x/40)
DisplayTransparentSprite(0,x-radius,y-radius)
Next
FlipBuffers()
Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindowoh... and have a nice day.