It's preferable to utilize GetRenderTargetData()
instead of GetFrontBufferData()
, because the former is faster. With that said, that's not really the question. You wish to store the data you get from the frontbuffer, or the stuff you're currently observing on the screen, into a texture.
First of all, IDirect3DTexture9
and IDirect3DSurface9
are actually, kind of, siblings, but they're not the same even though at some point in their class hiearchy they converge to IDirect3DResource9
(which is logical, as they are resources). What's neat about both of them is that they implement common functionality, specifically the possibility of LockRect() and manually copying the data from the surface (which is, crudely, just one mipmap level surface (a bunch of pixels) to the texture (which may consist of multiple mipmap levels). Therefore, your target is the level0 surface of the texture object.
With that in mind, since all CreateOffscreenPlainSurface()
are considered to stand alone, we cannot find a parent texture of which this surface might be a child of (being a particular mipmap of a texture). Long story short, if we don't LockRect both of them and manually copy the data, we can use StretchRect()
.
While its name might not give away one of its purpose, it'll help us out here. Remember about our comparison talk between textures and surfaces, surfaces kind of being their little brother. Well, if you define a texture properly (same as the surface), you're actually getting automated miplevels which you can manually define how many of them are there. But in essence, each of these levels is a surface. And "converting" from IDirect3DSurface9 to IDirect3DTexture9 is just a matter of filling in the proper miplevel surface (which in this case ought to be level0, since it is a screenshot basically).
Therefore, sipping this into coarse code gives us:
IDirect3DTexture9* texture; // needs to be created, of course
IDirect3DSurface9* dest = NULL; // to be our level0 surface of the texture
texture->GetSurfaceLevel(0, &dest);
g_pD3DDevice->StretchRect(pSurface, NULL, dest, NULL, D3DTEXF_LINEAR);
And there you go, one IDirect3DTexture9 to go. Would you like fries with that, sir? Do note I'm working off memory here, I haven't touched DX9 in quite a while (dropped in favor of DX10). Hope it helps.