SpriteBatch loses a texture

May 7, 2014 at 2:28 PM
Edited May 7, 2014 at 2:46 PM
I head in problem with a texture or SpriteBatch on WP8
I have the main game cycle (in CubeRenderer.cpp) like so:
void CubeRenderer::Update(float timeTotal, float timeDelta)
{
        //! update current screen
    sceene->Update(timeTotal, timeDelta);

    //! change screens (for test purpose)
    m_time += timeDelta;
    if (m_time >= m_timeTotal)
    {
        m_time = 0;
        ChangeScreen();   //<--- this simply change a Screen class to another and again
    }
}
void CubeRenderer::ChangeScreen()
{
    if (sceene != nullptr)
    {
        delete sceene;
        sceene = nullptr;
    }
    if (m_screenId == 1)
    {
        sceene = new GameSceene2(m_d3dDevice, spriteBatch);
        m_screenId = 2;
    }
    else if (m_screenId == 2)
    {
        sceene = new GameSceene(m_d3dDevice, spriteBatch);
        m_screenId = 1;
    }
}
void CubeRenderer::Render()
{
     //.....
    
     // render current screen
     sceene->Render();
}
So, it's main game logic.
In Screen class I create a texture:
CreateDDSTextureFromFile(m_device.Get(), L"Assets/txt.DDS", nullptr, _texture.ReleaseAndGetAddressOf());
_texture is a ComPtr:
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> _texture;
And in Render method of the Screen I draw this texture.

Run this.. going going.. and throw the error in "__abi_FailFast".. every time in exactly time. :(
Please, help me.
May 7, 2014 at 2:30 PM
Edited May 7, 2014 at 2:31 PM
Forgot...

In Screen class in Render method I draw a texture.
If I comment the line of the code with a draw, than have no errors.
May 7, 2014 at 4:45 PM
brrrrrr...
I have recode this example.
I add a TextureManager
class TextureManager
{
public:
    TextureManager(ID3D11Device* device) {m_device = device;}
    ~TextureManager(){}
    void CreateTexture()
    {
        DirectX2::CreateDDSTextureFromFile(m_device.Get(), L"Assets/LoadingScreenStep.DDS", nullptr, &_texture); 
    }
    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> GetTexture() {return _texture;}
private:
    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> _texture;
    Microsoft::WRL::ComPtr<ID3D11Device> m_device;
};
And add this TextureManager to main class (in CubeRenderer.cpp).
Then add method than delete exist TextureManager and create new one.
The texture released and created again, not so?
void CubeRenderer::RecreateManager()
{
    if (manager != nullptr)
    {
        delete manager;
        manager = nullptr;
    }
    manager = new TextureManager(m_d3dDevice.Get());
    manager->CreateTexture();
}
Now, Update method is:
void CubeRenderer::Update(float timeTotal, float timeDelta)
{
        //! update current screen
    sceene->Update(timeTotal, timeDelta);

    //! change screens (for test purpose)
    m_time += timeDelta;
    if (m_time >= m_timeTotal)
    {
        m_time = 0;
        RecreateManager();  // <----- ADD THIS. recreate TextureManager
        ChangeScreen(); 
    }
}
And in Screen class I draw the texture from this TextureManager (send it to Screen as referense).

It is work, and dont crush. What is this? O_o
Coordinator
May 7, 2014 at 5:02 PM
Enabling Break on C++ Exceptions in the debugger will make it easier to track these down. Likely the file path you provided is invalid or the file is missing from your deployment.
May 7, 2014 at 5:56 PM
Thank.
Break on C++ I have enabled, it didn help me.
"Likely the file path you provided is invalid or the file is missing from your deployment"
In Update method im recreate texture every 1 second. First ~10 seconds all going well and then crush. How path missing?(
And if I recreate the texture in TextureManager every 1 second also then it didnt miss?

I dont understand this)
May 7, 2014 at 6:23 PM
Edited May 7, 2014 at 6:26 PM
Ohhh.
If I create the texture in TextureManager and draw this texture in a Sceene like:
this->GetSpriteBatch()->Draw(manager->GetTexture().Get(), XMFLOAT2(0, 0));
see manager->GetTexture().Get()
and delete and create again and again TextureManager and Sceenes - it's OK.

If I in a Sceene get references on this texture from TextureManager:
   Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> _texture;
   //....
   _texture = _manager->GetTexture();
and draw this texture from Sceene class:
this->GetSpriteBatch()->Draw(_texture.Get(), XMFLOAT2(0, 0));
_see texture.Get()
then it crushes.
Crushes not on start the app. It happen after ~10 seconds.

What wrong with my mind of ComPtr?
May 7, 2014 at 6:36 PM
Edited May 7, 2014 at 6:38 PM
Aha...
In my TextureManager I made some changes.
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> GetTexture() {return _texture;}
This code is evel.

I change it to:
void GetTexture(ID3D11ShaderResourceView** txt) { (*txt) = _texture.Get(); }
and init my texture in a Sceene:
_manager->GetTexture(_texture.ReleaseAndGetAddressOf());
So, ComPtr to count references well.
Marked as answer by walbourn on 5/7/2014 at 1:29 PM