使用图像的一部分创建directx9纹理

时间:2011-10-18 16:19:33

标签: c++ directx textures

我有一个图像(208x8),我想在不同区域复制8x8方块,然后加入所有方块以创建一个IDirect3DTexture9 *

1 个答案:

答案 0 :(得分:2)

根据您的具体操作IDirect3DDevice9 :: UpdateSurface或IDirect3DDevice9 :: StretchRect可能会对您有所帮助。

对于像你所描述的非常小的纹理上的简单操作,使用CPU操作它们是有利的(即使用IDirect3DTexture9 :: LockRect)。对于D3D9,这通常意味着纹理被重新上传到VRAM,因此它通常仅对小的或不经常修改的纹理有用。但有时候如果你是渲染绑定的并且你在循环中更新纹理的位置时要小心,那么可以隐藏这样的操作成本并“免费”获取它们。

为了避免VRAM上传,您可以将POOL_MANAGED资源与相应的使用和锁定标志结合使用,将资源置于AGP孔径内,从而允许CPU和GPU高速访问,请参阅:{{3 }}

如果您正在操作CPU,请注意各种纹理格式的平铺和对齐限制。有关此内容的最佳信息在SDK附带的文档中(包括几个白皮书),在线文档不完整。

这是一个基本的例子:

IDirect3DTexture9* m_tex = getYourTexture();
m_tex->LockRect(0, &outRect, d3dRect, D3DLOCK_DISCARD);

// Stride depends on your texture format - this is the number of bytes per texel. 
// Note that this may be less than 1 for DXT1 textures in which case you'll need 
// some bit swizzling logic. Can be inferred from Pitch and width.
int stride = 1; 
int rowPitch = outRect.Pitch;
// Choose a pointer type that suits your stride.
unsigned char* pixels = (unsigned char*)outRect.pBits;
// Clear to black.
for (int y=0; y < d3dRect.height; ++y)
{
    for (int x=0; x < d3dRect.width; ++x)
    {
        pixels[x + rowPitch * y] = 0x0;
    }
}

m_tex->UnlockRect(0);