如何将frontBuffer数据复制到纹理DirectX 9

时间:2012-05-30 15:59:34

标签: c++ windows video directx textures

我似乎找不到通过我的应用程序的前缓冲区数据从表面数据创建纹理的方法

这是我非常肯定正在使用的代码(Direct X 9,C ++)

// capture screen
IDirect3DSurface9* pSurface;
g_pd3dDevice->CreateOffscreenPlainSurface(640, 480,
    D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL);
g_pd3dDevice->GetFrontBufferData(0, pSurface);

现在我已经有了我的frontBufferData,我想用它创建一个IDirect3DTexture9对象。

这个功能/ D3DXCreateTextureFromFileInMemory / 似乎是最合乎逻辑的,但似乎没有做到这一点。

我很确定有办法做到这一点,我很难以确定如何做到这一点。非常欢迎任何帮助!

谢谢!

1 个答案:

答案 0 :(得分:5)

最好使用GetRenderTargetData()代替GetFrontBufferData(),因为前者更快。话虽如此,这不是真正的问题。您希望将从前缓冲区获得的数据或您当前在屏幕上观察到的内容存储到纹理中。

首先,IDirect3DTexture9IDirect3DSurface9实际上是某种兄弟姐妹,但他们相同,即使在他们班级的某些时候他们是收敛到IDirect3DResource9(这是合乎逻辑的,因为它们是资源)。它们两者的优点在于它们实现了通用功能,特别是 LockRect()的可能性,并从表面手动复制数据(粗略地说,只是一个mipmap级别的表面(一堆像素)到纹理(可能由多个mipmap级别组成)。因此,你的目标是纹理对象的level0表面。

考虑到这一点,由于所有CreateOffscreenPlainSurface()被认为是独立的,我们找不到这个表面可能是其子元素的父纹理(作为纹理的特定mipmap)。长话短说,如果我们不LockRect他们并手动复制数据,我们可以使用StretchRect()

虽然它的名字可能不会泄露其目的之一,但它会帮助我们在这里。记住我们在纹理和表面之间的比较谈话,表面有点像他们的小兄弟。好吧,如果你正确定义一个纹理(与表面相同),你实际上得到了自动化的miplevels,你可以手动定义它们中有多少个。但实质上,这些水平中的每一个都是一个表面。从IDirect3DSurface9“转换”到IDirect3DTexture9只需要填充正确的miplevel表面(在这种情况下应该是level0,因为它基本上是截图)。

因此,将其简化为粗略代码会给我们:

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);

然后你去,一个IDirect3DTexture9去。先生,你想要炸薯条吗?请注意我在这里工作,我在相当长一段时间没有触及DX9(赞成DX10)。希望它有所帮助。