Hi! I'm trying to get smooth image dragging in my Opengl program and there's a very annoying lag that I cant fix.
The dragged image is slightly behind the system cursor. The faster I move the mouse, the more lag I get.
When I grab the actual window by the title bar, ad drag it around, there's no lag whatsoever. The cursor just stays 'glued' to it. And I want that!
The ms-per-frame seems to be around 1ms (it's just one image and the program is just 25kB, no libraries, no external gl loaders). Dragging is pretty smooth, but this small lag ruins everything.
So I wanted to ask if this is a known issue, or I'm just missing something here. Is just querying getcursorpos() enough for this, or should I also catch WM_MOUSEMOUVE messages? Hopefully it's not just my PC being slow, or broken graphic drivers or whatever else. And I think I see this very lag in almost every application I use even on much faster machines.
Any clues/advice would be greatly appreciated. Thanks!
I'm fairly certain that, at least on most modern machines, the display mouse cursor is updated at the device refresh rate, and no faster. So in theory you should be able to have the mouse cursor locked to your drag. However, if I had to guess (without looking at your entire program in more detail), I would say that the problem could be when you are calling GetCursorPos() as compared to when Windows is able to look at the latest mouse cursor position.
When Windows is updating the movement of a window, it can obviously make sure that it does not update where it thinks the mouse cursor is after that before submitting the final composite for that frame to the GPU. But you don't know when that is happening. So it's pretty easy for you to have a one-frame lag between where you think the cursor is and where Windows draws the cursor - all that has to happen is that Windows has to update the cursor position in between when you called GetCursorPos() and when it submits that frame to the GPU. Does that make sense?
So typically what you want to do is draw the cursor yourself while it is in your window, which avoids this potential visual lag, if that makes sense. Because I don't know that there's much you can do to ensure that you are always right in line with the cursor rather than a frame behind - really the only thing I can think of is timing the vertical blank and trying to push your processing to be at the last possible instant before the blank, but that sounds very error-prone to me.
All that being said, this is not something I've ever looked at personally before, since games always draw their own cursors, so it's never an issue...
Ok. The 1 frame lag does seem to be the reason for the drag-lag I'm seeing. Re-reading my question now, I don't even know why I assumed this had something to to with getcursorpos()
I'm not sure about drawing my own cursor. Although it does seem like a valid way to sync cursor with the ui, this would feel like I'm intentionally slowing things down.
Windows itself seems to be ok with this kind of lag - when I drag folders around in the Explorer, they do seem to be slightly behind the cursor as well, but the movement looks nice and fluid.
But the 'locked' feel of the title bar dragging still bothers me. They are cheating aren't they? It's just that I'm seeing this lag everywhere and I thought that I would definitely not have this when I write my own thing... I might experiment with predictions based on current mouse velocity later, but we'll see. So much other stuff to do.
You might also want to ditch the GetCursorPos(), which is based on Windows's central updating of the notion of where the mouse is, and switch to using Raw Input to get raw mouse data back from the mouse directly. This might give you a tighter feedback loop, depending on the circumstances.
(Eg., if Windows is not processing the USB mouse input buffer until too late for you to get it with GetCursorPos(), you might be able to process it yourself through raw input, or something like this).
But, without knowing exactly what's going on, it's hard to say whether that would actually help, since I don't actually know whether Windows lets you get at USB mouse data any faster than it processes it for GetCursorPos() in practice, if that makes sense.