我似乎无法find从我的应用程序的前台缓冲区数据获取的曲面数据创build纹理的方法
这是我很确定的代码工作(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,我想用它创build一个IDirect3DTexture9对象。
这个函数/ D3DXCreateTextureFromFileInMemory /似乎是最合乎逻辑的,但似乎没有办法。
我很确定有一种方法可以做到这一点,艰难,我不确定如何。 任何帮助将非常欢迎!
谢谢!
最好使用GetRenderTargetData()
而不是GetFrontBufferData()
,因为前者更快。 就这样说,这不是真正的问题。 您希望将您从前缓冲区获得的数据或您当前在屏幕上观察的内容存储到纹理中。
首先, IDirect3DTexture9
和IDirect3DSurface9
实际上是兄弟姐妹,但是即使在他们的类层次结构的某个时刻,它们也会聚合到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而下降了)。 希望能帮助到你。