Jump to content
  • Advertisement
Sign in to follow this  
CodeZero

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
Share on other sites
For me it rather seems that the mouse cursor is lagging behind the box. :o
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 this post


Link to post
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 this post


Link to post
Share on other sites

For me it rather seems that the mouse cursor is lagging behind the box. :o
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!