Rendering always lags behind input

This topic is 2525 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm posting this in the "General" section because ultimately I think I may have a problem with how I'm handling input. All the code does is create a window and initialize OpenGL, then draws a box around where the mouse is. The problem is, if the mouse is moving, the box is never centered on the mouse - it lags behind where the mouse currently is.

Even though it's subtle, it's very noticeable. Move the mouse around in a circle, even slowly, and you can see that the box is never centered on the mouse. I've tried several things and can't seem to figure out why it behaves this way. Am I handling and processing the input properly? Could it be something to do with syncing?

Pasted below is a stripped down version that shows what I'm talking about. It needs to link to opengl32.lib and glu32.lib.

Thanks,
Jake

 #include <windows.h> #include <gl/glu.h> HDC dc; int mouseX = 0; int mouseY = 0; LRESULT CALLBACK WndProc ( HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch ( msg ) { case WM_MOUSEMOVE: mouseX = LOWORD( lParam ); mouseY = HIWORD( lParam ); return 0; default: return DefWindowProc( wnd, msg, wParam, lParam ); } } void createWindow ( ) { WNDCLASS wndClass; wndClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wndClass.lpfnWndProc = WndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 4; wndClass.hInstance = GetModuleHandle( 0 ); wndClass.hIcon = LoadIcon( NULL, IDI_WINLOGO ); wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndClass.hbrBackground = NULL; wndClass.lpszMenuName = NULL; wndClass.lpszClassName = "test"; RegisterClass( &wndClass ); RECT rect = { 100, 100, 700, 500 }; DWORD style = WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_CAPTION; AdjustWindowRect( &rect, style, false ); HWND window = CreateWindowEx( 0, "test", "test", style, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0, 0, GetModuleHandle( 0 ), 0 ); dc = GetDC( window ); PIXELFORMATDESCRIPTOR pfd = { sizeof( PIXELFORMATDESCRIPTOR ), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; int pixelFormat = ChoosePixelFormat( dc, &pfd ); SetPixelFormat( dc, pixelFormat, &pfd ); HGLRC rc = wglCreateContext( dc ); wglMakeCurrent( dc, rc ); ShowWindow( window, SW_NORMAL ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glColor3f( 1.0f, 0.0f, 0.0f ); glViewport( 0, 0, 600, 400 ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( 0, 600, 400, 0.0f, -1.0f, 1.0f ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); } int main ( ) { createWindow(); MSG msg; memset( &msg, 0, sizeof( MSG ) ); while ( msg.message != WM_QUIT ) { while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); if ( msg.message == WM_QUIT ) break; } glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glLoadIdentity(); glBegin( GL_QUADS ); glVertex2i( mouseX - 10, mouseY - 10 ); glVertex2i( mouseX + 10, mouseY - 10 ); glVertex2i( mouseX + 10, mouseY + 10 ); glVertex2i( mouseX - 10, mouseY + 10 ); glEnd(); SwapBuffers( dc ); } return 0; } 

Share on other sites
I noticed that too. Getting mouse position directly seems to work correctly:
 POINT ptMousePos; GetCursorPos(&ptMousePos); ScreenToClient(DXUTGetHWND(), &ptMousePos); MyEngine::Vector2 MousePos((float)ptMousePos.x, (float)ptMousePos.y);

Share on other sites
For me it rather seems that the mouse cursor is lagging behind the box.
The lag you talk about generally happens when the driver is buffering frames (often disabled in window mode, but enabled in fullscreen mode). Try disabling VSync and pre-rendered frames in your graphics control panel, and see if that makes a difference. Also try disabling triple buffering.

At least vertical sync can also be controlled from your application with a WGL extension if you find that it's the cause of your problem (depending on your graphics settings, it can usually be 'forced on', 'forced off', or 'application decides').

Share on other sites

I noticed that too. Getting mouse position directly seems to work correctly:
 POINT ptMousePos; GetCursorPos(&ptMousePos); ScreenToClient(DXUTGetHWND(), &ptMousePos); MyEngine::Vector2 MousePos((float)ptMousePos.x, (float)ptMousePos.y);

Well, I tried that, but I still see the lag. Thanks for the try

Share on other sites

For me it rather seems that the mouse cursor is lagging behind the box.
The lag you talk about generally happens when the driver is buffering frames (often disabled in window mode, but enabled in fullscreen mode). Try disabling VSync and pre-rendered frames in your graphics control panel, and see if that makes a difference. Also try disabling triple buffering.

At least vertical sync can also be controlled from your application with a WGL extension if you find that it's the cause of your problem (depending on your graphics settings, it can usually be 'forced on', 'forced off', or 'application decides').

This reduced the lag to a degree, but it's still there. This all came about because the GUI I'm designing wasn't very responsive to mouse input. The frustrating thing is, when I run games like DEFCON that have a very simple GUI, much like mine, it's very responsive and doesn't feel laggy at all. So I'm confident that I'm just not setting things up or handling them properly. I wrote up the code above as an example how I can't even get the simplest of things to respond the way it should.

Share on other sites
l, I tried that, but I still see the lag. Thanks for the try

I forgot to mention that should be called right before actually using mouse position, I hope you didn't put that into Window Callback =p

Share on other sites

[quote name='CodeZero' timestamp='1324321942' post='4895425']l, I tried that, but I still see the lag. Thanks for the try

I forgot to mention that should be called right before actually using mouse position, I hope you didn't put that into Window Callback =p
[/quote]

Yeah, I tried both. Neither seemed to fix the problem.

Share on other sites
So I did some digging around in DEFCON's code and found out that they hide the mouse, then manually redraw it themselves to hide the fact that the mouse lags behind the input. When I un-hid the real mouse, their input was even more laggy than mine, probably because the input handling is much more involved.

Is it common practice to do this? Wouldn't it create inconsistencies in where the user thinks they are clicking and where they actually are?

Share on other sites
Wouldn't it create inconsistencies in where the user thinks they are clicking and where they actually are?

So long as the click is interpreted as being at the visible position of the mouse cursor, there's no problem.

1. 1
Rutin
36
2. 2
3. 3
4. 4
5. 5

• 11
• 15
• 12
• 14
• 9
• Forum Statistics

• Total Topics
633352
• Total Posts
3011483
• Who's Online (See full list)

There are no registered users currently online

×