Original Post
EDIT: Original problem solved, please see fourth post! I've been attempting to set up simple omni-directional shadow mapping. I appeared to have it sorted but then realised that it wasn't resetting correctly. I eventually realised that performing multiple COM releases fixed the problem but it made mad me think that I'm perhaps not going about this as efficiently as I could be. If anyone could take a look at my code below and tell me if all these COM releases really are the only way to keep changing render targets I would be very grateful. (also is it necessary for me to recreate the cube texture after the reset or is there a cleaner way?) [Edited by - OakWood on August 25, 2007 4:31:56 PM]
//I naturally need these releases
void ShadowMapDemo::onLostDevice()
{
ReleaseCOM(mSurface);
ReleaseCOM(mShadowMap);
mGfxStats->onLostDevice();
HR(mFX->OnLostDevice());
}
ShadowMapDemo::onResetDevice()
{
HR(mFX->OnResetDevice());
//create cube map Is there a better place to create the cubemap?
HR(D3DXCreateCubeTexture(gd3dDevice, 512, D3DX_DEFAULT, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &mSM));
buildProjMtx();
}
void ShadowMapDemo::drawScene()
{
HRESULT hr;
UINT nIndex;
D3DXMATRIXA16 cubeProject, cubeView, lightTranslate;
//set projection matrix for 90 degree field of view
D3DXMatrixPerspectiveFovLH(&cubeProject, D3DX_PI * 0.5f, 1.0f, 0.5f, 1000.0f ) ;
//set translation by subtracting by light position
D3DXMatrixTranslation(&lightTranslate, -LightPos->x, -LightPos->y, -LightPos->z);
//loop round for all six faces of the cube map
for(nIndex = 0; nIndex <6; nIndex++)
{
//obtain a pointer to the desired cube map surface
HR(mShadowMap->GetCubeMapSurface((D3DCUBEMAP_FACES)nIndex,0,&mSurface));
//draw to the cube map
HR(gd3dDevice->SetRenderTarget(NULL, mSurface));
HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0));
HR(gd3dDevice->BeginScene());
//change to shadow map tech
HR(mFX->SetTechnique(mhBuildShadowMapTech));
//create correct matrix for this face
D3DXMatrixMultiply (&cubeView, &lightTranslate, &D3DUtilGetCubeMapViewMatrix(nIndex) );
D3DXMatrixMultiply (&cubeView, &cubeView, &cubeProject );
UINT numPasses = 0;
HR(mFX->Begin(&numPasses, 0));
HR(mFX->BeginPass(0));
// Set Matrix
HR(mFX->SetMatrix(mhLightWVP, &cubeView));
HR(mFX->CommitChanges());
//true is a bool indicating it's a shadow map pass (ie. don't set render states)
drawGrid(true);
drawCylinders(true);
drawSpheres(true);
HR(mFX->EndPass());
HR(mFX->End());
HR(gd3dDevice->EndScene());
//release surface to prevent leak. DO I HAVE TO RELEASE THIS EACH LOOP?
ReleaseCOM(mSurface);
}
//begin normal render pass
//Set render target as backbuffer
HR(gd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &mSurface));
HR(gd3dDevice->SetRenderTarget(NULL, mSurface));
// Clear the backbuffer and depth buffer.
HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0));
HR(gd3dDevice->BeginScene());
HR(mFX->SetTechnique(mhTech));
// Setup the rendering FX
HR(mFX->SetValue(mhAmbientLight, &mAmbientLight, sizeof(D3DXCOLOR)));
HR(mFX->SetValue(mhDiffuseLight, &mDiffuseLight, sizeof(D3DXCOLOR)));
HR(mFX->SetValue(mhSpecLight, &mSpecLight, sizeof(D3DXCOLOR)));
HR(mFX->SetValue(mhLightPosW, LightArray[0], sizeof(D3DXVECTOR3)));
HR(mFX->SetValue(mhLightPosW2, LightArray[1], sizeof(D3DXVECTOR3)));
HR(mFX->SetValue(mhAttenuation012, &mAttenuation012, sizeof(D3DXVECTOR3)));
// Begin passes.
UINT numPasses = 0;
HR(mFX->Begin(&numPasses, 0));
for(UINT i = 0; i < numPasses; ++i)
{
HR(mFX->BeginPass(i));
drawGrid(false);
drawCylinders(false);
drawSpheres(false);
HR(mFX->EndPass());
}
HR(mFX->End());
HR(gd3dDevice->EndScene());
//release to prevent leak
ReleaseCOM(mSurface);
// Present the backbuffer.
HR(gd3dDevice->Present(0, 0, 0, 0));
}

