CreateDDSTextureFromFile crash

Jan 25, 2014 at 10:00 PM
Hi!

I'm working on a game project for windows phone. I stuck with this problem:

I'm using animated sprite(you can think of a GIF). I call CreateDDSTextureFromFile from main. But after some time application crashes. I think that i might be about calling CreateDDSTextureFromFile may cause overload memory. Is there a way to unload texture? Or any idea to make animated sprites(like gif animations)

<code>

void char::loadTexture(ID3D11Device* d3dDevice, int gif)
{

m_Texture=nullptr;
if (gif==0)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left.dds", nullptr, &m_Texture);

if (gif==1)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run1.dds", nullptr, &m_Texture);

if (gif==2)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run2.dds", nullptr, &m_Texture);

if (gif==3)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run3.dds", nullptr, &m_Texture);

if (gif==4)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run4.dds", nullptr, &m_Texture);

if (gif==5)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run1.dds", nullptr, &m_Texture);

if (gif==6)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run2.dds", nullptr, &m_Texture);

if (gif==7)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run3.dds", nullptr, &m_Texture);

if (gif==8)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run4.dds", nullptr, &m_Texture);

if (gif==9)
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right.dds", nullptr, &m_Texture);

}

<code>
Coordinator
Jan 26, 2014 at 7:00 AM
Edited Jan 27, 2014 at 8:27 PM
Without any sense of how large these .DDS files are it's not easy to tell what's happening. If they are reasonably sized and block compressed, they shouldn't tie up that much memory. It shouldn't be a big deal to load and keep nine textures resident, but it looks to me like you are 'leaking' your texture--i.e. you are creating it, using it, and then when you create the next one frame you are losing track of the first one but not releasing it.

Direct3D 11 Textures and Block Compression

Direct3D SDK Debug Layer Tricks

Direct3D objects are reference counted. Your code here doesn't indicate what the type is for m_Texture. If it is a ID3D11ShaderResourceView*, then you are definitely leaking the resource. Use of Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> is definitely recommended here.

Managing the Lifetime of an Object
COM Coding Practices

Smart Pointers (Modern C++)
Microsoft::WRL::ComPtr is essentially the same as CComPtr mentioned in this doc page

For performance, you really should only load your nine textures at startup of your application, and then just reuse them. You should not be loading the frame from disk over and over again... Do something like this instead:
class char
{
...
    Microsoft::WRL:ComPtr m_Texture[9];
...
};

void char::loadTexture(ID3D11Device* d3dDevice)
{
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left.dds", nullptr, m_Texture[0].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run1.dds", nullptr, m_Texture[1].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run2.dds", nullptr, m_Texture[2].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run3.dds", nullptr, m_Texture[3].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-left-run4.dds", nullptr, m_Texture[4].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run1.dds", nullptr, m_Texture[5].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run2.dds", nullptr, m_Texture[6].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run3.dds", nullptr, m_Texture[7].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right-run4.dds", nullptr, m_Texture[8].ReleaseAndGetAddressOf()); 
CreateDDSTextureFromFile(d3dDevice, L"Assets/jester-right.dds", nullptr, m_Texture[9].ReleaseAndGetAddressOf()); 
 } 
Marked as answer by walbourn on 1/25/2014 at 11:07 PM
Jan 26, 2014 at 3:29 PM
thank you for your answer :)
I want to say that my texture size is 80X160. I don't think it is big. And I don't have any other textures.
I couldn't hande WRL since I am a newbie :\
but you gave me idea. So I used array instead of WRL.
Simply I created an array: array<ID3D11ShaderResourceView*, 10> m_Texture;
I guess performance wouldn't be much different from yours. And I don't know any other methods to create DDS texture.
So do you think it will do the same?
Coordinator
Jan 26, 2014 at 7:53 PM
Edited Jan 27, 2014 at 12:38 AM
The key point is that you were leaking textures. If you stop the leak, it should work.

Definitely take some time to read that article on Smart-pointers. They will make your life as a newbie much easier than you realize...

Really the most 'optimal' way to do what you want to is called a sprite sheet. Rather than creating a texture for each individual frame of the animation, you would pack all the frames into a single texture and then render different parts of that texture. Ideally you'd pack a bunch of different characters and frames together, limited by the size limit of textures depends on your target Feature Level (for phone, it's 4096 for Feature Level 9.3 which could hold 1275 80x160 sprite frames; for Surface it would be 2048 for Feature Level 9.1 which could hold 300 80x160 sprite frames). This is demonstrated in a XNA Game Studio sample. I have a work-item to write a C++ version of it for DirectXTK someday...
Marked as answer by walbourn on 1/27/2014 at 12:27 PM