How to change the Colours of a specific Sprites Texture?

Right now im using a function in my sprite class called SetTextureColour:

    public void SetTextureColour(Color Colour)
    {
        Color[] data = new Color[Texture.Width * Texture.Height];
        Texture.GetData(data);

        for (int i = 0; i < data.Length; i++)
        {
            if (data[i] == Color.White)
            {
                data[i] = Colour;
            }
        }
        Texture.SetData(data);
    }

To change the colour of every white pixel in the sprite's texture to the specified colour, this works fine but the problem I have is that it changes the colours for every sprite which shares that texture, instead of just that individual sprite's. Does anyone have a solution so that I can change the pixels of only that sprites texture, so I could use the function specifying different colours for multiple sprites which have the same texture.

Thanks in advance.

EDIT:

Upon advice I tried to do this using a pixel shader, although I have never used them before I attempted to do so, so far I have this as suggested-

sampler TextureSampler : register(s0);
float3 key_color;
float3 new_color;

float4 ChangePixel(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
{
  float4 newColor = tex2D(TextureSampler, texCoord);

  if (distance(key_color, color.rgb)<0.001f)
  {
     color.rgb = new_color;
  } 

  return newColor;
} 

technique PixelChange
{
    pass Pass0
    {
        PixelShader = compile ps_2_0 ChangePixel();
    }
}

Which is loaded using load content, I also set its technique using this-

        Effect1.CurrentTechnique = Effect1.Techniques["PixelChange"];

I then set the values using these two lines-

        Effect1.Parameters["key_color"].SetValue(Color.White.ToVector3());
        Effect1.Parameters["new_color"].SetValue(Color.Red.ToVector3());

But it seems to do nothing, any chance someone could help me out at this? As I said this is the first time using shaders so I could use some aid.

One last thing, the effect is used in spriteBatch.Begin, so it isnt a question of the effect not being applied.

Upvotes: 0

Views: 1577

Answers (2)

Blau
Blau

Reputation: 5762

You can use a shader that do that for you...

sampler texture : register(s0);
float3 key_color = float3(1,1,1);
float3 new_color;

float4 pixel_shader_that_replaces_color(in float4 color:COLOR0, in float2 coords:TEXCOORDS) : COLOR0
{
      float4 color = tex2D(texture, coords);
      if (distance(key_color, color.rgb)<0.001f)
      {
         color.rgb = new_color;
      } 
      return color;
} 

In your code you have to load the new effect... and for each color you want to draw replaced do this...

 effect.SetValue("key_color", Color.White.ToVector3());
 effect.SetValue("new_color", yourcolor.ToVector3());
 spritebatch.Begin(-...., , ,, effect);
     // Inside this all your texture pixels with Color.White will be replaced to newColor
 spritebatch.End()

You have to call sprite.Begin for each new_color you want.. but I think is better than setting the texture data...

PD: I'm writing the code on the fly... it needs some extra work... like the vertex shader that you can find inside the stock sample , but these are the basics :)

Upvotes: 2

thanks to the help of the people who answered my question and guys on facepunch, I have the solution-

sampler TextureSampler : register(s0);
float3 key_color;
float3 new_color;

float4 ChangePixel(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : COLOR0
  {
    float4 newColor = tex2D(TextureSampler, texCoord);

  if (distance(key_color, newColor.rgb)<0.001f)
  {
     newColor.rgb = new_color;
  } 

  return newColor * color;
} 

technique PixelChange
{
    pass Pass0
    {
       PixelShader = compile ps_2_0 ChangePixel();
   }
}

To use the shader, use -

        Effect1.Parameters["key_color"].SetValue(Color.White.ToVector3());
        Effect1.Parameters["new_color"].SetValue(Color.Aqua.ToVector3());

Key color sets the colour to be searched for, and new color is the colour to replace it with, thanks for your help everybody!

Upvotes: 0

Related Questions