Page 1 of 2
StartDrawing(SpriteOutput()) speed
Posted: Thu Nov 23, 2023 8:19 am
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?
Re: StartDrawing(SpriteOutput()) speed
Posted: Thu Nov 23, 2023 9:24 am
by mk-soft
Do not create a new sprite every time, but create several sprites beforehand and change the sprite.
Re: StartDrawing(SpriteOutput()) speed
Posted: Thu Nov 23, 2023 10:54 am
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
Re: StartDrawing(SpriteOutput()) speed
Posted: Thu Nov 23, 2023 1:52 pm
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
Re: StartDrawing(SpriteOutput()) speed
Posted: Thu Nov 23, 2023 9:28 pm
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?
Re: StartDrawing(SpriteOutput()) speed
Posted: Fri Nov 24, 2023 2:19 pm
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).
Re: StartDrawing(SpriteOutput()) speed
Posted: Fri Nov 24, 2023 8:27 pm
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.
Re: StartDrawing(SpriteOutput()) speed
Posted: Fri Nov 24, 2023 10:20 pm
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.
Re: StartDrawing(SpriteOutput()) speed
Posted: Sat Nov 25, 2023 9:50 am
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.
Re: StartDrawing(SpriteOutput()) speed
Posted: Sat Nov 25, 2023 12:19 pm
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
Re: StartDrawing(SpriteOutput()) speed
Posted: Sat Nov 25, 2023 4:46 pm
by Kuron
That looks REALLY good!!!
Re: StartDrawing(SpriteOutput()) speed
Posted: Sun Nov 26, 2023 12:22 am
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
Re: StartDrawing(SpriteOutput()) speed
Posted: Sun Nov 26, 2023 8:10 am
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)?
Re: StartDrawing(SpriteOutput()) speed
Posted: Sun Nov 26, 2023 8:21 am
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.
Re: StartDrawing(SpriteOutput()) speed
Posted: Sun Nov 26, 2023 9:14 am
by coco2
Is drawing textures during the main game loop necessary? What would it be used for?