2017-10-09 56 views
0

我有关DirectX 11DirectX11的 - 纹理和动态变化

几个问题当我通过CreateTexture2D创建的纹理和我指定默认的使用,我应该能够使用UpdateSubresource,对不对?

a)内存更新是否必须与原始纹理格式相同?我的意思是当我使用DDS DXT1创建纹理时,UpdateSubresource数据是否也必须是DDS DXT1?

b)什么时候可以更新资源?在DX12中,您可以在完成命令列表之前更新resoruce。否则没有任何反应

c)我应该更新每个mip的更新,其中每个子资源的索引是index * miplevels,对吗?

或者我应该用map unmap来代替吗?成功更新所需的所有规则是否有很好的例子?

回答

1

这种加载纹理的最有效方法是在创建时使用initData。你可以制作它DEFAULTIMMUTABLE

另一种方法是使用DEFAULT纹理和一组较小的STAGING纹理。您通过Map将数据加载到STAGING纹理中,然后通过CopyResource进行复制。理想情况下,您可以重复使用STAGING纹理(相同大小,mips,格式等)。 UpdateSubresource有效,但效率不高 - 最常用于Constant Buffers。

动态纹理仅用于您计划更新每帧或每隔几帧的内容。根据硬件的不同,GPU和CPU可以访问的内存效率稍低(用于渲染)。

使用在d3d11.h定义的助手D3D11CalcSubresource找出子资源:

UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels) 
{ 
    return MipSlice + ArraySlice * MipLevels; 
} 

这是覆盖在MSDN上编程指南在:

How to: Initialize a Texture Programmatically
How to: Use dynamic resources

参见DDSTextureLoader and WICTextureLoader

请注意,您可以得到如何低效UpdateSubresource的某种意义上是考虑看看实现该功能here了DirectX 12的帮手。

+0

我真的在做项目的任务,我的目标是用现有的DX11应用程序替换所有纹理。所以我不得不挂钩不同的DirectX方法。 – Schnappi

0

所以我发现,包括我的解决方案:

如果纹理作为DYNAMIC创建你不能Map它,如果它拥有一个以上的MIPS。 (我的纹理中有更多的mips,所以我不得不以其他方式去做)

所以我不得不用DEFAULT创建纹理。然后UpdateSubresourceD3D11CalcSubresource在for循环中,我更新了纹理中的所有mips。所以在我的情况下,使用简单的多纹理贴图2D纹理:D3D11CalcSubresource(i, 0, totalMipsInTexture)。我设法在调用Present之前更新纹理(注意多线程)。我最后的建议是:如果你挣扎,在DirectX中启用调试层(当你创建设备传递时)。它会告诉你你做错了什么。