移动鼠标时抖动

Posted

技术标签:

【中文标题】移动鼠标时抖动【英文标题】:Jittering when moving mouse 【发布时间】:2011-11-27 16:06:24 【问题描述】:

我有一个 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】:

当您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-&gt;yrelmme-&gt;yrel 更感兴趣,这就是为什么它在原始代码中的原因,无论我在哪里使用它都将其否定(我在上面发布的代码中将其删除)

我写/****** Mouse moved by mme-&gt;xrel and mme-&gt;yrel ******/ 的地方是你想要对鼠标动作进行操作的地方。其他代码是忽略SDL_WarpMouse产生的运动

【讨论】:

这很有意义。关于如何解决这个问题的任何建议? 当我添加handleMouseMove(mme-&gt;xrel, mme-&gt;yrel); 代替您的评论时,当我移动鼠标时,它直接指向上方,然后卡在那里.. 有什么想法吗? 您的 handleMouseMove 获取绝对鼠标位置。 xrel 和 yrel 是鼠标的运动,表示鼠标移动了多少。 啊,当然。好的,我得到了那个工作,但是它对抖动没有任何影响:/。但是,我会让你纠正,因为你已经针对我的问题。谢谢! 那么抖动肯定是别的东西! :-?如果没有看到代码,我真的无法判断,但是您是否有机会在每次事件处理后绘制或处理所有然后绘制一次?

以上是关于移动鼠标时抖动的主要内容,如果未能解决你的问题,请参考以下文章

当鼠标移入Echarts出现抖动并滚动条迅速出现消失

当鼠标移入Echarts出现抖动并滚动条迅速出现消失

用于在世界中放置对象时的光线投射抖动

Rigidbody钢体移动时抖动问题

当我们将鼠标悬停在元素上并将其字体设置为粗体时如何避免抖动

我的角色 Sprite Node 移动时抖动,为啥?