Faster vector graphics
Faster vector graphics
Is it possible to get faster vector graphics? I want to use them in my game running 60 FPS or above and the built in ones are not fast enough. Also I looked into making my own library using DrawingBuffer() but that is also not fast enough since it needs "StartDrawing(ScreenOutput()) which takes 5ms. I don't actually know what the purpose of it is, if you are directly drawing to the screen then you need it to be fast, and if you are not making realtime graphics then there's no need to draw directly to the screen, so it seems pointless to me.
Can 3rd party libraries give faster graphics in PureBasic?
Can 3rd party libraries give faster graphics in PureBasic?
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Faster vector graphics
I've been using the sprite library, and I've been drawing vector graphics to sprites, then drawing the sprites but the anti-aliasing isn't as good as when you draw directly with the vector commands, especially when rotating sprites.
Re: Faster vector graphics
Can you post some demo code that demonstrates what you're trying to achieve but is too slow for your needs?
Re: Faster vector graphics
You can speed up some things by using threads. What I did in a project is this (was vectordrawing on a canvas for a game):
- when you get the data for drawing, don't draw it directly, but instead collect it in a structured list. For example coordinates, thickness ect. of lines/shapes you want to draw.
- in a separate thread, you use this data (or better a copy of it) to draw it on an image.
- while that other thread is drawing the new frame (image), your main thread can display the previously drawn image (swap images, don't recreate of course) in a canvas and can do the other game logic as well as collecting the new data for the new frame.
- these two parallel parts are supposed to overlap, but not outtake each other. So you need to coordinate with semaphores on both sides signaling each other to ensure a strictly alternating order.
- when you get the data for drawing, don't draw it directly, but instead collect it in a structured list. For example coordinates, thickness ect. of lines/shapes you want to draw.
- in a separate thread, you use this data (or better a copy of it) to draw it on an image.
- while that other thread is drawing the new frame (image), your main thread can display the previously drawn image (swap images, don't recreate of course) in a canvas and can do the other game logic as well as collecting the new data for the new frame.
- these two parallel parts are supposed to overlap, but not outtake each other. So you need to coordinate with semaphores on both sides signaling each other to ensure a strictly alternating order.
Re: Faster vector graphics
I will get back to you. I really believe that all the graphics capabilities in PureBasic cannot be used for games except for sprites.pjay wrote: Sat Dec 02, 2023 9:27 am Can you post some demo code that demonstrates what you're trying to achieve but is too slow for your needs?
I tested that out recently and concluded that drawing images was too slow. What frame time did you have? With a 60 hz monitor it is 16 ms, but with a 240hz monitor it's 4 ms. StartDrawing can take up to 1 ms, DrawAlphaImage up to 1 ms and StopDrawing up to 1 ms, that's potentially 3 ms just to draw one image. A modern PC should be able to draw 2D graphics easily at 240 hz.
Re: Faster vector graphics
I wasn't drawing the image myself, I only used SetGadgetAttribute(canvas, #PB_Canvas_Image, ImageID(img)). Not sure what blitting or copying PB does internally.
I looked into my notes of the project and it says that the initial version with those changes wasn't actually faster but a bit slower, so I'm not sure anymore if I gained some speed with additional later optimizations or not.
. My FPS still sucked, but I had a lot of drawing and I have poor hardware, so I guess you would have to see for yourself if it could help in your situation.
I looked into my notes of the project and it says that the initial version with those changes wasn't actually faster but a bit slower, so I'm not sure anymore if I gained some speed with additional later optimizations or not.

Re: Faster vector graphics
Refreshing the images over 60 frames makes no sense, as the brain is slower anyway. Actually, 30 frames is enough for the eye to have a smooth picture. The 4 ms (240 HZ) are only good to prevent the monitor's pixels from glowing.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Faster vector graphics
I respectfully disagree; whilst I agree that 30fps is the generally the minimum needed, my laptop can switch between 60fps and 120fps & the difference in smoothness between the two is still very noticable.
@coco2
I'll always lean towards hardware accelerated options when it comes to realtime graphics applications.
If the sprite library doesn't fulfill your requirements then I'd write some OpenGL code that does the job, abstract it if necessary to make your life easier. I'd imagine even the legacy immediate mode that PB supports natively would be more than sufficient and capable of 100s of frames per second on most modern PCs.
Re: Faster vector graphics
A CanvasGadget is too slow and too calculation intensive.
Example with 30 frames
Example with 30 frames
Code: Select all
;-TOP
#ProgramTitle = "Main Window"
#ProgramVersion = "v1.01.2"
Enumeration Windows
#Main
EndEnumeration
Enumeration MenuBar
#MainMenu
EndEnumeration
Enumeration MenuItems
#MainMenuAbout
#MainMenuExit
EndEnumeration
Enumeration Gadgets
#MainCanvas
EndEnumeration
Enumeration StatusBar
#MainStatusBar
EndEnumeration
UsePNGImageDecoder()
UseJPEGImageDecoder()
Global image1, image2
Procedure LoadResources()
image1 = LoadImage(0, #PB_Compiler_Home + "examples/3d/Data/Textures/flare.png")
image2 = LoadImage(1, #PB_Compiler_Home + "examples/3d/Data/Textures/Lensflare5.jpg")
EndProcedure
Procedure Limit(*Value.integer, Min, Max)
If *Value\i < Min
*Value\i = Min
ElseIf *Value\i >= Max
*Value\i = Max
EndIf
EndProcedure
Procedure FilterCallback(x, y, SourceColor, TargetColor)
If SourceColor > TargetColor
ProcedureReturn SourceColor
Else
ProcedureReturn TargetColor
EndIf
EndProcedure
Procedure RedrawGadget(Gadget)
Static x1, y1, x2, y2, xdir1 = 5, ydir1 = 5, xdir2 = 5, ydir2 = 5
Protected dx, dy
dx = GadgetWidth(Gadget)
dy = GadgetHeight(Gadget)
If StartDrawing(CanvasOutput(Gadget))
If x1 < -100
xdir1 = Random(20,5)
ElseIf x1 > dx - 50
xdir1 = Random(20,5) * -1
EndIf
If y1 < -100
ydir1 = Random(20,5)
ElseIf y1 > dy - 50
ydir1 = Random(20,5) * -1
EndIf
If x2 < -100
xdir2 = Random(20,5)
ElseIf x2 > dx - 50
xdir2 = Random(20,5) * -1
EndIf
If y2 < -100
ydir2 = Random(20,5)
ElseIf y2 > dy - 50
ydir2 = Random(20,5) * -1
EndIf
x1 + xdir1
y1 + ydir1
x2 + xdir2
y2 + ydir2
Box(0, 0, dx, dy, 0)
DrawingMode(#PB_2DDrawing_CustomFilter)
CustomFilterCallback(@FilterCallback())
DrawImage(image2, x2, y2)
DrawImage(image1, x1, y1)
StopDrawing()
EndIf
EndProcedure
Procedure DoEventTimer()
RedrawGadget(0)
EndProcedure
Procedure UpdateWindow()
Protected dx, dy
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
; Resize gadgets
ResizeGadget(#MainCanvas, 0, 0, dx, dy)
EndProcedure
Procedure Main()
Protected dx, dy, time, lasttime
#MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
; Menu
CreateMenu(#MainMenu, WindowID(#Main))
MenuTitle("&File")
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
MenuItem(#PB_Menu_About, "")
CompilerElse
MenuItem(#MainMenuAbout, "About")
CompilerEndIf
; Menu File Items
CompilerIf Not #PB_Compiler_OS = #PB_OS_MacOS
MenuBar()
MenuItem(#MainMenuExit, "E&xit")
CompilerEndIf
; StatusBar
CreateStatusBar(#MainStatusBar, WindowID(#Main))
AddStatusBarField(#PB_Ignore)
; Gadgets
dx = WindowWidth(#Main)
dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
CanvasGadget(0, 0, 0, dx, dy, #PB_Canvas_Border)
LoadResources()
RedrawGadget(#MainCanvas)
; Bind Events
BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
BindEvent(#PB_Event_Timer, @DoEventTimer(), 0, 1)
;AddWindowTimer(0, 1, 33)
lasttime = ElapsedMilliseconds()
; Event Loop
Repeat
Select WaitWindowEvent(1)
Case #PB_Event_CloseWindow
Select EventWindow()
Case #Main
Break
EndSelect
Case #PB_Event_Menu
Select EventMenu()
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Case #PB_Menu_About
PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
Case #PB_Menu_Preferences
Case #PB_Menu_Quit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
CompilerEndIf
Case #MainMenuAbout
MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
Case #MainMenuExit
PostEvent(#PB_Event_CloseWindow, #Main, #Null)
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
EndSelect
EndSelect
time = ElapsedMilliseconds()
If time - lasttime >= 33
RedrawGadget(#MainCanvas)
lasttime = time
EndIf
ForEver
EndIf
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: Faster vector graphics
When using the sprite lib, you should precalculate everything before launching your rendering loop and never use startdrawing() in it. ScreenOutput() is basically only useful for debugging because it's very slow (you need to transfer GFX mem to main mem and then back, it's very costly).
That's why shaders have been added (to do real time changes on your sprites) but PB doesn't support them natively yet.
That's why shaders have been added (to do real time changes on your sprites) but PB doesn't support them natively yet.
- pf shadoko
- Enthusiast
- Posts: 386
- Joined: Thu Jul 09, 2015 9:07 am
Re: Faster vector graphics
ok with Pjay
I don't think it would be difficult to do the basic graphics functions in openGL
however I couldn't make anti-aliased polygons (for lines it's ok), if someone has the solution
@ fred :
in a game you always have to update a score, and other info (speed needle for coco2)
and then you have to go through startdrawing
I don't think it would be difficult to do the basic graphics functions in openGL
however I couldn't make anti-aliased polygons (for lines it's ok), if someone has the solution
@ fred :
in a game you always have to update a score, and other info (speed needle for coco2)
and then you have to go through startdrawing
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Faster vector graphics
Use sprites for that stuff too.pf shadoko wrote:in a game you always have to update a score, and other info (speed needle for coco2)
and then you have to go through startdrawing
BERESHEIT
- pf shadoko
- Enthusiast
- Posts: 386
- Joined: Thu Jul 09, 2015 9:07 am
Re: Faster vector graphics
@ netmaestro :
of course!
but startdrawing(spriteoutput(...)) is very slow (not as much as with screenoutput, but it easily drops the framerate)
see :
https://www.purebasic.fr/english/viewtopic.php?t=82923
of course!
but startdrawing(spriteoutput(...)) is very slow (not as much as with screenoutput, but it easily drops the framerate)
see :
https://www.purebasic.fr/english/viewtopic.php?t=82923
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Faster vector graphics
I'll post an example of how to do a speed indicator that uses virtually no cpu or time. It'll take me a couple hours as I have to rip code from projects but it'll be posted today.fred wrote:When using the sprite lib, you should precalculate everything before launching your rendering loop
BERESHEIT