global images?

BlitzMax Forums/BlitzMax Programming/global images?

hi. just a quick question.
is it faster(cpu wise) to load all images as globals, and then just have any images inside my types reference them? i have a game where there are lots of instances of one type, and i was wondering if its faster to do that than have each instance load the images as fields.
thanks!
una.x

Dunno, but even if global images are faster, is it worth having it all global? Globals are a major ingredient for messy oldskool code.

I'd say, make a benchmark, and you'll know!

... globals within the type might be worthwhile but each object instance you create can share the same TImage instance without having to loadimage it each time.
Obviously, if you make changes to the image/pixmap then it will be reflected in all objects referencing that image.

And when you insist on globals, at least don't waste your namespace and do something like this:

Type TImagepool
	Field image1:timage=LoadImage("C:\Bmaxdev\oO\1.PNG")
End Type

Global imagepool:Timagepool=New TImagepool

Print ImageWidth(imagepool.image1)


Then it'll all only cost you one variabele in your namespaec. A variable you can easily pass as function argument even.

Type Something
   Global image:timage=loadimage(........)
   
   Field x, y
   Method draw()
      drawimage Something.image, x, y
   End Method
End Type


Then the image is stored and loaded only once, in Something.image

My approach to this is a generic image handler type 'TImg' that keeps track of all loaded image files and offers a simple interface to the user to fetch the images without having to worry if the file has already been loaded or not.

With this you can simply call TImg.LoadImg("filename") wherever you wish in the program, and it actually loads the image only if it hasn't been loaded yet. Otherwise it just returns the preloaded TImage.

The idea is not to use it in the main loop, but call it in the creation of the entity represented by the image, and store the returned TImage within the created entity instance.

Type TImg
	Global g_mediaPath:String = "media/"
	Global g_L_imageFiles:TList
	Field _image:TImage		' container field for the image itself
	Field _filename:String	' filename of the media file in the media directory
	
	Method GetFileName:String() 
		Return _fileName
	End Method
	
	Method GetImage:TImage() 
		Return _image
	End Method
	
	' LoadImg returns a TImage matching a filename string. 
	Function LoadImg:TImage(filename:String, automid:Int = True) 
		AutoImageFlags MASKEDIMAGE | FILTEREDIMAGE | MIPMAPPEDIMAGE	' flags For LoadImage()

		If Not g_L_imageFiles Then g_L_imageFiles = CreateList() 
		
		' if the file has already been loaded, return it instead of reloading it
		For Local img:TImg = EachIn g_L_imageFiles
			If img.GetFileName() = filename Then Return img.GetImage() 
		Next
		
		AutoMidHandle automid
		Local image:TImage = LoadImage(g_mediaPath + filename) 
		If Not image Then Return Null
		
		Local img:TImg = TImg.Create(image, filename) 
		Return img._image
	End Function
	
	' finds a previously loaded image and removes it from the image list
	Function UnLoadImg(filename:String)
		If Not g_L_imageFiles Then Return
		For Local img:TImg = EachIn g_L_imageFiles
			If img.GetFileName() = filename Then 
				img._image = Null
				g_L_imageFiles.Remove(img)
			EndIf
		Next	
	EndFunction
	
	Function Create:TImg(image:TImage, filename:String) 
		If Not g_L_imageFiles Then g_L_imageFiles = CreateList() 
		Local img:TImg = New TImg
		img._filename = filename
		img._image = image
		g_L_imageFiles.AddLast(img) 
		Return img
	End Function
End Type


The problem with copying your code like that is it's not as easily understood by others as you may think.

The code (which is commented, I might add) is ready to be cut & pasted without anyone having to understand anything but the two interfaces: LoadImg and UnloadImg functions. It really shouldn't be that complicated.

I thought the code was very well documented both with comments and good use of function, method and variable names.
The only thing I really do differently is use a tmap rather than a list but then I bundle all media resources into the same functions.

I use something like this but with wrappers around the images like Vilu. You should never call LoadImage more than you need to is I think the short answer.

Type TimageLibrary Extends Tmap
Method get:Timage(path:String)
	Local o:Object = MapValueForKey(Self, path)
	If TImage(o) Return TImage(o)
EndMethod
Method open(path:String, frames:Int = 1) 
	Local i:Timage
	If frames > 1
		Local temp:Timage = LoadImage(path) 
		Local w:Int = ImageWidth(temp) 
		Local h:Int = ImageHeight(temp) 
		i = LoadAnimImage(path, w / frames, h, 0, frames)
	Else
		i = LoadImage(path)
	EndIf
	MapInsert(Self, path, i)
EndMethod
Method list:TMapEnumerator() 
	Return MapKeys:TMapEnumerator( Self )
EndMethod
EndType


The code (which is commented, I might add) is ready to be cut & pasted without anyone having to understand anything but the two interfaces: LoadImg and UnloadImg functions

Not really. The only way I could figure that out is to look into the program code and work it out. You should start the code with brief description of its use, that doesn't require the code to be read.

You should start the code with brief description of its use, that doesn't require the code to be read.


Sounds to me like you didn't read the post above the code snippet. ;)

Since the original question was in reference to speed, I'd say none of this will result in faster rendering.