6
\$\begingroup\$

In XNA, how can I draw a sprite on the screen that inverts the colors behind that sprite (i.e. the colors that would appear if the sprite weren't in the way of them)?

I feel this is the best technique for an aiming cursor in a game, but I'm unsure how I can achieve this. I'm open to other ideas for aiming cursors if this is less than ideal.

\$\endgroup\$
  • 4
    \$\begingroup\$ The problem of making something visible on all backgrounds appears in situations like painting the label text for desktop icons, and no color manipulation solution works for all cases. The approach that tends to give the best visibility is drop shadows or otherwise outlining the shape with contrasting colors. \$\endgroup\$ – Lars Viklund Aug 6 '11 at 23:00
9
\$\begingroup\$

To do this in XNA, you will need to use a shader. You will need to render your scene to a texture (Or, render just the portion the cursor covers), and then draw the cursor using that texture and a shader that inverts the color. Unless you've already got a deferred renderer, this will probably be more hassle than it's worth. If you do, you can use the existing depth/color buffers, and re-shade the pixels covered by the cursor in your color-inverting shader.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Have any examples about how I use a shader? \$\endgroup\$ – Corey Ogburn Aug 7 '11 at 2:05
  • \$\begingroup\$ There's some in the app hub education stuff. \$\endgroup\$ – Blecki Aug 7 '11 at 3:19
1
\$\begingroup\$

A simple method to reduce the likelihood that your cursor is the same color as your background is to sample the center pixel beneath your cursor, and invert that color. You would draw your entire cursor with that color, or use it to apply a shading.

Or sample say 5 pixels (if it's a cross hair you could sample the center, top, bottom, left, right pixel) and average them, then invert the average.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

You can do this by altering the way that you are rendering the game. First render to a texture http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series3/Render_to_texture.php.

After you have rendered the frame to the texture you can then edit the colours of the location that you are interested in:

Color pixel;
int xlocationOfSprite;
int ylocationOfSprite;
int widthOfSprite;
int heightOfSprite;

for (int x = xlocationOfSprite; x < widthOfSprite; x++)
{
    for (int y = ylocationOfSprite; y < heightOfSprite; y++)
    {
        pixel = bitmap.GetPixel(x, y);

        // Do what ever color manipulation you want

        bitmap.SetPixel(x, y, pixel);
    }
}

Then render the modified texture to the screen.

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Are you suggesting that he'd do the manipulation CPU-side? That's not going to be cheap, particularly with the pipeline stalls from readbacks. \$\endgroup\$ – Lars Viklund Aug 7 '11 at 1:35
  • \$\begingroup\$ He'd have to download the texture from the graphics card, and then upload it again. Doing it in-place with a shader would be much faster. \$\endgroup\$ – Blecki Aug 7 '11 at 3:16
0
\$\begingroup\$

A quick 'n' cheesy way goes something like:

  • Enable alpha blending
  • Set your source blend factor to one minus dest color
  • Set your dest blend factor to one minus source alpha
  • Set your blend equation to additive
  • Draw the sprite as normal
  • Disable any states you need to disable

Just tested this (in OpenGL, not XNA, but the principle is the same) and it works well enough.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.