【问题标题】:How to copy frontBuffer data to texture DirectX 9如何将frontBuffer数据复制到纹理DirectX 9
【发布时间】:2012-06-04 21:42:38
【问题描述】:

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

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

我很确定有办法做到这一点,但我不知道该怎么做。非常欢迎任何帮助!

谢谢!

【问题讨论】:

    标签: c++ windows video directx textures


    【解决方案1】:

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

    首先,IDirect3DTexture9IDirect3DSurface9 实际上是兄弟姐妹,但他们相同,即使在他们的班级层次结构中的某个时刻它们会收敛到 @987654325 @(这是合乎逻辑的,因为它们是资源)。两者的巧妙之处在于它们实现了共同的功能,特别是 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)。希望对您有所帮助。

    【讨论】:

    • 不客气。如果它解决了您的问题,请考虑接受此作为答案。
    猜你喜欢
    • 2013-05-05
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多