Jump to content
  • Advertisement
Sign in to follow this  
NovaCaine

Saving Depth/Stencil buffer to file

This topic is 4811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey all, I'm having a spot of trouble saving my Depth/Stencil buffer to a file.
HRESULT hr;
IDirect3DSurface9* pTemp;
IDirect3DSurface9* pTemp2;

m_D3DDevice->CreateOffscreenPlainSurface( m_iWidth, m_iHeight, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTemp, NULL );
hr = m_D3DDevice->CreateOffscreenPlainSurface( m_iWidth, m_iHeight, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTemp2, NULL );
				
if( hr != D3D_OK ) {
	MessageBox( m_hWnd, "Surface Creation Failed", "BUGGER", MB_OK );
}

hr = m_D3DDevice->GetDepthStencilSurface( &pTemp );
				
if( hr != D3D_OK ) {
	MessageBox( m_hWnd, "GetDepthStencilSurface Failed", "BUGGER", MB_OK );
}

m_D3DDevice->UpdateSurface( pTemp, NULL, pTemp2, NULL );

hr = D3DXSaveSurfaceToFile( "Temp.tga", D3DXIFF_TGA, pTemp, NULL, NULL );

if( hr != D3D_OK ) {
	MessageBox( m_hWnd, "D3DXSaveSurfaceToFile Failed.", "BUGGER", MB_OK );
}

pTemp->Release();
pTemp2->Release();

it all seems to work file until i try to update the surface where i get: Direct3D9: (ERROR) :Source and dest surfaces are different formats. UpdateSurface fails Direct3D9: (ERROR) :This format is not supported for SystemMem, Scratch or Managed textures Direct3D9: (ERROR) :Failure trying to create a texture the last 2 come from when it executes the SaveSurfaceToFile function. what am i doing wrong? my guess would have been the z/stencil buffer is a different format than my surfaces, but if i try to set it to be the same (D3DFMT_D24S8) i get an error that the format is not supported. any help would be great. thx in advance

Share this post


Link to post
Share on other sites
Advertisement
D3DXSaveSurfaceToFile doesn't support depth-stencil buffers to the best of my knowlege. How would you convert depth information into pixel information?

Your best bet is creating a lockable depth buffer (D3DFMT_D16_LOCKABLE or D3DFMT_D32F_LOCKABLE), and locking it to save the values to a file.
As far as I know, you can't save stencil buffer information, or lock the stencil buffer.

Edit: About your errors:
The first error is because you create an A8R8G8B8 surface for pTemp2, but pTemp1 ends up as whatever format your depth-stencil surface is in. GetDepthStencilSurface() will overwrite the surface that's there (So you also have a resource leak).
The second and third errors are probably because you can't save depth-stencil formats to file using D3DXSaveSurfaceToFile().

Edit 2: What are you trying to do here anyway? If you want to save the depth buffer as an image, the best way would be to lock it, copy the data into a D3DFMT_L8 format surface (Lock them both, and do the conversion yourself), then save the D3DFMT_L8 surface with D3DXSaveSurfaceToFile().

Share this post


Link to post
Share on other sites
cheers for the quick reply evil steve,

Quote:

The first error is because you create an A8R8G8B8 surface for pTemp2, but pTemp1 ends up as whatever format your depth-stencil surface is in. GetDepthStencilSurface() will overwrite the surface that's there (So you also have a resource leak).


yeah, i just saw this after posting.

Quote:

Your best bet is creating a lockable depth buffer (D3DFMT_D16_LOCKABLE or D3DFMT_D32F_LOCKABLE), and locking it to save the values to a file.


just so i can clarify, this basically means creating the depth/stencil buffer from scratch, not with the EnableAutoDepthStencil member of my Present parameters.


Quote:

As far as I know, you can't save stencil buffer information, or lock the stencil buffer.


i'm sure there must be a way, as i know Renderware is capable of this. Not sure if it is part of it's own functionality or what, but i have seen it done.

Share this post


Link to post
Share on other sites
In your presentation parameters, when you create the device, you can specify one of those formats for the depth buffer format, you don't have to create it from scratch.

I also noticed that according to the D3DXSaveSurfaceToFile documentation (In my SDK at least, October 2004), it says that it can't save as TGA or PPM files.

The only way you can get access to the depth buffer is if you use a lockable format, and the only two lockable formats availiable don't have stencil information with them. The reason being that the graphics card might have the depth-stencil information in a special format, for performance reasons - or it might even be two seperate buffers, or compressed in some way.

Apparently it's possible to do what you're trying to do in OpenGL. Perhaps Renderware uses OGL? (I know nothing about either Renderware or OpenGL)

Share this post


Link to post
Share on other sites
Quote:

I also noticed that according to the D3DXSaveSurfaceToFile documentation (In my SDK at least, October 2004), it says that it can't save as TGA or PPM files.


i read that as well, but it seems to work fine.

one more question, can i still read values from a buffer that i cant lock?

even the raw data would help, performance isn't an issue.

my plan is if i can get the raw data, convert it into rgb values( taking 8 bits for each colour ) then writing this manually to a file.

if you (or anyone else reading this) cannot think of any way i might be able to do this, maybe i should try doing this in OpenGL instead

Share this post


Link to post
Share on other sites
Quote:
Original post by NovaCaine
one more question, can i still read values from a buffer that i cant lock?
Nope. The only way to get information out of a non-lockable depth buffer would be with IDirect3DDevice::StretchRect() or IDirect3DDevice::UpdateSurface(), but StretchRect() can only copy to a depth-stencil buffer of the same format, which would mean you'd just have two copies of the data in a useless format. UpdateSurface() can only copy data from a system memory pool surface, and depth-stencil surfaces need to be in the default pool.
So it doesn't seem like it. Perhaps someone else can confirm/deny this?

What are you trying to do this for anyway? There may be a better way to do it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!