And again thanks a lot. While you was writing this message I made some tests with the classes and noted my self that I should keep the manager.Originally Posted by Sly
You have been very helpful. Thanks a lot.
And again thanks a lot. While you was writing this message I made some tests with the classes and noted my self that I should keep the manager.Originally Posted by Sly
You have been very helpful. Thanks a lot.
- In a world without the wall and fences, who will need the Gates and Windows.
Hmm, how about freeing texture in TSprite.Destroy - not local reference to ID3D9Texture but one in TSpriteManager.FTextures too?![]()
There are only 10 types of people in this world; those who understand binary and those who don't.
Yes. There should be some sort of call to method in TSpriteManager which seeks if there's no any references to texture itself and frees it.Originally Posted by Clootie
If that's what you meant.
edit: but of course that should be possible to avoid also, because if you destroy last sprite in the game which references to some texture and after couple frames sprite with same texture reappears in the game. So there should be boolean variable when destroying sprite which determines that is that "Seek 'n' Destroy" method ran or not.
- In a world without the wall and fences, who will need the Gates and Windows.
Sly.
You use StringList to maintain textures, but when I try to do something similar I get error "incompatible types IDirect3Dtexture9 and TObject".
In your example where you wrote IDirect3DTexture9(FTextures.Objects[0])._release;
- In a world without the wall and fences, who will need the Gates and Windows.
Yep, it's design issue.
Other issue is that video drivers do not like to create and destroy textures every frame or so. So, it's way better to allocate some pool of sprites of different sizes at start of your app, and later reuse these containers for real sprites then they are requested by your game engine.
There are only 10 types of people in this world; those who understand binary and those who don't.
Working code:
[pascal][background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000] var
l: TStringList;
texture: IDirect3DTexture9;
TextureFileName: String;
begin
l:= TStringList.Create;
// Add texture to list
l.AddObject(TextureFileName, Pointer(texture));
Pointer(texture):= nil;
// Remove texture from list
Pointer(texture):= Pointer(l.Objects[0]);
texture:= nil;
// You can also do this to free interface, but above is more recommended
// IDirect3DTexture9(Pointer(l.Objects[0]))._Release;
end.[/pascal]
There are only 10 types of people in this world; those who understand binary and those who don't.
Thank you. I got it to work now. I got it to working earlier too by that way what you mention in the last row of your post, but then I got exception all the time when exiting from application.Originally Posted by Clootie
That exception occured because all sprites was freed before SpriteManager and in sprite destructor I assigned nil to that texture referencer.
edit: Why it doesn't work? When I exit from application, I'll free all sprites first. In those sprite destructors i assign nil to that local texture referencer. After all sprites is released I free sprite manager itself, where I use method you descripted above. That causes an exception if there's no any sprite referencing to texture anymore. If I leave even one sprite to reference it and then call that sprite manager destructor all works fine. Why's that?
Shouldn't that texture exists in the stringlist even there's no sprite to referencing to it? In my opinion it should, but somehow it's released when all sprites stops referencing to it?!? Or do I lost my texture data to somewhere in memory?
Some pseudo code to clearify what I mean...
And when exiting SpriteManager destructor causes an exception if there's no sprite referencing to texture.Code:TSprite = Class private FTexture: IDirect3DTexture; public Create(Texture); Destroy; end; TSpriteManager = Class private FTextures : TStringList; function CreateSprite(FileName): TSprite; public Create; Destroy; end; { TSprite } TSprite.Create(Texture); begin FTexture := Texture; // assign reference to texture. end; TSprite.Destroy; begin FTexture := nil; // Free references to texture. end; { TSpriteManager } TSpriteManager.Create; begin FTextures := TStringList.Create; end; TSpriteManager.Destroy; var Texture: IDirect3DTexture9; begin while FTextures.Count > 0 do begin Pointer(Texture) := Pointer(FTextures.Objects[0]); // Get pointer to textue; Texture := nil; // Remove texture; FTextures.Delete(0); // Delete texture from stringlist. end; inherited; end; TSpriteManager.CreateSprite(FileName): TSprite; begin Seek(filename) if texture exists then Result := Sprite.Create(Pointer to existing texture) else begin LoadTexture(FileName); FTextures.Add(Loaded Texture); Result := Sprite.Create(Loaded Texture); end; end;
- In a world without the wall and fences, who will need the Gates and Windows.
I finally managed to help my self out. I changed that TStringList to Tlist type. I also made a record which holds the texture, filename and reference count in it. When new texture is loaded a new pointer to that record (which stores the texture itself) is made and that record pointer is stored in a Tlist.
I also build one procedure to SpriteManager class which is used to release sprite. That procedure has argument for releasing the texture from memory among the sprite itself (if there's no more sprites pointing to texture).
Finally when spritemanager is freed and if there's any pending textures in TList, it releases them in destructor and frees Tlist itself.
I stress tested this with hundreds of sprites. Some of them refenced to same texture and some of them had texture for that specific sprite only. When textures was released, created, released, created and so on memory changed (I was interrupting with debugger and watching memory usage from process list) and everything worked just fine.
Now I can finish the sprite engine. Still I want to thank you guys (or gals). Without your help I would never manage to do anything like this.
- In a world without the wall and fences, who will need the Gates and Windows.
Bookmarks