grep
grep

Reputation: 4026

Jittering when moving mouse

I have an opengl program and I am using SDL for the window creating / event handling etc. Now, when I move the mouse to re-position the cameras yaw/pitch, I get a jittering image, with the old position flashing on the screen for a split second.

Now i think this may be an issue with the way I re-position the mouse. I have it set back to the center of the screen at the end of the re-positioning. Here is the said code:

void handleMouseMove(int mouseX, int mouseY)
{
    GLfloat vertMouseSensitivity  = 10.0f;
    GLfloat horizMouseSensitivity = 10.0f;

    int horizMovement = mouseX - midWindowX;
    int vertMovement  = mouseY - midWindowY;

    camXRot += vertMovement / vertMouseSensitivity;
    camYRot += horizMovement / horizMouseSensitivity;

    if (camXRot < -90.0f)
    {
        camXRot = -90.0f;
    }

    if (camXRot > 90.0f)
    {
        camXRot = 90.0f;
    }

    if (camYRot < -180.0f)
    {
        camYRot += 360.0f;
    }

    if (camYRot > 180.0f)
    {
        camYRot -= 360.0f;
    }

    // Reset the mouse to center of screen
    SDL_WarpMouse(midWindowX, midWindowY);
}

Now, Inside my main while loop, here is the SDL code for calling this function:

while( SDL_PollEvent( &event ) )
        {
            if( event.type == SDL_KEYDOWN )
            {
                if( event.key.keysym.sym == SDLK_ESCAPE )
                {
                    Game.running = false;
                }
            }
            if( event.type == SDL_MOUSEMOTION )
            {
                int mouse_x, mouse_y;
                SDL_GetMouseState(&mouse_x, &mouse_y);

                handleMouseMove(mouse_x, mouse_y);
            }

I found that getting the coordinates like this verses event.motion.x and event.motion.x caused less of this effect.

Any thoughts on how I could avoid this 'jittering' image?

Upvotes: 2

Views: 1313

Answers (1)

Shahbaz
Shahbaz

Reputation: 47563

When you SDL_WarpMouse, another mouse move event is generated that you are handling again. You must ignore the second one.

To make things more complicated, it's not like every motion event is followed by one in the opposite direction caused by SDL_WarpMouse. The events may come for example two motions and 1 generated by warp to the middle of the screen. I have written this code which works for me:

void motion(SDL_MouseMotionEvent *mme)
{
    static bool initializing = true;  // For the first time
    static int warpMotionX = 0, warpMotionY = 0;  // accumulated warp motion
    if (initializing)
    {
        if (mme->x == midWindowX && mme->y == midWindowY)
            initializing = false;
        else
            SDL_WarpMouse(midWindowX, midWindowY);
    }
    else if (mme->xrel != -warpMotionX || mme->yrel != -warpMotionY)
    {
        /****** Mouse moved by mme->xrel and mme->yrel ******/
        warpMotionX += mme->xrel;
        warpMotionY += mme->yrel;
        SDL_WarpMouse(midWindowX, midWindowY);
    }
    else    // if event motion was negative of accumulated previous moves,
            // then it is generated by SDL_WarpMotion
        warpMotionX = warpMotionY = 0;
}

void processEvents()
{
    SDL_Event e;
    while (SDL_PollEvent(&e))
    {
        switch (e.type)
        {
            case SDL_MOUSEMOTION:
                motion(&e.motion);
                break;
            default:
                break;
        }
    }
}

Note that, I myself am interested in -mme->yrel than mme->yrel and that's why it's in the original code I have it negated wherever I use it (I removed it in the code I posted above)

Where I wrote /****** Mouse moved by mme->xrel and mme->yrel ******/ is where you want to act on the mouse motion. Other code is to ignore motion generated by SDL_WarpMouse

Upvotes: 3

Related Questions