[DirectX 9] Mesh gone after device reset

Started by
16 comments, last by Tispe 13 years, 1 month ago
Hi, I've a probably easy-to-solve problem but it seems really strange to me. After a device reset my mesh is not being rendered anymore. Here is my code:

Mesh::Mesh(D3DDevice* device, std::string folder , std::string file, bool optimize)
{
	_device = device;

	ID3DXBuffer *mtrlBuffer, *adjBuffer;
	D3DXLoadMeshFromX((folder + file).c_str(), D3DXMESH_MANAGED,
					  _device, &adjBuffer, &mtrlBuffer, 0,
					  &_numFaces, &_mesh);

	D3DXMATERIAL* mtrl = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

	for(uint i = 0; i < _numFaces; i++)
	{
		_material.push_back(mtrl.MatD3D);

		if(mtrl.pTextureFilename != 0)
		{
			D3DTexture* tex;
			std::string f = folder + mtrl.pTextureFilename;
			D3DXCreateTextureFromFileEx(_device, f.c_str(), 0,      
                                                    0, 0, 0,
						    D3DFMT_UNKNOWN,  
                                                    D3DPOOL_MANAGED, 
                                                    D3DX_DEFAULT,
						    D3DX_DEFAULT, 0, NULL, 
                                                    NULL, &tex);
			_texture.push_back(tex);
		}
		else
			_texture.push_back(0);
	}

	mtrlBuffer->Release();

	if(optimize)
	{
		_mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT |
                                       D3DXMESHOPT_COMPACT |
  				       D3DXMESHOPT_VERTEXCACHE,
				       (DWORD*)adjBuffer->GetBufferPointer(),
				       0, 0, 0);
	}

	adjBuffer->Release();
}

void Mesh::render()
{
	for(uint i = 0; i < _numFaces; i++)
	{
		_device->SetMaterial(&_material);
		_device->SetTexture(0, _texture);
		HRESULT hr = _mesh->DrawSubset(i);
		if(FAILED(hr))
			MessageBox(NULL, DXGetErrorString(hr), "", MB_OK);
	}
}


The things that are strange to me are that -the mesh is in the managed pool -the texture pointers are not 0 -the DrawSubset() function doesn't fail -the output of direct3d9 looks fine Any ideas what I'm doing wrong? Thanks in advance
Advertisement
Have you tried enabling the debug runtimes to see if they give you any warnings? Also, have you tried looking at a frame in PIX to see what's going on?
Quote:Original post by MJP
Have you tried enabling the debug runtimes to see if they give you any warnings? Also, have you tried looking at a frame in PIX to see what's going on?


The D3D9 debug runtime is enabled but I see no unusual output as I said before.

I found out that the mesh isn't gone completely. It just renders only 1 triangle which is black. I couldn't see it at first because backface culling is enabled.

I don't really know what to do with the results of PIX since I have never used it before.

Do you use the same ResetDevice() function when you reset as you do when you initially create the device? If the mesh renders correctly just after you create the device and mesh, it sounds like you set different parameters from your initial device creation when you reset the device. Check all your present params, lighting params, render states, etc., to ensure they're the same when you both create and reset the device.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Thanks for you help,

it was in fact because I didn't reset the renderstates and lights.
I thought these options wouldn't be affected when the device is lost.
Quote:Original post by Soul Reaver
Thanks for you help,

it was in fact because I didn't reset the renderstates and lights.
I thought these options wouldn't be affected when the device is lost.
When the device is reset, it's reset to the same state it was in when the device was created - so ALL device state is reset.
Glad you found the problem. I use the same ResetDevice() routine following both creation and reset to ensure things stay the same. You might try that.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Sorry for the bump but what code do you use for restoring the meshes/lights after the App regains focus?

Do you cycle through each Mesh object or something?

Edit: I though I had to readress textures and materials.

Fix: I made a new function to set all render states which is called at startup and after device gets focus

Sorry for the bump but what code do you use for restoring the meshes/lights after the App regains focus?

Do you cycle through each Mesh object or something?

Not sure what you mean by "restore." In any case, what you do in response to WM_SETFOCUS depends on what you do in response to WM_KILLFOCUS.

If you're having a problem, you should describe it.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

As an aside, you shouldn't be performing lost device handling in response to WM_ messages. It will only end in tears.

To quote from the SDK:
By design, the full set of scenarios that can cause a device to become lost is not specified. Some typical examples include loss of focus, such as when the user presses ALT+TAB or when a system dialog is initialized. Devices can also be lost due to a power management event, or when another application assumes full-screen operation.[/quote]
In other words, you aren't capturing all events that can cause a device to become lost, and the time will come when it bites you. Check the HRESULT of your IDirect3DDevice9::Present (or IDirect3DSwapChain9::Present) call for D3DERR_DEVICELOST instead.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement