Alleviating input latency for implementation of QOpenGLWidget

90 views Asked by At

I am implementing a custom QOpenGLWidget in Qt6 and have overridden paintGL() and mouseMoveEvent() to render a triangle that follows the movement of the mouse.

However, I notice that the triangle is always lagging a frame or more "behind" the position of the mouse pointer. I can see this more clearly when moving the mouse around quickly, as the gap between the triangle and the mouse pointer is larger. Is there any way to alleviate this latency? The latency is subtle, but it gives the app a sluggish feel.

If it matters, I am using the latest Qt6 community edition installed with the online installer for Debian 11.7 x64 on an Intel XEON E5-2697 with 64GiB memory and an nVidia Quadro P400 graphics card.

Here is my implementation spesifics:

void SpaceViewWidget::mouseEvent(QMouseEvent *event){
    auto buts = event->buttons();
    for(int i = 0; i < 3; ++i){
        auto buttonName = buttonNames[i];
        const bool last = buttonsPressed[i];
        const bool next = buts & buttonName;
        if(last != next){
            buttonsPressed[i] = next;
            if(next){
                buttonsPressedLocation[i] = event->position() + pan;
            }
        }
    }
}


void SpaceViewWidget::mousePressEvent(QMouseEvent *event){
    mouseEvent(event);
}


void SpaceViewWidget::mouseReleaseEvent(QMouseEvent *event){
    mouseEvent(event);
}


void SpaceViewWidget::mouseMoveEvent(QMouseEvent *event){
    // Middle button pressed
    if(buttonsPressed[2]){
        auto deltaPos = buttonsPressedLocation[2] - event->position();
        pan = deltaPos;
        viewDirty = true;
        update();
        qDebug()<<deltaPos;
    }
}


void SpaceViewWidget::updateViewMatrix(){
    if (viewDirty) {
        viewDirty = false;
        auto sz = QSizeF(size());
        auto sz2 = sz / 2;
        modelMat.setToIdentity();
        float sc=static_cast<float>(1<<chunkDepth);
        modelMat.scale(sc, sc, 1.0);
        viewMat.setToIdentity();
        projectionMat.setToIdentity();
        auto frustum = QRectF(-sz2.width(), -sz2.height(), +sz.width(), +sz.height() );
        projectionMat.ortho(frustum);
        auto center= chunks.center();
        viewMat.translate(-center.x()*sc, -center.y()*sc, 0.0);
        viewMat.translate(-pan.x(), -pan.y(), 0.0);
    }
}

void SpaceViewWidget::paintGL(){
    clearBackground();
    updatePolygonMode();
    updateViewMatrix();
    program.bind();
    textureArray.bind();
    vao.bind();
    vbo.bind();
    program.setUniformValue("modelMat", modelMat);
    program.setUniformValue("viewMat", viewMat);
    program.setUniformValue("projectionMat", projectionMat);
    const auto num_quads = chunks.flags.size()*4;
    f->glDrawArrays(GL_TRIANGLES, 0, num_quads);
}

And the vertex shader uses the view matricies as customary:

void main(){
    /*...*/
    gl_Position = 
              projectionMat
            * viewMat
            * modelMat
            * vec4(aPos.x, aPos.y, aPos.z, 1.0);
}

EDIT: Here is a capture made with "peek"

It is captured at 60fps while my native screen refresh rate is 29.97 fps. At first I center the mouse on the corner of the triangle and then I "drag" it around displaying the lagging.

Peek screencapture showing lag between mouse cursor and OpenGL rendering in Qt QOpenGLWidget

0

There are 0 answers