StartDrawing(SpriteOutput()) speed

Advanced game related topics
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

StartDrawing(SpriteOutput()) speed

Post by coco2 »

I have done some time measurements and have the following times for running the code mentioned:

StartDrawing(SpriteOutput()) - 2-5ms
StopDrawing() - 0-1ms
StartVectorDrawing(ImageVectorOutput()) - 0-1ms
StartDrawing(ImageOutput()) - 0-1

While 1ms seems like too long for some of these I'm mostly concerned with the 2-5ms for StartDrawing(SpriteOutput())

On a 60hz monitor with a 16ms frame time this is a problem
On a 144hz monitor with a 7ms frame time this is impossible

How do we deal with this problem when making games?

In particular I am talking about a 3D game that has 2D overlays. Several of these overlays need to be generated on the fly and it's not possible to do it fast enough. Any suggestions?
Last edited by coco2 on Thu Nov 23, 2023 9:40 pm, edited 1 time in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 6200
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: StartDrawing(SpriteOutput()) speed

Post by mk-soft »

Do not create a new sprite every time, but create several sprites beforehand and change the sprite.
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
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: StartDrawing(SpriteOutput()) speed

Post by coco2 »

It can be done with text, but other things cannot be done with prerendered sprites. I'm making a driving game and the 2D overlays include a tachometer with a needle that moves. I tried doing it with a background and needle sprite but the rotate sprite function is not good enough quality, the output doesn't look very good, like the edges of the needle are all jagged. I also need to make a map which is dynamic vector graphics and can't be done with sprites. Is it possible to render these things in other threads that draw to the screen at a different rate?

Edit: here is some code to demonstrate threads generating images. Is it correct that threads will not work with sprites?

Code: Select all

EnableExplicit
Structure Thread_Draw_Structure
  ThreadID.i
  Value.i
  Processing.i
  Image.i
  Width.i
  Height.i
EndStructure
Define.i Event
Define.Thread_Draw_Structure *P = AllocateStructure(Thread_Draw_Structure)
Procedure ThreadDrawImage(*P.Thread_Draw_Structure)
  If StartDrawing(ImageOutput(*P\Image))
    DrawingMode(#PB_2DDrawing_AllChannels)
    Circle(*P\Width/2, *P\Height/2, *P\Width/2-1, RGBA(Random(255, 0), Random(255, 0), Random(255, 0), 255))
    StopDrawing()
  EndIf  
  *P\Processing=2 ; finished
EndProcedure
InitSprite()
InitKeyboard()
ExamineDesktops()
*P\Width = 400
*P\Height = 400
OpenWindow(0, 0, 0, *P\Width, *P\Height, "Thread Draw Image Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
*P\Value = 1
*P\Processing = 0
*P\Image = CreateImage(#PB_Any, 400, 400, 32)
Repeat
  Delay(10)
  Event = WindowEvent()
  If *P\Processing=2
    StartDrawing(WindowOutput(0))
    DrawAlphaImage(ImageID(*P\Image), 0, 0)
    StopDrawing()
  EndIf
  If *P\Processing=0 ; make sure not to create multiple threads
    *P\Processing=1
    *P\ThreadID=CreateThread(@ThreadDrawImage(), *P)
  EndIf
Until Event = #PB_Event_CloseWindow
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 385
Joined: Thu Jul 09, 2015 9:07 am

Re: StartDrawing(SpriteOutput()) speed

Post by pf shadoko »

I wanted to do a bug report on this subject
I've already posted one about textures
(note: sprites are textures)
viewtopic.php?t=81586

indeed, a simple update of a 512*512 sprite takes more time than a frame
this problem must be corrected, I think you should do a bug report

PS: use the spritequality(#PB_Sprite_BilinearFiltering) command for a nice rotation
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: StartDrawing(SpriteOutput()) speed

Post by coco2 »

Thanks, spritequality(#PB_Sprite_BilinearFiltering) helps quite a bit, although not quite as good as directly drawing it with vector drawing functions.

How did you do it with DirectX? Is it possible to show the developers that the same thing can be done instantly?
ricardo_sdl
Enthusiast
Enthusiast
Posts: 141
Joined: Sat Sep 21, 2019 4:24 pm

Re: StartDrawing(SpriteOutput()) speed

Post by ricardo_sdl »

Hi coco2!
Did you measure the timing with different subsystems (OpenGL and Directx9 or DirectX11)? I think StartDrawing(SpriteOutput()) tends to be slower on opengl when run on windows (edited).
Last edited by ricardo_sdl on Fri Nov 24, 2023 9:01 pm, edited 1 time in total.
You can check my games at:
https://ricardo-sdl.itch.io/
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: StartDrawing(SpriteOutput()) speed

Post by DarkDragon »

StartDrawing/StopDrawing is all on CPU, there's no speed to expect. It downloads and uploads the texture from and to your GPU. You have to use static sprites to do this or shaders or so, something which is purely on the GPU. It's not a bug. Please show the quality problems you had when you used RotateSprite to draw the needle.
bye,
Daniel
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: StartDrawing(SpriteOutput()) speed

Post by coco2 »

Hi Richardo_sdl

I think I'm using DirectX 9, how can I test them out?

Hi DarkDragon, I fixed the quality issues by using spritequality(#PB_Sprite_BilinearFiltering). It is not 95% as good as drawing directly with the vector functions (it will never be as good as directly drawing it though).

I noticed that in the documentation it mentions using images in threads, it's pointless to use threads and images because you still have to display them which is time consuming and too slow for the main game loop. I have concluded that in Purebasic you need to do everything graphics in the main game loop thread using sprites.
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: StartDrawing(SpriteOutput()) speed

Post by DarkDragon »

coco2 wrote: Fri Nov 24, 2023 10:20 pmHi DarkDragon, I fixed the quality issues by using spritequality(#PB_Sprite_BilinearFiltering). It is not 95% as good as drawing directly with the vector functions (it will never be as good as directly drawing it though).
Why won't it be as good as directly drawing? Show the difference please.
coco2 wrote: Fri Nov 24, 2023 10:20 pmI noticed that in the documentation it mentions using images in threads, it's pointless to use threads and images because you still have to display them which is time consuming and too slow for the main game loop. I have concluded that in Purebasic you need to do everything graphics in the main game loop thread using sprites.
Images are mainly for applications, Sprites are for games/gpu rendering. Threads won't help there either, because you still have the physical bottleneck, the wires to your GPU and synchronization between GPU and CPU.
bye,
Daniel
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: StartDrawing(SpriteOutput()) speed

Post by coco2 »

Why won't it be as good as directly drawing? Show the difference please.
Hi DarkDragon,

When I rotated the sprite it's edges were a bit weird. I have found a way to fix it now, I created the sprite that needs to be rotated at 2x it's normal size, then zoom it, then rotate it and it looks really good, almost 100%.

You can see before I figure out the fix the way rotating causes the edges of the tachometer needle to be a bit "bumpy"?

Image is here:
https://ibb.co/3hbz6nB
User avatar
Kuron
Addict
Addict
Posts: 1626
Joined: Sat Oct 17, 2009 10:51 pm
Location: Pacific Northwest

Re: StartDrawing(SpriteOutput()) speed

Post by Kuron »

coco2 wrote: Sat Nov 25, 2023 12:19 pm https://ibb.co/3hbz6nB
That looks REALLY good!!!
Best wishes to the PB community. Thank you for the memories. ♥️
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 385
Joined: Thu Jul 09, 2015 9:07 am

Re: StartDrawing(SpriteOutput()) speed

Post by pf shadoko »

a small program to test startdrawing() times with textures, sprites and images
compare opengl and directx

Code: Select all

InitEngine3D()
InitSprite()
OpenWindow(0, 0,0,100,100,"")
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)

Debug "OS: "+OSVersion()+#TAB$+" PB: "+#PB_Compiler_Version 

t0=ElapsedMilliseconds()
For i=1 To 10
  CreateTexture(i,2048,2048)
  StartDrawing(TextureOutput(i))
  StopDrawing()
Next
t1=ElapsedMilliseconds()-t0
Debug "texture:"+#TAB$+t1

t0=ElapsedMilliseconds()
For i=1 To 10
  CreateSprite(i,2048,2048)
  StartDrawing(SpriteOutput(i))
  StopDrawing()
Next
t2=ElapsedMilliseconds()-t0
Debug "sprite:"+#TAB$+t2

t0=ElapsedMilliseconds()
For i=1 To 10
  CreateImage(i,2048,2048,32)
  StartDrawing(ImageOutput(i))
  StopDrawing()
Next
t3=ElapsedMilliseconds()-t0
Debug "image:"+#TAB$+t3
opengl:
OS: 120 PB: 603
texture: 3074
sprite: 692
image: 38

directx9
OS: 120 PB: 603
texture: 3
sprite: 336
image: 47
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: StartDrawing(SpriteOutput()) speed

Post by firace »

pf shadoko wrote: Sun Nov 26, 2023 12:22 am a small program to test startdrawing() times with textures, sprites and images
compare opengl and directx

Code: Select all

InitEngine3D()
InitSprite()
OpenWindow(0, 0,0,100,100,"")
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)

Debug "OS: "+OSVersion()+#TAB$+" PB: "+#PB_Compiler_Version 

t0=ElapsedMilliseconds()
For i=1 To 10
  CreateTexture(i,2048,2048)
  StartDrawing(TextureOutput(i))
  StopDrawing()
Next
t1=ElapsedMilliseconds()-t0
Debug "texture:"+#TAB$+t1

t0=ElapsedMilliseconds()
For i=1 To 10
  CreateSprite(i,2048,2048)
  StartDrawing(SpriteOutput(i))
  StopDrawing()
Next
t2=ElapsedMilliseconds()-t0
Debug "sprite:"+#TAB$+t2

t0=ElapsedMilliseconds()
For i=1 To 10
  CreateImage(i,2048,2048,32)
  StartDrawing(ImageOutput(i))
  StopDrawing()
Next
t3=ElapsedMilliseconds()-t0
Debug "image:"+#TAB$+t3
opengl:
OS: 120 PB: 603
texture: 3074
sprite: 692
image: 38

directx9
OS: 120 PB: 603
texture: 3
sprite: 336
image: 47
Hi, this program uses Debug statements. I can't test right now, but wouldn't it run faster with debugger off (and replacing the Debug commands with MessageRequester, for instance)?
miso
Enthusiast
Enthusiast
Posts: 403
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: StartDrawing(SpriteOutput()) speed

Post by miso »

Hi, this program uses Debug statements. I can't test right now, but wouldn't it run faster with debugger off (and replacing the Debug commands with MessageRequester, for instance)?
I tried yesterday with console output and debugger off, but there were no significant change.
coco2
Enthusiast
Enthusiast
Posts: 461
Joined: Mon Nov 25, 2013 5:38 am
Location: Australia

Re: StartDrawing(SpriteOutput()) speed

Post by coco2 »

Is drawing textures during the main game loop necessary? What would it be used for?
Post Reply