1
\$\begingroup\$

I am using opengl and GLFW to make a rendering engine.

Things work per se, but there is some weird flickering happening when I move the camera.

Due the nature of the problem I need to link a youtube video:

https://www.youtube.com/watch?v=XhFrXadnWbs&feature=youtu.be

If you pay attention you will see the stuttering happening as I move the camera.

I beleive this problem occurs due to how I have implemented my camera movement, which is:

GLFW key callback:

#define CAM_SPEED 0.2f
void static key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if(key == GLFW_KEY_W)
    {
        c.translateForward(CAM_SPEED);
    }
    if(key == GLFW_KEY_S)
    {
        c.translateForward(-CAM_SPEED);
    }
    if(key == GLFW_KEY_A)
    {
        c.translateSideways(-CAM_SPEED);
    }
    if(key == GLFW_KEY_D)
    {
        c.translateSideways(CAM_SPEED);
    }
}

Camera code:

    void inline translateForward(float speed)
    {
        glm::vec3 hForward = forward;
        hForward.y = 0;
        hForward = normalize(hForward);

        position += hForward*speed;
    }

    void inline translateSideways(float speed)
    {
        position += side*speed;
    }
\$\endgroup\$
  • \$\begingroup\$ Where do you charge the camera's rotation? Also, do you have any rate control on how often you poll for input, so you don't move faster/slower depending on the repeat rate of the key & how many key events get caught in a particular frame? \$\endgroup\$ – DMGregory Apr 29 '18 at 11:42
  • \$\begingroup\$ The camera rotation is updated in the cursor position callback for GLFW. I don't have any explicit rate control however, \$\endgroup\$ – Makogan Apr 29 '18 at 23:07
  • \$\begingroup\$ Sounds to me like a good thing to include in your question. \$\endgroup\$ – DMGregory Apr 30 '18 at 10:37
1
\$\begingroup\$

The problem is caused by a delay in the frequency of poll calls to the GLFW key callback function.

Changing the code so that the callback function updates some global booleans

Like this:

    if(key == GLFW_KEY_W)
    {
        if(action==GLFW_PRESS)
            E_W=true;
        if(action==GLFW_RELEASE)
            E_W=false;
    }
    if(key == GLFW_KEY_S)
    {
        if(action==GLFW_PRESS)
            E_S=true;
        if(action==GLFW_RELEASE)
            E_S=false;
    }
    if(key == GLFW_KEY_A)
    {
        if(action==GLFW_PRESS)
            E_A=true;
        if(action==GLFW_RELEASE)
            E_A=false;
    }
    if(key == GLFW_KEY_D)
    {
        if(action==GLFW_PRESS)
            E_D=true;
        if(action==GLFW_RELEASE)
            E_D=false;
    }
    if(key == GLFW_KEY_SPACE)
    {
        if(action==GLFW_PRESS)
            E_SPACE=true;
        if(action==GLFW_RELEASE)
            E_SPACE=false;
    }
    if(key == GLFW_KEY_LEFT_SHIFT)
    {
        if(action==GLFW_PRESS)
            E_SHIFT=true;
        if(action==GLFW_RELEASE)
            E_SHIFT=false;
    }

And then making the update happen inside of the render loop as follows:

if(E_W)
    c.translateForward(CAM_SPEED);
if(E_S)
    c.translateForward(-CAM_SPEED);
if(E_A)
    c.translateSideways(-CAM_SPEED);
if(E_D)
    c.translateSideways(CAM_SPEED);
if(E_SHIFT)
    c.translate(vec3(0,-1,0)*CAM_SPEED);
if(E_SPACE)
    c.translate(vec3(0,1,0)*CAM_SPEED);

Eliminates the stuttering.

Or simply put, the update was moved from the callback function to the render function

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.