我可以很容易地想到在Texture2D
中更改单个像素会有用的一些情况,特别是因为每次持续执行GetData<>(); SetData<>();
时会遇到性能损失和不便或者绘制到RenderTarget2D
。
是否有任何真正的理由不为单个像素公开setter方法?如果没有,有没有办法在不使用上述方法的情况下修改单个像素?
答案 0 :(得分:8)
出于性能原因,纹理初始化时,纹理数据几乎总是由图形驱动程序复制到视频内存(VRAM)。这使得在GPU 上运行的着色器的纹理提取速度更快;如果每个纹理高速缓存未必通过PCIe总线获取丢失的数据,你肯定不会高兴!
但是,正如您所注意到的,这使得CPU难以和/或慢速读取或修改数据。不仅PCIe总线相对较慢,而且VRAM通常不能由CPU直接寻址;通常必须使用特殊的低级DMA命令传输数据。这正是您在使用XNA GetData<>()
和SetData<>()
时看到性能损失的原因:它不是杀死您的函数调用开销,而是他们必须在您后面的VRAM中来回复制数据回来。
如果要修改VRAM中的数据,低级渲染API(例如OpenGL或Direct3D 11)会为您提供三个选项:
GetData<>()
和SetData<>()
在内部所做的事情。glTexSubImage2D()
的功能,该功能基本上会跳过“地图”步骤并将新的像素数据直接复制回VRAM,覆盖以前的内容。XNA建立在Direct3D之上,因此它也必须在这些限制范围内工作。那么,没有原始像素数据!
(另外,对于GPU缓冲区数据,上述所有内容也是如此。)