tags:

views:

1351

answers:

2

How can I draw a 2D rubber band rectangle in DirectX? Preferable using C#.

+3  A: 

The classic way to do rubberbanding is to:

  • Draw the regular scene, i.e. the "background"
  • Switch to "XOR mode", where your pen will XOR the pixels already in the framebuffer. It is important that the mode here is XOR, since XOR is losslessly "revertable", unlike for instance an add operation.
  • While "rubberbanding":
    • Draw the rubberband rectangle in its current coordinates
    • On the next frame, draw the rectangle again, still using XOR, using its previous coordinates. This removes the rectangle, leaving the framebuffer intact.
    • Update the rectangle's coordinates

Details on how to do this "with DirectX" are a bit harder ... I believe DirectDraw, the "old school" way of doing 2D in DirectX is obsolete, so I guess you must be using Direct3D. Unfortunately I'm not sure on the details, there. It might be that you're out of luck with finding pre-defined functionality to do XOR drawing, and need to roll your own. Hopefully someone can provide better details on that. Apologies if you were already up to speed on the rubberbanding theory itself.

unwind
A: 

You need two point variables (each one holding x and y coordinates). Let's call them FirstPoint and SecondPoint.

On mousedown, store the current mouse position to FirstPoint and SecondPoint. As long as the mouse is down, whenever it moves, update SecondPoint with the new mouse position.

Then each frame if the mouse is down, draw a rectangle based on the two corners, FirstPoint and SecondPoint. You'll need a tiny bit of math to detect if they are top-left/bottom-right or top-right/bottom-left and which one is which, but then you just draw a rectangle between them, or two triangles. You would of course have to switch to orthographic (2D) mode before drawing.

I'm not sure about unwind's answer, I don't even know how to do an XOR operation and it seems overly complicated, unless you specifically want the rectangle to be a negative of the background (which is what the XOR operation would do, I believe). Furthermore, if you are redrawing the scene each frame, there is no reason to do some silly XOR back and forth in order to erase the previous rectangle; it would already have been written over by drawing the new frame.

I would personally prefer to draw a rectangle with a solid outline and translucent fill; for this, set the current color to have an alpha value of maybe 128 (or 0.5f) and draw the rectangle between the two points, and then change the polygon draw mode to line and set the color solid, and draw another rectangle.

Finally, I'm sure you would want to react to the rubberband; when the mouse is released, do whatever you need based on the FirstPoint and SecondPoint variables. Also your draw code should only be drawing the rectangle while the mouse is down, so it will stop being drawn.

Ricket