Reputation: 3
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
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
Reputation: 3
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