PDA

View Full Version : Rubberbanding with XOR??



Ali
07-12-2007, 01:37 AM
hey,
I am trying to acheive mouse-based rubberbanding through XOR, it works well if I use swapbuffer() while drawing..However I saw a few lines of code in a book..that does not use swapbuffer() in mouse event handler, I am trying to use this method but it does not work properly and it takes time to refresh....

here is the code

int X1, Y1, X2, Y2;
void MouseEvent(int button, int state, int mx, int my)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
glEnable(GL_COLOR_OP_LOGIC);
glLogicOp(GL_XOR);
X1=mx; // setting first point of line
Y1=my; //
}

if(button==GLUT_LEFT_BUTTON && state==GLUT_UP)
{
glDisable(GL_COLOR_LOGIC_OP);
}

//.............mouse move...................
void mouseMove(int mx, int my)
{
drawLine(); //erase the old line
X2=mx;
Y2=my; //setting the second point
drawLine(); //draw the new line
}
the code is self explnantory but i am not clear about the first line how does our draw function delete the old line ? please explain

dorbie
07-12-2007, 03:53 AM
The XOR erases the old line when it is redrawn. This is why you're using an XOR.

But watch out a swap will screw it up unless you have swapbuffers as a buffer copy which is implementation dependent, there are two other methods swap as a page flip and swap invalidating the backbuffer. (and then there's tripple buffering). In summary all bets are off on the content of the backbuffer after a swap.

You also need to watch out for the first draw and not erase the old line first time in and watch when you refresh the 3D scene in the draw callback then swap because again you'll have no line to erase. Then there's the completioon of the drag if you want to be tidy.

The right way to do this is to have drawLine render to the frontbuffer. It may be slow but it is the only bulletproof method and it's only an XOR line (ofcourse assuming no driver bugs which may be a bigger issue).

Check the drawLine code, you may find that it is targeting the frontbuffer and you have no swap involved.

You'll note that this is not done in your draw callback but in your event handler. Luckily GLUT is a rinky dink little library or that's another thing that could bite you on the ass.

A couple of things trouble me here. I think event handling in GLUT is in sync with draw so I suspect that in mid drag you get a double line and you can only drag at the frame rate. drawLine may indeed happen on the backbuffer which suggests that it working at all is more luck than judgement AND that XOR and the old line erase is not required. But it depends on the GLUT setup you may have it on an itimer in which case yuck but it makes SOME sense.

There are also more robust ways to do this like taking an image grab and throwing that up on the backbuffer and drawing your line without relying on good XOR implementation and frontbuffer rendering and without risking GLUT screwing you up.

Finally during a drag if you are updating at the speed of GLUT you can make the render call draw the drag (maintain state) and if it isn't fast enough then in drag mode you blit the last image (which you grabbed on mouse press) instead of render the 3D scene. This will also make your code more portable keeping the draw stuff in the draw callback.

Ali
07-12-2007, 08:32 AM
hey..
thanks for the detailed reply..
Actually i am not using using glut event handelrs..I am using C# and CsGl..swapbuffer() function is working well so far...but I want to utilize XOR without the need to swap buffers because my application when run on another computer distorts the drawing area(screw up)..I am just trying to use the technique of the above code as it does not involve any buffer ****..but XOR function (without swapbuffer()) updates the drawing rae after a delay....
any help will be appreciated
thanks

dorbie
07-12-2007, 09:10 PM
You have the help you need if you read my post carefully.