我有一个Texture2D
我正在从内容管道加载。这个工作正常,但是一旦我尝试在完全不同的SetData
上使用Texture2D
我的游戏中的所有纹理都会变成黑色:
这是在我的HUDMeter课程中,我想要的课程是红色
Texture2D colorGrad = Content.Load<Texture2D>(GradientAsset);
Color[,] pixels = new Color[colorGrad.Width, colorGrad.Height];
Color[] pixels1D = new Color[colorGrad.Width * colorGrad.Height];
pixels = GetRedChannel(colorGrad);
pixels1D = Color2DToColor1D(pixels, colorGrad.Width);
System.Diagnostics.Debug.WriteLine(pixels[32,32]);
Gradient = colorGrad;
Gradient.SetData<Color>(pixels1D);
这些是使用Riemers教程
protected Color[,] GetRedChannel(Texture2D texture)
{
Color[,] pixels = TextureTo2DArray(texture);
Color[,] output = new Color[texture.Width, texture.Height];
for (int x = 0; x < texture.Width; x++)
{
for (int y = 0; y < texture.Height; y++)
{
output[x,y] = new Color(pixels[x,y].G, 0, 0);
}
}
return output;
}
protected Color[,] TextureTo2DArray(Texture2D texture)
{
Color[] colors1D = new Color[texture.Width * texture.Height];
texture.GetData(colors1D);
Color[,] colors2D = new Color[texture.Width, texture.Height];
for (int x = 0; x < texture.Width; x++)
for (int y = 0; y < texture.Height; y++)
colors2D[x, y] = colors1D[x + y * texture.Width];
return colors2D;
}
private Color[] Color2DToColor1D (Color[,] colors, int width)
{
Color[] output = new Color[colors.Length];
for (int x = 0; x < width; x++)
{
for (int y = 0; y < colors.Length / width; y++)
{
output[x + y * width] = colors[x % width, y % (colors.Length/width)];
}
}
return output;
}
这是绘制精灵的代码,这很好用,我总是画精灵:
batch.Draw(meter.Gradient, new Vector2(X, Y), Color.White);
更新
我实际上发现不使用同一文件的精灵不是黑色的。 Texture2D.SetData&lt;&gt;()实际上是否更改了文件本身?有什么用?
更新
我只是尝试使用Alpha和RGB,它正在工作。我认为其中一种转换方法有问题。
答案 0 :(得分:2)
如果你这样做:
Texture2D textureA = Content.Load<Texture2D>("MyTexture");
Texture2D textureB = Content.Load<Texture2D>("MyTexture");
textureA
和textureB
都指向同一个对象。因此,如果您在其中一个上调用SetData
,则会影响它们。这是因为ContentManager
保留了已加载的内部资源列表,因此不必继续重新加载相同的资源。
解决方案是创建一个大小相同的新Texture2D
对象,在GetData
加载的对象上调用ContentManager
,然后在新纹理上调用SetData
示例(未测试):
Color[] buffer = new Color[textureA.Width * textureA.Height];
Texture2D textureB = new Texture2D(textureA.GraphicsDevice,
textureA.Width,
textureA.Height);
textureA.GetData(buffer);
textureB.SetData(buffer);
完成后, Dispose()
新纹理(例如:在Game.UnloadContent
方法中)。但是永远不要处理由ContentManager
加载的那个(因为,就像我说的那样,它是一个共享对象;而是使用ContentManager.Unload
代替。)