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

发布于 2024-12-10 14:21:12 字数 72 浏览 0 评论 0原文

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

i have an image(208x8) and i would like to copy 8x8 squares from it at different areas then join all the squares to create one IDirect3DTexture9*

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一指流沙 2024-12-17 14:21:12

根据您想要执行的操作,IDirect3DDevice9::UpdateSurface 或 IDirect3DDevice9::StretchRect 可能会帮助您。

对于像您所描述的那样对非常小的纹理进行简单操作,使用 CPU(即使用 IDirect3DTexture9::LockRect)来操作它们可能是有利的。对于 D3D9,这通常意味着将纹理重新上传到 VRAM,因此它通常仅适用于小型或不经常修改的纹理。但有时,如果您受到渲染限制,并且您非常小心在循环中更新纹理的位置,则可以隐藏此类操作的成本并“免费”获得它们。

为了避免 VRAM 上传,您可以使用 POOL_MANAGED 资源并结合适当的使用和锁定标志,将资源定位在 AGP 孔径内,从而允许 CPU 和 GPU 进行高速访问,请参阅:http://msdn.microsoft.com/en-us/library/windows/desktop/ee418784(v=vs.85).aspx

如果您在 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);

Depending on exactly what you are trying to do IDirect3DDevice9::UpdateSurface or IDirect3DDevice9::StretchRect might help you.

For simple operations on very small textures like you are describing, it can be advantageous to manipulate them using the CPU (i.e. with IDirect3DTexture9::LockRect). With D3D9 this usually implies that the texture be re-uploaded to VRAM, so it is generally only useful for small or infrequently modified textures. But sometimes if you are render-bound and you are careful about where you update the texture within your loop, it's possible to hide the cost of operations like this and get them "for free".

To avoid the VRAM upload, you can use a POOL_MANAGED resource combined with the appropriate usage and lock flags to situate the resource within the AGP aperture which allows for high-speed access from both the CPU and GPU, see: http://msdn.microsoft.com/en-us/library/windows/desktop/ee418784(v=vs.85).aspx

If you are manipulating on the CPU, be aware of the tiling and alignment restrictions for the various texture formats. The best information about this is within the documentation that comes with the SDK (includes several whitepapers), the online documentation is incomplete.

Here's a basic example:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文