Дрожание при движении мыши - PullRequest
2 голосов
/ 27 ноября 2011

У меня есть программа opengl, и я использую SDL для создания окна / обработки событий и т. Д. Теперь, когда я перемещаю мышь для изменения положения камеры / рычага, я получаю дрожащее изображение, мигающее старое положениена экране на долю секунды.

Теперь я думаю, что это может быть проблема с тем, как я переставил мышь.Я установил его обратно в центр экрана в конце перестановки.Вот этот код:

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);
}

Теперь, внутри моего основного цикла while, есть код SDL для вызова этой функции:

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);
            }

Я обнаружил, что получаю такие координатыстихи event.motion.x и event.motion.x вызвали меньше этого эффекта.

Есть какие-нибудь мысли о том, как мне избежать этого "дрожащего" изображения?

1 Ответ

3 голосов
/ 27 ноября 2011

Когда вы SDL_WarpMouse, генерируется другое событие перемещения мыши, которое вы обрабатываете снова. Вы должны игнорировать второй.

Чтобы усложнить ситуацию, не обязательно, чтобы за каждым событием движения следовало одно в противоположном направлении, вызванное SDL_WarpMouse. К событиям могут относиться, например, два движения и 1, сгенерированные деформацией, к середине экрана. Я написал этот код, который работает для меня:

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;
        }
    }
}

Обратите внимание, что я сам интересуюсь -mme->yrel, чем mme->yrel, и поэтому именно в исходном коде он отменяется везде, где я его использую (я удалил его в коде, который я разместил выше)

Где я написал /****** Mouse moved by mme->xrel and mme->yrel ******/ - это место, где вы хотите воздействовать на движение мыши. Другой код должен игнорировать движение, генерируемое SDL_WarpMouse

...