Jump to content
  • Advertisement
Sign in to follow this  
Duncanf

Creating a Texture from a Surface

This topic is 4837 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

Ello all, I need to create a texture from the depth buffer of the device. It's easy to create a depth surface (using device->CreateDepthStencilSurface(..)), and set it (using device->SetDepthStencilSurface(..)), but after I've rendered to those surfaces, how can I then create a texture from that surface? I'm trying to sort out a bug in my shadow mapping (see my reply here if you think you might be able to help with that technique). Cheers for any help, Duncan

Share this post


Link to post
Share on other sites
Advertisement
Make a new texture with dimensions the same as or larger than the surface. Then lock the surface and copy the data to a buffer. Unlock the surface and lock the texture. Copy the data from the buffer to the texture. That's all you need to do. The only catch is that the data on the surface and in the buffer will be in a different format from the data on your texture. In order to produce an easily viewable texture, you will need to write a conversion function to convert from whatever depth format you are using to whatever RGB format you pick.

Share this post


Link to post
Share on other sites
Cheers for the reply. I've not copied data in this way in Direct3D, so I'm not sure how to do it, and the API doesn't make it very clear. How do I know how much data to store from the surface to the buffer?

[EDIT]

Did this and it seems to work, though it doesn't make a difference to my shadow mapping problems :D

D3DLOCKED_RECT pLockedRect, pLockedRect2;
void* buff;
int size;
shadowMapDepthSurface->LockRect(&pLockedRect,NULL,D3DLOCK_READONLY);
size = shadowMapSize*pLockedRect.Pitch;
buff = malloc(size);
memcpy(buff,pLockedRect.pBits,size);
shadowMapDepthSurface->UnlockRect();
shadowMapDepthTexture->LockRect(0,&pLockedRect2,NULL,D3DLOCK_DISCARD);
memcpy(pLockedRect2.pBits,buff,size);
shadowMapDepthTexture->UnlockRect(0);
free(buff);

[Edited by - Duncanf on May 21, 2005 3:09:51 PM]

Share this post


Link to post
Share on other sites
You could use a pixel shader that renders the depth directly to the texture..

Share this post


Link to post
Share on other sites
Interesting... How could I do that? And to which texture would it render? I thought pixel shaders only had access to texture coordinates and colour values, I don't see how to do depth with that.

[Edited by - Duncanf on May 22, 2005 4:33:07 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Duncanf
Cheers for the reply. I've not copied data in this way in Direct3D, so I'm not sure how to do it, and the API doesn't make it very clear. How do I know how much data to store from the surface to the buffer?

[EDIT]

Did this and it seems to work, though it doesn't make a difference to my shadow mapping problems :D

D3DLOCKED_RECT pLockedRect, pLockedRect2;
void* buff;
int size;
shadowMapDepthSurface->LockRect(&pLockedRect,NULL,D3DLOCK_READONLY);
size = shadowMapSize*pLockedRect.Pitch;
buff = malloc(size);
memcpy(buff,pLockedRect.pBits,size);
shadowMapDepthSurface->UnlockRect();
shadowMapDepthTexture->LockRect(0,&pLockedRect2,NULL,D3DLOCK_DISCARD);
memcpy(pLockedRect2.pBits,buff,size);
shadowMapDepthTexture->UnlockRect(0);
free(buff);

That's no good; you didn't do any sort of conversion. shadowMapDepthTexture is presumably 32 bpp, probably D3DFMT_A8R8G8B8. shadowMapDepthSurface might be 16 bpp or 32 bpp (you didn't tell me) but in either case, you can't just copy directly like you did because you need to come up with a way to convert a height into a color. What you need is something like this (source tags are your friend):

D3DSURFACE_DESC kDepthSurfaceDesc;
int iDepthPitch;
D3DLOCKED_RECT kLockedRect;
BYTE* pBuffer;
shadowMapDepthSurface->GetDesc(&kDepthSurfaceDesc); // You need to know the size, width, height, and format of the surface
shadowMapDepthSurface->LockRect(&pLockedRect,NULL,D3DLOCK_READONLY);
iDepthPitch = kLockedRect.Pitch; // and the pitch
pBuffer = (BYTE*)malloc(kDepthSurfaceDesc.Size);
memcpy(pBuffer, kLockedRect.pBits, kDepthSurfaceDesc.Size);
shadowMapDepthSurface->UnlockRect();
shadowMapDepthTexture->LockRect(0,&kLockedRect,NULL,D3DLOCK_DISCARD);
for(int iX = 0; iX < kDepthSurfaceDesc.Width; iX++)
{
for(int iY = 0; iY < kDepthSurfaceDesc.Height; iY++)
{
// this assumes that you are using D3DFMT_D16 for the depth surface and that your texture is D3DFMT_A8R8G8B8.
int iDepth = *(WORD*)((BYTE*)pBuffer+(iY*iDepthPitch+iX*sizeof(WORD)));
*(D3DCOLOR*)((BYTE*)kLockedRect.pBits+(iY*kLockedRect.Pitch+iX*sizeof(D3DCOLOR))) = D3DCOLOR_ARGB(255, iDepth/256, iDepth/256, iDepth/256);
}
}
shadowMapDepthTexture->UnlockRect(0);
free(pBuffer);


I didn't have time to test that, but that should give you an idea of what it is really supposed to look like. Look up D3DLOCKED_RECT and the D3DFMT_s to learn more about 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!