Hardware-like software cursor.

So, here is my problem: I want to draw a cursor in OpenGL, so I can easily handle things like partial transparency and 24bpp color depth across platforms.

I’ve done that, by (you can guess it) drawing a simple renderd quad on top of everything in the position of cursor and hiding the original, hardware(“native”?) cursor. The thing I’m running into is when the game starts to lag, the cursor lags with it - what doesn’t take place when using hardware cursor. Is there a way around that lag or any well established practice on this topic? Or maybe you just have an idea how to handle this?

It’s done in Lwjgl(2.9.3) , but the technicalities here may be not of importance.

There is no simple solution here. As you expected: either increase the framerate or use the hardware cursor.

A crazy solution would be to detect frame rate drops and when those happen draw a dummy frame. You’d just copy the contents of the previous frame to the screen (without the old mouse) and redraw the mouse in its new position, effectively doubling the mouse’s frame rate compared to the rest of the game’s. It would have a tiny bit of overhead (1 fullscreen pass for each extra frame to copy the previous one), but could help a lot if mouse smoothness is critical.

Wasn’t that the technique used in Molyneux’s Black & White?
I seem to remember the cursor & game framerates being disconnected from one-another as being a major selling point of that game.

I (honestly) was thinking about that solution too - but it makes your (gameplay) framerate issues even worse, especially when vsync is on.

If it’s dynamic enough and only activates at <half the monitor’s refresh rate, it should be OK. It might improve the perceived responsibility.

Preferably you would want to smear every gameplay-frame over N render-frames - but… what a contrived solution for a problem that might be fixable in a much more sensible way (aim for 60fps, you can do it!)

Perhaps maybe it would be possible to create an “overlay” GL context and drawable on top of the existing one? Could this be a solution, or I miss some point? What you think?

Make it run at 60 FPS.

Or 24 fps for a cinematic look.

Could you also just repaint the small cursor and the small ‘dirty’ section where it used to be painted? Might save some time.

have you tried implementing mouse smoothing?

Usually done by interpolating the mouse position between either:

  1. where the mouse was and where it should be (previous polled position and current polled position)
    or
  2. where it currently is and by predicting where it will be the next time its polled (current polled position and predicted next position).

Rather than jumping between mouse positions you can move the cursor at a constant speed between mouse positions or draw it at an interpolated position between the two positions at the time the frame is rendered.

This should hide small amounts of lag and give the appearance of smooth movement.

This doesn’t really help in this case. It’s not that the mouse isn’t polled often enough; it’s that the screen isn’t redrawn fast enough. Interpolation won’t help if the mouse position only updates 10 times per second.

@kappa
Oh, that sounds pretty interesting :slight_smile: Though not perfect, it may be enough of a compromise. I’ll probably give it a try. Do you have any examples of this or is this just idea from top of your head?

If the frame drop is that large then I agree with you. However if the application is running that slow then its unlikely the other techniques mentioned above are going to help much and in general the application has serious issues which need to be addressed first.

For smaller frame drops though, mouse interpolation should work well enough.

It’s a technique used in many commerical games and triple A titles (sometimes you can even toggle it on/off in the options), IIRC (not 100% sure) it was also used in Revenge of the Titans (OpenGL game with source code).

I don’t have a link to an article setting out the implementation, however the concepts at the end of the fix your game loop articles are pretty similar such as here, here and here.

Thanks :slight_smile: I really (will, cause I can’t twice in a row) appreciate that.

If you want draw small quad on top img and then move it - without redraw bottom img

  1. draw main img to pixel buffer
  2. then copy rec quad from main img, before draw it
  3. draw quad
  4. restore rec quad
  5. move mouse pos – repeat from 2

If game lags – have sharp FPS – then it simple lags and need fix lags ^^