I cut him, but he didn't use less memory...

BlitzMax Forums/BlitzMax Programming/I cut him, but he didn't use less memory...

Hi,

In another thread muk posted this link to some sprites and tilesets: www.reinerstileset.4players.de:1059/

I downloaded one of the sprites and wrote a small blitzmax app that loads and animates the bmp files. But they contain too much "empty space", or what do you call it, around the character. So i wrote a quick and dirty Sprite Optimizer (tm)(c)(r)(etc).
Since Sprite Optimizer (tm)(c)(r)(etc) cuts away all the unneeded pixels aroudn a sprite, the sprite should use less memory when stored in videoram. Well, it doesn't according to memalloced().
While I write this I realized that bmax should resize all images to the nearest power of 2 in order to make it compatible with older graphics cards (like mine, i guess), but some of the images gets cut so much that I believe it should be at least some small difference.

Anyway, to sum it all up:

1) Do memalloced() report video ram usage too?
2) If the graphic card compress the images, do memalloced() use that size instead of the "raw" size?

One character animations uses 19501652 bytes according to memalloced() (384 images), I hope this isn't true when it's stored in video ram.

Or am I way wrong here?

Here is the source for my little app:

Graphics 320,240,0

Local files:String[]
Local images_list:TList = CreateList()

files = LoadDir( CurrentDir() )

For Local f:String = EachIn files
	If Instr( f.tolower() ,".bmp") Then
		images_list.addlast(f)
	EndIf
Next

files = New String[images_list.count()]
Local last_one = images_list.count()

For Local i = 0 Until last_one
	files[i] = String( images_list.valueatindex(i) )
Next

FlushMem


'SetClsColor 128,128,255

Local index = 0
Local start_pos = 0
Local end_pos = 0

While Not KeyHit(KEY_ESCAPE)

	If KeyHit( KEY_UP ) And index < last_one-1 Then index:+1
	If KeyHit( KEY_DOWN ) And index > 0 Then index:-1

	If KeyHit( KEY_PAGEUP ) And index < last_one-11 Then index:+10
	If KeyHit( KEY_PAGEDOWN ) And index >= 10 Then index:-10

	If KeyHit( KEY_S ) Then start_pos = index
	If KeyHit( KEY_E ) Then end_pos = index

	If KeyHit( KEY_ENTER ) Then run_anim( start_pos, end_pos, files )
	
	

	' ------ GFX
	Cls
		DrawText "Memory usage: "+MemAlloced(), 0,0

		DrawText "Frames : "+last_one, 0,GraphicsHeight()-64
		DrawText "Start  : "+files[start_pos], 0,GraphicsHeight()-48
		DrawText "End    : "+files[end_pos], 0,GraphicsHeight()-32
		DrawText "Current: "+files[index], 0,GraphicsHeight()-16

	Flip
	FlushMem
Wend




Function run_anim( s,e, files:String[] )

	Local images:timage[] = New timage[ e-s ]
	Local num = e-s
	
	' get mask color
	Local tmp:timage = LoadImage( files[s] )
	Local tmppx = LockImage(tmp)
	Local pixdata = ReadPixel( tmppx, 0,0)
	UnlockImage(tmp)
	tmppx = Null
	tmp = Null
	FlushMem

	Local r,g,b,a
	a=(pixdata Shr 24) & $ff
	r=(pixdata Shr 16) & $ff
	g=(pixdata Shr 8) & $ff
	b=pixdata & $ff	

	'SetMaskColor r,g,b

	Local startmem = MemAlloced()
	' Load images
	AutoMidHandle(True)
	For Local i = 0 Until num
		Cls
		DrawText "Loading... "+ Int((Float(i)/Float(num))*100)+"%", 50,50
		
		
		tmp = LoadImage( files[s+i] )
		Local px = LockImage(tmp)
		UnlockImage( tmp )
		tmp = Null
		
		Local minx,maxx,miny,maxy,x,y
		Local col
		
		' Find minx
		For x = 0 Until PixmapWidth(px)
		For y = 0 Until PixmapHeight(px)
			col = ReadPixel(px,x,y)
			If col <> pixdata Then minx = x ; Exit
		Next
		If col <> pixdata Then Exit
		Next
		
		' find maxx
		For x = PixmapWidth(px)-1 To 0 Step -1
		For y = 0 Until PixmapHeight(px)
			col = ReadPixel(px,x,y)
			If col <> pixdata Then maxx = x ; Exit
		Next
		If col <> pixdata Then Exit
		Next
		
		' find miny
		For y = 0 Until PixmapHeight(px)
		For x = 0 Until PixmapWidth(px)
			col = ReadPixel(px,x,y)
			If col <> pixdata Then miny = y ; Exit
		Next
		If col <> pixdata Then Exit
		Next
		
		' find maxy
		For y = PixmapHeight(px)-1 To 0 Step -1
		For x = 0 Until PixmapWidth(px)
			col = ReadPixel(px,x,y)
			If col <> pixdata Then maxy = y ; Exit
		Next
		If col <> pixdata Then Exit
		Next
		
		' copy area from px to tmppx
		tmppx = CreatePixmap(maxx-minx+1,maxy-miny+1, PixmapFormat(px) )
		For x = minx To maxx
		For y = miny To maxy
			col = ReadPixel( px, x,y )
			WritePixel( tmppx, x-minx,y-miny, col )
		Next
		Next
		px = Null
		
		images[i] = LoadImage( tmppx )
		Flip
		FlushMem
	Next
	
	FlushMem
	Local endmem = MemAlloced()-startmem
	
	Local cx = GraphicsWidth()/2
	Local cy = GraphicsHeight()/2
	
	' Animate
	Local frame = 0
	Local frame_time = 100
	Local time = MilliSecs()+frame_time
	
	SetClsColor 64,64,64
	
	While Not KeyHit( KEY_SPACE )
		Local fps = 1000/frame_time
	
		If MilliSecs() >= time Then
			frame:+1
			If frame >= num Then frame = 0
			time = MilliSecs()+frame_time
		EndIf

		If KeyHit(KEY_A) Then frame_time:+10
		If KeyHit(KEY_Z) And frame_time >= 10 Then frame_time:-10
	
			
		Cls
			DrawImage images[frame], cx,cy
			DrawText "Position "+ Int((Float(frame)/Float(num))*100)+"%", 0,0
			DrawText "FPS: "+fps+" (a/z)", 0,16
			DrawText "Images memory usage: "+endmem, 0,32
		Flip
		FlushMem
	Wend
	
	SetClsColor 0,0,0

	FlushKeys

EndFunction


Compile and put the executable in a directory with a lot of BMP files.
Iterate files with UP/DOWN
iterate files 10 at a time with PGUP/PGDOWN
set start frame with S
set end frame with E
Run animation with ENTER

FlushMem would be used to clear the memory of any graphics you are no longer using - but it is not guaranteed. The garbage collector ultimately decides when to clear memory. FlushMem doesn't say when to clear the memory, it says when to make a decision whether or not to clear the memory.

I don't think MemAlloced() report anything to do with vidram...
I don't think graphics in vidmem are compressed.

The size of memory your graphic is taking up in vidmem is (in worst case scenario, could vary) width*height*4. If one frame of your 384 frame anim takes up 50k uncompressed, then yes, that near-20meg figure looks about right.

It's not exactly right, though, because 384 does not divide into that figure evenly.

MemAlloced only reports system RAM. DX mode loads textures to SystemRAM, OpenGL loads it straight into VRAM. (you could force that for DX as well but its not a that good idea)

And no actuall the graphics are not S3TC (DXTC is the same) compressed.

Thank you for the replies.