annonymously
annonymously

Reputation: 4708

Texture2D is turning black

I have a Texture2D that I'm loading from the Content Pipeline. That's working fine, but as soon as I try to use SetData on a completely different Texture2D all of the textures in my game go completely black:

Normal

Black

This is in my HUDMeter class, the class that I want to be just red

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);

These are using Riemers tutorial

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;
}

And here is the code to draw the sprites, this works fine and is how I always draw sprites:

batch.Draw(meter.Gradient, new Vector2(X, Y), Color.White);

Update:

I've actually found that the sprites that don't use the same file are not black. Does Texture2D.SetData<>() actually change the file itself? what is the use of that?

Update:

I just tried to use the Alpha as well as RGB and it's working. I'm thinking that there's something wrong with one of the conversion methods.

Upvotes: 3

Views: 828

Answers (1)

Andrew Russell
Andrew Russell

Reputation: 27245

If you do this:

Texture2D textureA = Content.Load<Texture2D>("MyTexture");
Texture2D textureB = Content.Load<Texture2D>("MyTexture");

Both textureA and textureB refer to the same object. So if you call SetData on one of them, it will affect both of them. This is because ContentManager keeps an internal list of resources already loaded, so it doesn't have to keep reloading the same resource.

The solution would be to create a new Texture2D object of the same size, call GetData on the one loaded by ContentManager, and then SetData on the new texture.

Example (not tested):

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() of the new texture when you are finished with it (eg: in your Game.UnloadContent method). But never dispose of the one loaded by ContentManager (because, like I said, it is a shared object; use ContentManager.Unload instead).

Upvotes: 2

Related Questions