Skip to main content
GameDev.net gamedev.net
🔒 Locked

EDIT: Weird problem with cube maps when increasing their size.

Started by OakWood Aug 23, 2007 at 5:03 PM 4 replies 700+ views
Original Post
OakWood
OakWood
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?)

//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));
}
 







[Edited by - OakWood on August 25, 2007 4:31:56 PM]
Matt Aufderheide
Matt Aufderheide
Instead of getting the surfaces each time you render, just store them in a globally accessable array at creation time.

i just create the cubemaps and get the surfaces once, and store them all.. My light managemnt code ensures that I never add or destroy lights..just move them around, so there is no need to dynamically create new cubemaps or get surface pointers..
OakWood
OakWood
Thanks, I'll give that a go in future. This was my first mockup of shadow maps I clumsily welded into old code, so I don't really have any system for managing lights yet. Thanks for the reply.
OakWood
OakWood
AAAAaaagh. Just tried increasing my cube maps from 512 to 1024 and ended up with this happening when I shadow map:
Image Hosted by ImageShack.us

Does anyone have any idea why this might happen?
It seems to be rendering the screen to the shadow map in some way and yet I've only changed the size of the cubemap. I also tried decreasing the size and that worked fine.
Just to prove it was working before I increased the size of the cubemaps:
Image Hosted by ImageShack.us
OakWood
OakWood
Sounds like that could well be the problem. Sorry if this is a stupid question, but I've tried google and I can't seem to find out how to change the size of the depth buffer. Could someone please enlighten me as to how I can alter the size of the depth buffer.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.