移动鼠标时抖动

时间:2011-11-27 16:06:25

标签: c++ opengl sdl

我有一个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.xevent.motion.x这样的坐标可以减少这种影响。

有关如何避免这种'抖动'图像的任何想法?

1 个答案:

答案 0 :(得分:2)

当您SDL_WarpMouse时,会再次生成另一个鼠标移动事件。你必须忽略第二个。

为了使事情变得更复杂,并不是每个运动事件都跟随SDL_WarpMouse引起的相反方向。这些事件可能来自例如两个动作和一个由经线产生到屏幕中间的动作。我写过这段代码对我有用:

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,这就是为什么它在原始代码中我无论在哪里使用它都会被否定(我在上面发布的代码中删除了它)< / p>

我在哪里写/****** Mouse moved by mme->xrel and mme->yrel ******/是您想要对鼠标移动的行为。其他代码是忽略SDL_WarpMouse

生成的动作