• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
SleepySamurai

Do I need to release() these textures?

8 posts in this topic

So lets say I have a struct called 'Sprite.' Inside that struct is the member LPDIRECT3DTEXTURE9 texture.

Let's say I make an array of Sprite's that looks like: Sprite myArray[1000].

 

I want the same image to be loaded to all 1000 of myArray texture members.

 

I could make a for loop that uses 'LoadTexture' (My texture loading function) to load an image to each texture member. But this is a very taxing process and takes a noticable amount of time to complete. At the end of my program I would then release() each texture via for loop.

 

So the other option is to create a LPDIRECT3DTEXTURE9 defaultImage. Load an image to defaultImage, then run a loop that:

myArray[i].texture = defaultImage;

 

The load time is unnoticible using this method.

 

So here's my question:

 

Do I have to release() all 1000 textures in myArray or do I only have to release() defaultImage?

For the record, I've tried realease()ing all 1000. Get the Unhandled exception at 0x00430906 error and have to break.

Does that mean I'm doing something wrong, or that I only have to release the one? An explination as to why would be nice as well.

 

Thanks for the help!

 

0

Share this post


Link to post
Share on other sites
Good practice is to AddRef defaultImage each time you assign it to myArray[i].texture. That way your object lifetime is properly managed.
1

Share this post


Link to post
Share on other sites

As a rule, for every resource Create(), you need a Dispose(). In your first example, you do 1000 Create()'s, (LoadTexture() is doing the Create() internally, but its still there) , so you'll need 1000 Dispose()'s, as each Sprite has its own unique texture object.

 

In the second example you create one texture that is shared amongst 1000 objects. This means there's one Texture, but 1000 references to it. Therefore, you need only 1 Dispose(). 

 

If all your sprite objects are going to be using the exact same texture, then definitely use the second method, otherwise you're using 999 times more texture memory and bandwidth for no reason.

 

I'm not sure if you've checked it out already, but it might be worthwhile looking into the built in sprite handling stuff of D3DX, such as ID3DXSprite. It's designed to be a lightweight way to draw lots of small textures to the screen and might be suitable for your application.

0

Share this post


Link to post
Share on other sites

As a rule, for every resource Create(), you need a Dispose().


In the second example you create one texture that is shared amongst 1000
objects. This means there's one Texture, but 1000 references to it.
Therefore, you need only 1 Dispose().

 

 
In theory yes, but in practice you should, especially in your second case, use AddRef() every time you pass a texture to another object - so when its shared by 1000 object it would have a RefCount of 1000 (+1?), and every time one object gets destroyed or accepts another texture handle, you call Release() - so only if no object has a reference, the texture gets freed.
1

Share this post


Link to post
Share on other sites

In the second example you create one texture that is shared amongst 1000 objects. This means there's one Texture, but 1000 references to it. Therefore, you need only 1 Dispose().

 

COM objects don't really work that way.  Because they're internally reference counted, if anything needs to hold on to the object for any reason, that assignment should be accompanied by an AddRef.  Then it can be safely Released later on, which will just decrement the reference count rather than destroying the object.  When the final Release happens, the object is destroyed.

 

The reason for this is that if something else Releases the texture while your myArray (to use the example here) is still using it, the texture won't be destroyed and myArray can continue to safely use it.

 

So in other words, yes, Release the defaultTexture 1000 times as you currently are, but also add an AddRef when you set them to your myArray, and the Release won't crash, giving you proper COM object lifetimes.

 

You see this kind of pattern all over the design of D3D; e.g. GetSurfaceLevel will require a Release otherwise the surface leaks, and - more relevant here - ID3DXEffect will AddRef on a SetTexture call.

1

Share this post


Link to post
Share on other sites

In the second example you create one texture that is shared amongst 1000 objects. This means there's one Texture, but 1000 references to it. Therefore, you need only 1 Dispose().

 

COM objects don't really work that way.  Because they're internally reference counted, if anything needs to hold on to the object for any reason, that assignment should be accompanied by an AddRef.  Then it can be safely Released later on, which will just decrement the reference count rather than destroying the object.  When the final Release happens, the object is destroyed.

 

The reason for this is that if something else Releases the texture while your myArray (to use the example here) is still using it, the texture won't be destroyed and myArray can continue to safely use it.

 

So in other words, yes, Release the defaultTexture 1000 times as you currently are, but also add an AddRef when you set them to your myArray, and the Release won't crash, giving you proper COM object lifetimes.

 

You see this kind of pattern all over the design of D3D; e.g. GetSurfaceLevel will require a Release otherwise the surface leaks, and - more relevant here - ID3DXEffect will AddRef on a SetTexture call.

 

Thanks for the help! Very informative. I'm new to development so I'll put some time into studying AddRef, as it sounds pretty vital.

But just for the sake of understanding, if I only release defaultImage like in the second example, is that causing a memory leak in myArray? Is it bad/dangerous coding or just improvable coding? (for the record I don't intend on settling for poor coding).

0

Share this post


Link to post
Share on other sites

If you're referring to the second example in your original post ("So the other option is to create a LPDIRECT3DTEXTURE9 defaultImage. Load an image to defaultImage, then run a loop that: myArray[i].texture = defaultImage;") - no, it won't leak.  This doesn't actually copy any data at all, so you still only have one copy of the texture.  Instead each myArray[i].texture will point to the original texture (if this concept sounds strange to you then I recommend doing some reading/learning/exercises on pointers).

 

Where you get trouble is when you Release defaultImage.  Each myArray[i].texture still points to defaultImage, but defaultImage is no longer valid for use.  Any operation on myArray[i].texture will - if you're lucky - crash immediately.  If you're unlucky it will continue working then give you weird behaviour (or a crash) some time later and you'll have no idea whatsoever where to even begin looking for the problem.  This normally happens the day before a release deadline.

1

Share this post


Link to post
Share on other sites

If you're referring to the second example in your original post ("So the other option is to create a LPDIRECT3DTEXTURE9 defaultImage. Load an image to defaultImage, then run a loop that: myArray[i].texture = defaultImage;") - no, it won't leak.  This doesn't actually copy any data at all, so you still only have one copy of the texture.  Instead each myArray[i].texture will point to the original texture (if this concept sounds strange to you then I recommend doing some reading/learning/exercises on pointers).

 

Where you get trouble is when you Release defaultImage.  Each myArray[i].texture still points to defaultImage, but defaultImage is no longer valid for use.  Any operation on myArray[i].texture will - if you're lucky - crash immediately.  If you're unlucky it will continue working then give you weird behaviour (or a crash) some time later and you'll have no idea whatsoever where to even begin looking for the problem.  This normally happens the day before a release deadline.

Ah yes! And the reason nothing is copied is because LPDIRECT3DTEXTURE9 is a pointer! I forgot about that. Okay, thanks for taking the time not just to answer, but to help me understand as well.

0

Share this post


Link to post
Share on other sites

Just to provide a counterpoint, it is also perfectly legal to only add one reference to the COM object and use it 1000 times - but then you are responsible to ensure that all 1000 of those copies are not released by some other code and that your single reference is only released when all 1000 copies are ready to be retired.  If you build a system around your copies that properly encapsulates all of the references in a safe way, then it is possible to (mis)use the object reference system in different ways.

 

That being said, the advice given by the others is perfectly correct - you probably should add a reference to each copy of the item in the array!

2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0