Initially choppy graphics

BlitzMax Forums/BlitzMax Programming/Initially choppy graphics

sswift(Posted 2006) [#1]
Has anyone investigated this issue, and found a solution? In my game I have a bunch of objects on the screen, and for a second after they start to animate after I click the mouse, a lot of frames are dropped, making the motion look choppy.

It seems like the frames of the animated images that haven't been drawn are not loaded into video memory until they need to be drawm, and that means that everything goes choppy for a second while 288 animation frames get buffered.

I suppose one could draw all the images once without flipping to prebuffer them, but that seems a rather crummy way to fix the issue. Shouldn't Blitzmax buffer this stuff until it runs out of video ram automatically when loading the images?


sswift(Posted 2006) [#2]
Drawing them seemed to fix it, but I don't know if that is going to slow down the load with lots of graphics or not.

Here are the functions, plus some extra stuff:

' -----------------------------------------------------------------------------------------------------------------------------------------------------------
' These functions override the regular image loading functions so that we can display an error when an image is missing. 
' -----------------------------------------------------------------------------------------------------------------------------------------------------------

	Function LoadImage:TImage(Url:Object, Flags%=-1)
	
		Local Image:TImage
		
		Image = Brl.Max2D.LoadImage(Url, Flags)
		If Image = Null Then RuntimeError("The following image failed to load: ''" + String(Url) + "''.  Please reinstall the game.")
		
		DrawImage Image, 0, 0
		
		Return Image
		
	End Function
	

	Function LoadAnimImage:TImage(Url:Object, Cell_Width%, Cell_Height%, First_Cell%, Cell_Count%, Flags%=-1)
	
		Local Image:TImage
		Local Frame%

		Image = Brl.Max2D.LoadAnimImage(Url, Cell_Width, Cell_Height, First_Cell, Cell_Count, Flags)
		If Image = Null Then RuntimeError("The following image failed to load: ''" + String(Url) + "''.  Please reinstall the game.")
		
		For Frame = First_Cell To First_Cell+(Cell_Count-1)
			DrawImage Image, 0, 0, Frame
		Next  
		
		Return Image
		
	End Function
		

' -----------------------------------------------------------------------------------------------------------------------------------------------------------
' This function overrides the standard RuntimeError function which does not work properly.  Assert also does not work.
' -----------------------------------------------------------------------------------------------------------------------------------------------------------

	Function RuntimeError(Error$)
		EndGraphics
		Notify(Error$, True)
		End
	End Function
	
	
' -----------------------------------------------------------------------------------------------------------------------------------------------------------
' This function oveerides the standard Flip() function with a lag fix for DirectX.
' -----------------------------------------------------------------------------------------------------------------------------------------------------------
	
	Function Flip(Sync%=-1)
		
		Brl.Graphics.Flip Sync
		
		?Win32
			If TD3D7Max2DDriver(_max2dDriver)
				Local sdesc:DDSurfaceDesc2 = New DDSurfaceDesc2
				sdesc.dwSize = SizeOf(sdesc)
				Local res:Int = PrimaryDevice.backbuffer.Lock(Null,sdesc,DDLOCK_WAIT|DDLOCK_READONLY,Null)
				PrimaryDevice.backbuffer.unlock(Null)
			EndIf
		?
		
	End Function



ImaginaryHuman(Posted 2006) [#3]
This is probably more down to how the graphics driver handles its textures. Some will have to do some transfer/processing the first time that you use a given texture, after which it is normal speed. It's not really BlitzMax's fault. Once it hands over the graphics data to GL/DX it's out of its hands as to how this happens. You probably will have to draw all the images once to make them current, unless anyone else knows a better idea.


Grey Alien(Posted 2006) [#4]
I've noticed the same thing. It happens more on some PCs than others and also occurs when the user switches between full-screen and windowed mode dynamically. There was actually a similar issue in BPlus where the graphics weren't moved onto the video RAM immediately so slowed down the game on the first draw.


tonyg(Posted 2006) [#5]
The first time anything is drawn it is converted from pixmap to an image regardless whether loadimage/loadpixmap was used.
Somebody asked for a flag to automatically create the texture but it never happened and I can't find the post (it was about 1 year ago).
I'm guessing if all images were loaded into video RAM immediately we'd run out of space on some machines pretty quickly.
I know that Bmax for DX uses auto-managed memory for textures which, I think, is why imagebuffers were not included.


sswift(Posted 2006) [#6]
Hm... I just realised I could make a function in my sprite system which could draw all the frames of all the sprites which currently exist (or are just visible) and I could call that when switching video modes to buffer the graphics. Not an ideal solution, but it saves me from having to change how I load and store the images in my program.

Btw, in case anyone is interested... I have updated a few things with the sprite system, but I have not made a release because I have changed the way you specify animations to SpriteName.AnimatePosition(...) rather than Animate.Position(SpriteName, ...), and I just haven't had time to update all the demos, and I had been also trying to decide if I wanted to make that change permanent or not, which I've now decided to do. Just didn't want you to think I've abandoned updates for it.