Sign in to follow this  
mateo

direct3d9 - copying backbuffer to a texture

Recommended Posts

Would anyone happen to know how to copy a section of the backbuffer to a texture? And provide some example code to do it?

Share this post


Link to post
Share on other sites
Hey,
I'm not 100% sure about this, but I think it should work. Create a texture and access its surface. Then get the backbuffer from your DirectX device and use UpdateSurface to copy the portion of the backbuffer surface to your texture's surface.

Something like this maybe:


...

IDirect3DTexture9* texture = NULL;
IDirect3DSurface9* textureSurface = NULL;
IDirect3DSurface9* backBufferSurface = NULL;

// Make a texture of some size
D3DXCreateTexture(width, height, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, &texture, NULL);

// Get its surface
texture->GetSurfaceLevel(0, &textureSurface);

// Get the backbuffer
dxDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backBufferSurface);

// Determine how much to copy and where to start copy it to
RECT areaToCopy = { 0, 0, 640, 480 };
POINT destinationPoint = { 0, 0 };

// Copy the backbuffer surface to the texture
dxDevice->UpdateSurface(backBufferSurface, &areaToCopy, textureSurface, &destinationPoint);

...



Didn't test it. Hope it works. Good luck.

Share this post


Link to post
Share on other sites
I don't think it's possible to only copy part of the backbuffer to a texture, but by using GetRenderTargetData() you should be able to copy the complete backbuffer to a texture that's in system memory and go from there.

Share this post


Link to post
Share on other sites
Quote:
Original post by remigius
I don't think it's possible to only copy part of the backbuffer to a texture...


Change up the texture coordinates. If you want to copy the top-left quarter of the buffer, u: [0, 0.5] and v: [0, 0.5].

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i think that IDirect3DDevice9::StretchRect() could be what you're looking for...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Yes, StretchRect will do the trick nicely.

Share this post


Link to post
Share on other sites
idramire: I tried the example code, but didn't work, look in the directx sdk and noticed that UpdateSurface requires that the source surface be in system memory, I want to copy from surface-surface.

remigius: I want to be able to copy only a portion of the backbuffer.

I've tried StretchRect and it keeps returning with an invalid call error.

Share this post


Link to post
Share on other sites
Quote:
I've tried StretchRect and it keeps returning with an invalid call error.


StretchRect probably is the only option if you only wish to copy part of the backbuffer (though you might work around that using alternative texture coordinates like mentioned above). If you get an InvalidCallException, try enabling the Direct3D debug runtime, it will tell you something that makes some more sense.

I don't have the docs around atm, but iirc you can only use StretchRect on the backbuffer to stretch to a texture that's a render target (since the backbuffer is also a render target). There are some more restrictions on the surface properties and I believe not all devices support streching and/or partial copies (making StretchRect pretty much equivalent to UpdateSurface, safe for the surface requirements. This should only be an issue for old hardware though, afaik).

Hope this helps & sorry about the misinformation in my previous post, I forgot about good ol' StretchRect :)

Share this post


Link to post
Share on other sites
With StretchRect, both surfaces need to be in the default memory pool. Your backbuffer will be, but your texture surface may not be. As remigius suggested, if you install the debug runtimes, D3D will give you more information about why it's failing.
Also:
Quote:
If the source or destination surface is a texture surface (or a cube texture surface), you must use a Direct3D 9 driver that supports D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES


I'd highly recommend using render-to-texture for this though, it should be at least as efficient, if not more.

Share this post


Link to post
Share on other sites
I'll just have to use "SetRenderTarget" and use direct3d primitives to do the drawing. Actually everything worked fine all the way up to "UpdateTexture" or "StretchRect". I'll just have to keep plugging away until something works.

ldramire: just wanted to draw some original designs on the backbuffer and copy them to a texture. Had no Idea how involved that would be.

Thanks to everybody for there help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this