[D3D11] Depth buffer does nothing

Started by
30 comments, last by 360GAMZ 12 years, 4 months ago
Hey,
with the recode of the core of my engine, most rendering functionality was gone.
That was also the case with the depth buffer, and now I would like to re-implement it finally.
However, I would not post here if that would work out of the box.

When I set my DepthStencilView and DepthStencilState, my scene just looks like no depth buffer would be there at all.
And I have no idea why.

It would be great if you could have a look over my code and maybe tell me what is wrong.

Here is the creation of the texture/view:
RenderToDepthStencilStruct(UINT SizeX,UINT SizeY,DXGI_FORMAT Format, HRESULT* Result=NULL, DXGI_FORMAT DSVFormat=DXGI_FORMAT_UNKNOWN, DXGI_FORMAT SRVFormat=DXGI_FORMAT_UNKNOWN)	{		HRESULT hr=S_OK;		Texture=NULL;		ShaderResView=NULL;		DepthStencilView=NULL;		if(SizeX == 0 || SizeY == 0)		{			LogError() << L"SizeX or SizeY can't be 0";		}		if(Format==0)		{			LogError() << L"DXGI_FORMAT_UNKNOWN (0) isn't a valid texture format";		}		//Create a new render target texture		D3D11_TEXTURE2D_DESC Desc;		ZeroMemory( &Desc, sizeof( D3D10_TEXTURE2D_DESC ) );		Desc.ArraySize = 1;		Desc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;		Desc.Usage = D3D11_USAGE_DEFAULT;		Desc.Format = Format;		Desc.Width = SizeX;		Desc.Height = SizeY;		Desc.MipLevels = 1;		Desc.SampleDesc.Count = 1;		LE(DXUTGetD3D11Device()->CreateTexture2D(&Desc,NULL,&Texture));		//Create a render target view		D3D11_DEPTH_STENCIL_VIEW_DESC DescDSV;		DescDSV.Format = (DSVFormat != DXGI_FORMAT_UNKNOWN ? DSVFormat : Desc.Format);		DescDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;		DescDSV.Texture2D.MipSlice = 0;		DescDSV.Flags=0;		LE(DXUTGetD3D11Device()->CreateDepthStencilView((ID3D11Resource *)Texture,&DescDSV,&DepthStencilView));		// Create the resource view		D3D11_SHADER_RESOURCE_VIEW_DESC DescRV;		DescRV.Format = (SRVFormat != DXGI_FORMAT_UNKNOWN ? SRVFormat : Desc.Format);		DescRV.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;		DescRV.Texture2D.MipLevels = 1;		DescRV.Texture2D.MostDetailedMip = 0;		LE(DXUTGetD3D11Device()->CreateShaderResourceView( (ID3D11Resource *)Texture, &DescRV, &ShaderResView ));		if(FAILED(hr))		{			LogError() << L"Coould not create ID3D11Texture2D, ID3D11ShaderResourceView, or ID3D11DepthStencilView. Killing created resources (If any).";			ReleaseAll();			if(Result)*Result=hr;			return;		}		LogInfo() << L"RenderToDepthStencilStruct: Successfully created ID3D11Texture2D, ID3D11ShaderResourceView, and ID3D11DepthStencilView.";		if(Result)*Result=hr;	}


Thats how I call it:

DepthBuffer=new RenderToDepthStencilStruct(SizeX, SizeY, DXGI_FORMAT_R32_TYPELESS, &hr, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_R32_FLOAT);


And here I set the view and the state:
DXUTGetD3D11DeviceContext()->OMSetRenderTargets(1, &RenderTargetView, DepthBuffer->GetDepthStencilView());	DXUTGetD3D11DeviceContext()->OMSetDepthStencilState(DefaultDepthStencilState, 0);


I had this problem before, and I even made a thread for it: http://www.gamedev.net/community/forums/topic.asp?topic_id=574751

But there I just forgot to set the depth stencil state. Now I do it, and I don't know what's wrong...
Advertisement
You forgot to clear the depth buffer every frame. That's probably what's causing the problem.

It's : ID3D11DeviceContext::ClearDepthStencilView.

Click here for ClearDepthStencilView documentation at MSDN
No, I do clear the depth buffer.

Here is my whole rendering function:
HRESULT SceneRenderer_ToSwapchain::RenderScene(Scene* Scene){	HRESULT hr=S_OK;	if(!Scene)	{		LogError() << L"Invalid scene: " << Scene;		return E_FAIL;	}	DXUTGetD3D11DeviceContext()->ClearRenderTargetView(RenderTargetView,(float *)&D3DXVECTOR4(0.0,0.0,0.0,1));	DXUTGetD3D11DeviceContext()->ClearDepthStencilView(DepthBuffer->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1, 0);	//Set the RTV	DXUTGetD3D11DeviceContext()->OMSetRenderTargets(1, &RenderTargetView, DepthBuffer->GetDepthStencilView());	DXUTGetD3D11DeviceContext()->OMSetDepthStencilState(DefaultDepthStencilState, 0);	D3D11_VIEWPORT vp;	vp.MinDepth=0;	vp.MaxDepth=0;	vp.TopLeftX=0;	vp.TopLeftY=0;	vp.Width=SwapChainDesc.BufferDesc.Width;	vp.Height=SwapChainDesc.BufferDesc.Height;	DXUTGetD3D11DeviceContext()->RSSetViewports(1,&vp);	//Update projection matrix to ours	GetProjectionMatrix(&Scene->GetBasicObjectInfo()->Projection);	//Prerender	Scene->PreRenderWorld();	//Render scene	Scene->RenderScene(RG_NORMAL);	//Render post processing	Scene->PostRenderWorld();	return S_OK;}


And the problem does not look like a not-cleared depth buffer...
Here is a picture of a simple test scene:

(That are 5 meshes)

You can see that the ducks are overdrawing each other.
With a working depth buffer everything should render normal.
Quote:
Desc.Width = SizeX;
Desc.Height = SizeY;


Does SizeX and SizeY have the same values as the size of the framebuffer?

In my code, I don't call OMSetRenderTargets every frame. I only call it when I create the depth and frame buffer and whenever I resize the window.

Double check and make sure the smaller ducks have a larger z-coordinate than the larger ones (assuming they're all lining up along the z-axis).

Also, does DepthBuffer->GetDepthStencilView() return a valid pointer?

[Edited by - 16bit_port on October 1, 2010 4:40:24 PM]
Quote:
Does SizeX and SizeY have the same values as the size of the framebuffer?


I use the same variables for resizing my swapchain. I also checked this.
If they wouldn't be the same, the debug layer would give me some hints, though.

Quote:
In my code, I don't call OMSetRenderTargets every frame. I only call it when I create the depth and frame buffer and whenever I resize the window.


I have some multiple viewports, each with it's own swapchain and stuff. That's why I need that.

Quote:
Double check and make sure the smaller ducks have a larger z-coordinate than the larger ones (assuming they're all lining up along the z-axis).


Same scene, viewing from the top:


Quote:
Also, does DepthBuffer->GetDepthStencilView() return a valid pointer?

I just triple checked this ... :-/
Quote:
I have some multiple viewports, each with it's own swapchain and stuff. That's why I need that.


I would temporarily disable the other viewports and make sure you're not accidentally using the other viewports' resource views and whatnot. Also it'll just make debugging easier.
Quote:
I would temporarily disable the other viewports and make sure you're not accidentally using the other viewports' resource views and whatnot. Also it'll just make debugging easier.


There are no other than the main-viewport open at the moment. They only pop up if I want them to do. [smile]
For the "Format", I would pass in DXGI_FORMAT_D24_UNORM_S8_UINT. Also, try specifying NULL for the second param in CreateDepthStencilView().
Still the same ...
Damn, I'm sitting like 4 hours now on this stupid problem! And I bet at the end it was just a tiny little mistake by me. It's always like that.
Did you try specifying NULL for the second param in CreateDepthStencilView()? (I had JUST edited that into the previous reply so I don't know if you caught it or not.)

If this isn't the solution, then I don't know what is :
Move

DXUTGetD3D11DeviceContext()->ClearDepthStencilView(DepthBuffer->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1, 0);

so that it is called AFTER

DXUTGetD3D11DeviceContext()->OMSetRenderTargets(1, &RenderTargetView, DepthBuffer->GetDepthStencilView());
DXUTGetD3D11DeviceContext()->OMSetDepthStencilState(DefaultDepthStencilState, 0);

This topic is closed to new replies.

Advertisement