by the Codermind team. |
Question
«I'm not using the default hardware cursor in my game but rather a custom cursor drawn as a 3D object on top of my scene so that I can vary its shape and size to what I want. The problem I have is that the hardware cursor is very responsive, while my hand drawn cursor seems to lag a lot between the movement of my mouse and the update on the screen. This is especially problematic when the frame rate of my game is in the low ten frames per second, but is perceptible even when the frame rate is higher. How do I make the custom cursor as responsive as the hardware cursor ?»
Answer
Laggy cursors are usually caused by this :
- Rendering of commands sent to the GPU and their appearance on the screen will take more than the equivalent of three frames of rendering time. That's the max acceptable latency on PC between a present call and its execution by the GPU. Now, to that latency, add the difference between the time you actually took the input value and the time you called present() (could be an extra frame, maybe more depending on how your code is organized).
- Windows hardware cursor has a lot less latency, because there is a specific thread running on your PC, that will poll mouse position and send an immediate command to the graphics card driver as soon as it's changed. The cursor will then appear in the right position as soon as the screen is refreshed.
You can be closer to the speed of the hardware cursor by doing those things :
- Make sure the frame rate isn't far from the refresh rate. Higher or equal is best of course. Sometimes slower is okay, depending on what smoothness you're looking for.
- Limit the amount of time the CPU can take in advance to the GPU. You can do that usually with event queries (in Direct3D). Looping on event queries with a short sleep time. That way you limit the time between the present() call and the appearance on the screen. (if you were gpu limited in the first place).
- Update your rendered mouse reticle position in a separate thread, independently of your main rendering thread. Just before present and immediately after having waited for the event query render your mouse cursor. That way you minimize the perceived latency between the mouse movement and its appearance on the screen. That last one is also true if you're CPU limited, as the time spent on the CPU will be added to the latency otherwise.
Ultimately, if your frame rate is dropping way too much, and you cannot reduce the load, maybe you could cut your rendering frame into several parts (if the rendering is the culprit), or update your game logic at a lower rate than display (if the game logic is the culprit) so that elements that may play a "psychological" role into what the player think of responsiveness of your game are updated more frequently. That last part will require more work of course but it can improve the player experience not only the mouse lag issue.




