2

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

这是我很确定正在工作的代码(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 / 似乎是最合乎逻辑的,但似乎没有奏效。

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

谢谢!

4

1 回答 1

5

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

首先,IDirect3DTexture9实际上IDirect3DSurface9是兄弟姐妹,但它们并不相同,即使在他们的班级层次结构中的某个时刻它们会收敛IDirect3DResource9(这是合乎逻辑的,因为它们是资源)。它们的优点在于它们实现了通用功能,特别是LockRect()和手动将数据从表面(粗略地说,只是一个 mipmap 级别表面(一堆像素)复制到纹理(其中可能由多个mipmap级别组成)。因此,您的目标是纹理对象的level0表面。

考虑到这一点,由于所有这些CreateOffscreenPlainSurface()都被认为是独立的,因此我们无法找到该表面可能是其子级的父纹理(作为纹理的特定 mipmap)。长话短说,如果我们不对它们都进行 LockRect 并手动复制数据,我们可以使用StretchRect().

虽然它的名字可能不会泄露它的一个目的,但它会在这里帮助我们。记住我们在纹理和表面之间的比较谈话,表面有点像他们的小兄弟。好吧,如果您正确定义纹理(与表面相同),您实际上会获得自动 miplevel,您可以手动定义其中有多少。但本质上,这些层次中的每一个都是一个表面。而从 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)。希望能帮助到你。

于 2012-05-30T17:06:48.517 回答