video memory and two identical textures

BlitzMax Forums/BlitzMax Programming/video memory and two identical textures

deps(Posted 2005) [#1]
Quick question.

local img1:TImage = loadimage("image.png")
local img2:TImage = loadimage("image.png")


Does the video memory contains two copies of image.png now, or will BlitzMax detect this and only upload it once.


TeraBit(Posted 2005) [#2]
It will contain two copies of the Texture.

It's likely that Max3D will detect this as part of Model loading, but just loading straight images will not, and it's probably a good thing that it doesn't in case you want to alter one or more copies in some way.


deps(Posted 2005) [#3]
and it's probably a good thing that it doesn't in case you want to alter one or more copies in some way.

Good point. And thanks for the help.


Jeroen(Posted 2005) [#4]
What I did for a game was write a custom loader (in my case for meshes, but the principle works with textures as well).

basicly it comes down to this:
1. filename already in library? copy the entity.
2. not in library? load the entity.

When I loaded a mesh using this custom function, it added
the filename (and a reference to the object) in a type
if it was not not in this list already.

This way multiple objects where not loaded twice, only
referenced more.

Compare it with Macromedia Flash object instances and objects in the library.


deps(Posted 2005) [#5]
Thanks Jeroen. I'm going to code something similar to that.


FlameDuck(Posted 2005) [#6]
Might I suggest using a TMap rather than a list?


deps(Posted 2005) [#7]
TMaps is faster than TLists? Good to know.


deps(Posted 2005) [#8]
How does this look?
Type Texture

	Global textures:TMap

	Function Load:TImage( filename:String )
	
		If Not textures Then textures = New TMap
		
		If Not textures.ValueForKey(filename) Then
			' Not found, load it.
			Local img:TImage = LoadImage( filename )
			If Not img Then Throw "Unable to load "+filename
			
			textures.insert( filename, img )
			Print "New texture loaded. "+filename
			
			Return img		
		Else
			' get the texture and return it
			Print "Texture reused. "+filename
			Return TImage(textures.ValueForKey(filename))
		EndIf
	
	
	EndFunction


	' Call this after you have changed the graphics mode to reload all textures
	Function Reload()

		If Not textures Then Return ' Nothing to reload

		Local templist:TMap = New TMap

		Local nodeenum:TNodeEnum=textures.ObjectEnumerator()
		While nodeenum.HasNext()
		Local temp:TNode=TNode(nodeenum.NextObject())
			Print("Reloading texture "+temp.Key().ToString())
			'Print("VAL: "+item(temp.Value()).val)
			templist.insert( temp.Key().ToString(), LoadImage( temp.Key().ToString() ) )
		Wend
		
		textures = templist
	
	EndFunction
	
	
	Function Clear()
		textures.clear()
	EndFunction
	

EndType


Anything I should change/add/remove?


Jay Kyburz(Posted 2005) [#9]
This might be a dumb question but what is tMap?

I do this will an array. Note that now that the texture is reference by the tMap and the object you will need to remove it from the map when it is no longer needed by the game.

I use simple reference counting.

I also do tricky stuff like store the full path and can reload every texture in the game in one call. This makes tuning textures cool.


tonyg(Posted 2005) [#10]
There's a bit of an explanation and example here .
However, I'm still not sure why it's not documented.
If it's not documented (I'm guessing) it shouldn't be used in case it's removed later.... maybe?