移动鼠标时抖动

Jittering when moving mouse

本文关键字:抖动 鼠标 移动      更新时间:2023-10-16

我有一个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的坐标所产生的影响较小。

关于如何避免这种"抖动"图像,有什么想法吗?

当您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->yrelmme->yrel更感兴趣,这就是为什么它在原始代码中我在使用它的任何地方都否定了它(我在上面发布的代码中删除了它)

我写的/****** Mouse moved by mme->xrel and mme->yrel ******/是你想对鼠标运动采取行动的地方。其他代码是忽略SDL_WarpMouse

产生的运动