gpt4 book ai didi

c# - Texture2D SetData 错误

转载 作者:太空宇宙 更新时间:2023-11-03 13:13:14 25 4
gpt4 key购买 nike

我目前正在尝试在从文件加载后使用 SetData<> 在 Texture2D 对象上手动设置纹理数据。已在启用 MipMap 的情况下创建 Texture2D。数据已从使用 DXT1 压缩保存的 .dds 文件加载,大小为 512x512。

这是负责创建纹理并将数据加载到其中的代码。

texture = new Texture2D(graphics, (int)ddsHeader.Width, (int)ddsHeader.Height, mipMapCount > 1, sFormat);

for (int i = 0; i < (int)mipMapCount; i++)
{
int pow = (int)Math.Pow(2, i);

int width = (int)ddsHeader.Width / pow;
int height = (int)ddsHeader.Height / pow;

Rectangle? rect = null;

// get image size
int blockSize = GetBlockSize(width, height);
Console.WriteLine(string.Format("Width {0} Height {1}", width, height));
Console.WriteLine("Block size: " + blockSize + " " + (int)ddsHeader.PitchOrLinearSize);
// read the texture
byte[] textureData = reader.ReadBytes(blockSize);
rect = new Rectangle(0, 0, width, height);

// set the color into the appropriate level of the texture
if (sFormat == SurfaceFormat.Color && dxFormat == DXGIFormat.A8B8G8R8)
{
Color[] colors = ProcessUncompressedTexture(textureData, width, height);
texture.SetData<Color>(i, rect, colors, 0, width * height);
}
else
{
texture.SetData<byte>(i, rect, textureData, 0, blockSize);
}
}

它工作正常,数据被正确加载并正确设置到每个 mip 级别 - 直到它到达第 9 级别,它抛出以下内容:ArgumentException 未处理:传入的数据的大小太大或对于这个资源来说太小了。

这是输出。

Width 512 Height 512        // level 0
Block size: 262144 262144
Width 256 Height 256 // level 1
Block size: 65536 262144
Width 128 Height 128 // level 2
Block size: 16384 262144
Width 64 Height 64 // level 3
Block size: 4096 262144
Width 32 Height 32 // level 4
Block size: 1024 262144
Width 16 Height 16 // level 5
Block size: 256 262144
Width 8 Height 8 // level 6
Block size: 64 262144
Width 4 Height 4 // level 7
Block size: 16 262144
Width 2 Height 2 // level 8
Block size: 4 262144

现在,textureData 的计数为 4。此 mip 级别的宽度和高度为 2。矩形的大小也为 2 个单位。我看不出是什么导致了这个错误的发生,因为之前的 8 个级别都设置好了。

有谁知道这里可能发生了什么导致这种情况?

最佳答案

好吧,我想我已经找到了答案,而且有点道理。

本主题 here似乎表明 DXT 压缩 mipmap 的最小允许大小是 4x4 block 。这与我所看到的相符,因为上面的 DXT1 和 5 错误,但如果我切换到说 DXGIFormat.A8B8G8R8,它会下降到 1x1 mip-mapped 大小的 block 。

最小 4x4 block 大小的原因是 DXT 压缩算法将 block 压缩到最小 4x1。

无论如何,如果我使用的是 DXT 压缩纹理,我已经修改了我的代码以将要读取的 block 的大小调整为至少 4x4,并且它有效。

为了下一个遇到同样问题的人(无论他们是谁),这是我更新的 mipmap 集代码:

// create the texture
texture = new Texture2D(graphics, (int)ddsHeader.Width, (int)ddsHeader.Height, mipMapCount > 1, sFormat);

Console.WriteLine(texture.LevelCount);

for (int i = 0; i < (int)mipMapCount; i++)
{
int pow = (int)Math.Pow(2, i);

int width = (int)ddsHeader.Width / pow;
int height = (int)ddsHeader.Height / pow;

Rectangle? rect = new Rectangle(0, 0, width, height);

if (dxFormat == DXGIFormat.DXT1 || dxFormat == DXGIFormat.DXT5)
{
if (width < 4 && height < 4)
{
width = 4;
height = 4;
}
}

// get image size
int blockSize = GetBlockSize(width, height);
Console.WriteLine(string.Format("Width {0} Height {1} // level {2}", width, height, i));
Console.WriteLine("Block size: " + blockSize + " " + (int)ddsHeader.PitchOrLinearSize);
// read the texture
byte[] textureData = reader.ReadBytes(blockSize);
Console.WriteLine("Data size: " + textureData.Length);

// set the color into the appropriate level of the texture
if (sFormat == SurfaceFormat.Color && dxFormat == DXGIFormat.A8B8G8R8)
{
Color[] colors = ProcessUncompressedTexture(textureData, width, height);
texture.SetData<Color>(i, rect, colors, 0, width * height);
}
else
{
texture.SetData<byte>(i, rect, textureData, 0, blockSize);
}
}

我移动了矩形? rect = ... 调用,并将 DXT 小于 4x4 block 检测放在其下方。它不是最整洁的,但它确实有效。

关于c# - Texture2D SetData 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27560496/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com