All images not accounted for...
BlitzPlus Forums/BlitzPlus Programming/All images not accounted for...
| ||
Help! In my game, I have a routine that deletes all images one by one:If image<>0 then FreeImage image : image=0 The problem is that I don't seem to have deleted all of the images, and I still have some seemingly left anaccounted for taking up video memory. How am I supposed to find all of these? Any ideas? |
| ||
Do you use copyimage in somewhere ? |
| ||
No. I do load one particular image 4 separate times under different handles in the same loading routine:scytheul2=LoadImage("Graphics\Scythe2\scythe ul.png") MidHandle scytheul2 MaskImage scytheul2,255,0,255 scythedl2=LoadImage("Graphics\Scythe2\scythe ul.png") MidHandle scythedl2 MaskImage scythedl2,255,0,255 RotateImage scythedl2,270 scythedr2=LoadImage("Graphics\Scythe2\scythe ul.png") MidHandle scythedr2 MaskImage scythedr2,255,0,255 RotateImage scythedr2,180 scytheur2=LoadImage("Graphics\Scythe2\scythe ul.png") MidHandle scytheur2 MaskImage scytheur2,255,0,255 RotateImage scytheur2,90and later... If scythedl2<>0 Then FreeImage scythedl2 : scythedl2=0 If scytheul2<>0 Then FreeImage scytheul2 : scytheul2=0 If scytheur2<>0 Then FreeImage scytheur2 : scytheur2=0 If scythedr2<>0 Then FreeImage scythedr2 : scythedr2=0 Could it be something to do with this? I'm a bit sceptical, 'cos I seem to be losing a lot more vidmem thatn these would account for. Any further ideas? |
| ||
Anyone got any other ideas? This is a nasty problem for the game, so if anyone else could help, this would be greatly appreciated. |
| ||
Just a thought. You wouldn't by chance be adding or deleting image handle variables from a function, would you? If so you need to declare the image handle variable name as global. If that's not it, I don't know. Cheers, Andy |
| ||
Are we absolutely positive that FreeImage immediately de-allocates the memory internally? (It's conceivable that Blitz might not deallocate the memory until it absolutely has to, for optimization purposes, but truthfully, I don't know.) |
| ||
>Andy A No, I don't use a function. I ran a little tes program to see what happens to images when you delete them, and I think it's pretty conclusive that there's images floating about in my game undeleted. The routine's as follows: Graphics 800,600 firstvidmem=AvailVidMem() timer=CreateTimer(15) While Not KeyDown(1) Color 255,255,0 WaitTimer timer image1=LoadImage("image.png") If KeyDown(28)=1 Then FreeImage image1 : image1=0 images=images+1 Print images vidmem=AvailVidMem() Print vidmem Wend End If you hold down enter, you see that the memory stays the same, because it is loaded and then deleted. Therefore, it means that I have images floating around that I haven't found. I've tried setting the handles for the graphics as all global and seeing if they come up in the debug sidebar in the IDE, but all the images come up as 0. I can't find a single one that doesn't come up as 0 - even the ones that I've loaded and not deleted! This could be a solution, but I don't know what I'm doing wrong. Thanks so far. Any more ideas? |
| ||
That's puzzling. I thought that it might possibly have something to do with freeing the images in a different order than they were created. However, modifying your test routine to load four images then delete them in a different order deallocated memory as it should. I also tried putting in the MaskImage and RotateImage commands for each in case they were to blame, but deallocation worked as it should have again. You don't do this in the test routine, but in your actual program, you aren't by chance comparing available video memory before setting the graphics mode with afterwards, are you? firstvidmem=AvailVidMem() Graphics 800,600 vidmem=AvailVidMem() Print firstvidmem+", "+vidmem WaitKey End That results in a "loss" of memory due to setting up buffers. Just grasping at straws... :) all the images come up as 0. I can't find a single one that doesn't come up as 0 - even the ones that I've loaded and not deleted! Hmm, that doesn't sound quite right. You might try adding DebugLog statements every time you delete an image, just to make sure that FreeImage is really being called. For example: If scythedl2<>0 Then FreeImage scythedl2 : scythedl2=0 DebugLog "Freed scythedl2" else DebugLog "scythedl2 not freed" endif To save lots of typing, this could be done in a function. Oh, and maybe having a Global count of total images currently loaded (similar to your test program) and decrementing it when an image is freed could be helpful (in case you're already using DebugLog for other things and it'd be hard to read through all the text). |
| ||
I don't check the beginning vidmem before the graphics mode is set. As a function, how would I be able to state the image handle in the function? This one's had me puzzled... >Edit - I think I've managed it - just was expecting it to try to free an image called "handle" if I used this, rather than "image1". If KeyDown(28)=1 Then imagefree(image1)calls up... Function imagefree(handle) FreeImage handle : handle=0 End Function Thanks. This should help me a lot! |
| ||
AAAARGH! Well, at least I'm closer to finding the solution, but this is getting annoying! Here's my image-freeing function:Function delete_image(handle) Local handlenum If handle<>0 Then FreeImage handle handlenum=handle handle=0 loadedimages=loadedimages-1 DebugLog "Freed "+handlenum+" to "+handle Else DebugLog handle+" not freed" EndIf End Function This means I can check to see if an image has been deleted... or not. The problem is that the images that I have loaded go through the routine and come out in debug as (for example): Freed 28574048 to 0 Freed 28573792 to 0 Freed 28606112 to 0 Freed 28574288 to 0Which is all well and good, but then I do the deleting routine again, and though these images should be deleted, it comes out as: Freed 28574048 to 0 Freed 28573792 to 0 Freed 28606112 to 0 Freed 28574288 to 0which quite obviously shows that they haven't been deleted. This is probably the source of the memory problems, but as for the solution, I have no idea what to do! Please help!!! |
| ||
;Blitz normally passes variables by value, with no way to pass by reference ;(short of using Globals, which negates the point of explicitly passsing them) a=100 b=10 Print "pre: "+a ; displays 100 Print "pre: "+b ; displays 10 foo(a,b) Print "post: "+ a ; displays 100 Print "post: "+b ; displays 10 Print"---" ;However, Types are always passed by reference Type bartype Field a Field b End Type bar.bartype=New bartype bar\a=100 bar\b=10 Print "pre: "+bar\a ; displays 100 Print "pre: "+bar\b ; displays 10 foobar(bar) Print "post: "+ bar\a ; displays 200 Print "post: "+bar\b ; displays 11 WaitKey End Function foo(a,b) a=200 ; these changes will not matter outside this function b=b+1 End Function Function foobar(baz.bartype) baz\a=200 ; these changes *will* matter outside this function baz\b=baz\b+1 End Function This shows how the variables passed to foo() are not affected outside of foo() since only the *values* of a & b are passed to it, not "the real" a & b. I would have expected your function to cause a problem when it tried to FreeImage a handle that had already been freed, but that doesn't happen: Graphics 800,600 FreeImage 12345 ; just a number picked out of thin air FreeImage 12345 ; even worse, we're freeing this nonexistent handle twice! hdl=CreateImage(32,32) FreeImage hdl FreeImage hdl ; Blitz has no problem with this Print "No boom. Press a key." WaitKey End (BTW, there's a similar discussion about "missing memory" for 3D at http://blitzbasic.com/bbs/posts.php?topic=25942 ) |
| ||
Maybe this works. global Picture1=loadimage("PICTURE.bmp") maskimage 255,0,255 picture2=picture1 picture3=picture1 picture4=picture1 when you don't need the picture anymore picture2=0 picture3=0 picture4=0 to free the image from memory if picture2=0 and picture3=0 and picture4=0 then freeimage picture1 end if this way the picture loads once instead of four times. later |
| ||
Well, I seem to have solved that delelting-images-that-aren't-there problem. I just added:imagefree(image) : image=0and everything seems to be fine. I've also added a bit of code to tell me how much memory is freed when I delete an image, which is of great use. Still, the problem remains as to where the faults are, so keep those solutions coming! Thanks so far! >EDIT YESSSS! Problem solved! It turns out I wasn't freeing the fonts correctly, so it kept on loading the fonts again and again - not the images! I can't believe that after all that, the problem was THAT! Thanks to all of you - your advice is incredibly valuable, and without it, I probably wouldn't have worked it out anyway. And you've all solved me a hell of a load of problems I'm likely to have encountered in the future. Thanks to you all! |
| ||
Sorry to pull this old thread back up...but thought it might prove helpful :P This: Function delete_image(handle) Local handlenum If handle<>0 Then FreeImage handle handlenum=handle handle=0 loadedimages=loadedimages-1 DebugLog "Freed "+handlenum+" to "+handle Else DebugLog handle+" not freed" EndIf End Function Should be: Function delete_image(handle) Local handlenum If handle<>0 Then FreeImage handle handlenum=handle handle=0 loadedimages=loadedimages-1 DebugLog "Freed "+handlenum+" to "+handle Else DebugLog handle+" not freed" EndIf Return handle ;<----------right here...a Function is designed to return a value End Function Then when you call the function you do this: handle = delete_image(handle) NOT this: delete_image(handle) : handle = 0 |
| ||
Thanks! The problem's solved, but thanks for the advice. I'm sure it could save me some typing time. :) |