Jump to content
  • Advertisement
Sign in to follow this  
Nokame

XNA 4.0 Replacing Pixel Color

This topic is 2073 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there,

I was hoping to simply get some direction.I want independent images to have an effect applied to them, where a y value parameter (which will increase/decrease) determines where the effect should be applied to the image.  For example:

 

- Let's say the example image has a height of 100 pixels

- We'll start the y value at 0

 

Because the y value is at 0 the effect should be applied along the first row of pixels in the image (row 0).  The game will update the y value, thus moving the effect up/down the image (like a scan animation, I suppose).

 

Now.. the effect I'm looking to do seems simple. I just want to replace a single color, a range of colors,or all the colors of the row, specified by y, with another single color.  I can figure this part out.

 

The main problem for me, is figuring out how to apply and updating value, like y, to the effect on a single image... among many images.  If anyone could point me in a good direction, I'd be grateful.  It's also probably worth mentioning that i'm using XNA 4.0, and this game is using 2D spritebatch. Thanks for reading.

 

Nokame

Share this post


Link to post
Share on other sites
Advertisement
Hmm... Since you mentioned XNA in tag...

Texture editing is quite simple to perform:
void EditTexture(Texture2D Texture)
{
// You need to initialize one 1D and one 2D array first
Color[] TextureArray = new Color[Texture.Width * Texture.Height];
Color[,] TextureField = new Color[Texture.Width, Texture.Height];

// This will give you the color of your texture for each pixel; GetData retuns a 1D array
Texture.GetData(TextureArray);

// For easier manipulation, transform your 1D into 2D array
for (int x = 0; x < Texture.Width; x++)
     for (int y = 0; y < Texture.Height; y++)
           TextureField[x, y] = TextureArray[x + y * tileTexture.Height];

// Using double For loop to go through the pixels, perform whatever editing you need

// After editing, you need to put everything back into 1D array
for (int x = 0; x < Texture.Width; x++)
     for (int y = 0; y < Texture.Height; y++)
           TextureArray[x + y * Texture.Height] = TextureField[x, y];

// We'll make a new object so that edit of the texture doesn't affect all instances of that texture
Texture = new Texture2D(Texture.GraphicsDevice, Texture.Width, Texture.Height);

// Save an edited texture
Texture.SetData(TextureArray);
}
I hope this is self explanatory enough smile.png
Short explanation: you extract the color data via Texture.GetData method into a 1D array, transform 1D array into 2D for easier manipulation, perform whatever manipulation you have to (like swapping Color.Red for Color.Green), transform it back into 1D array and save as new texture.

Of course, you need to write your own modification to satisfy your needs.

Be careful, Texture.SetData affects ALL instances of an object (so if you "scan" a paper on one location, all papers will be "scanned").

Also, you mentioned adding effects to your sprite... I rather wouldn't tinker with the sprites to do that but draw effects on top of the sprites, either with same or new SpriteBatch. Reason is that image manipulation like this is time consuming and you'll also need to track where and when you need to draw original image, image with effect etc.

I hope this helps. Edited by Aurioch

Share this post


Link to post
Share on other sites

I apologize for not being clear.

 

The effect would be applied to a rendertarget2d surface, not the image itself.  So in the above "example" the y = 0  parameter would cause the surface's pixel-row 0 to be altered, not the image pixel-row 0.  Aurioch's method is something I want to avoid beacuse it seems like it has needless overhead to do it during runtime, whereas applying color effects using HLSL seems to be very easy... I just want to apply that color effect to a single row of pixels (given an updating value: y) on the surface, rather than the entire surfafce. 

 

Thanks.

Share this post


Link to post
Share on other sites

Well, this is what i'm talking about.  I'll use the following in my draw method

 

effect.Parameters["y"].SetValue(0);    // At y = 0 the rendertarget2d surface top row is altered using hlsl.

 

Not sure why it took me so long to find.  I haven't tried to implement yet, but I'm sure it'll work fine... I've also been toying around with another way to get the desired effect.  Thanks for the feedback.

Share this post


Link to post
Share on other sites

Yes, you can do it that way.

 

You could also just draw the appropriate portion of the sprite a second time with the desired effect. That way your shaders are a little simpler. But... whatever is easiest.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!