1
votes

I've got a problem with GLFW and dragging mouse. The program doesn't get the displacements of the mouse on Linux. I need your help because on windows it's works. Is it a software problem?

There is the code :

//SEED INCLUDES
#include <Seed/Graphics/engine/engine.hpp>

Engine::Engine()
{
    initLog();
}

Engine::~Engine()
{
    // Close OpenGL window and terminate GLFW
    glfwTerminate();
    TwTerminate();
}

void Engine::mainRender(std::shared_ptr<Scene> scene)
{
    double currentTime = 0, lastTime = 0;
    float deltaTime = 0;

    glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);

    //get all the nodes with a model
    std::stack<ObjectNode*> n;
    std::vector<ObjectNode*> nodes;
    n.push(scene->getRootObjectNode());
    while (!n.empty())
    {
        ObjectNode *n2 = n.top();
        n.pop();
        for (int i = 0; i < n2->getChildren()->size(); i++)
        {
            n.push(n2->getChildren()->at(i));
        }
        if (n2->getModel())
        {
            nodes.push_back(n2);
        }
    }

    //glfwWaitEvents();
    //glfwSwapInterval(0.1);
    //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);

    //main loop to render
    do
    {
        // Clear the depthbuffer and the colourbuffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // Black background
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        //get events glfw
        glfwPollEvents();
        //get current time
        currentTime = glfwGetTime();

        //update mouse control and keyboard control
        this->controller->updateControl(this->window, scene->getCamera(), deltaTime);

        //node->getMaterial()->setLight(a, d, s);
        scene->render(nodes);
        //scene->ShadowMappingRender();
        //scene->SSAOrender();

        //Draw anttweakbar
        TwDraw();
        //get current time
        lastTime = glfwGetTime();

        //time between 2 frames
        deltaTime = float(lastTime - currentTime);

        //on nettoie les buffers
        glfwSwapBuffers(this->window);

    } while (glfwGetKey(this->window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(this->window) == 0);
}
bool Engine::initSystem()
{
    // Initialise GLFW
    if (!glfwInit())
    {
        std::cout << "Failed to initialize GLFW" << std::endl;
        return false;
    }
    //glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL

    window = glfwCreateWindow(WIDTH, HEIGHT, "Moteur3d", NULL, NULL);

    if (window == NULL){
        std::cout << "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" << std::endl;
        glfwTerminate();
        return false;
    }
    glfwMakeContextCurrent(window); // Initialize GLEW 
    glewExperimental = GL_TRUE; // Needed in core profile 

    if (glewInit() != GLEW_OK) {
        std::cout << "Failed to initialize GLEW, version of opengl must be greater or equal than opengl 3.2\n" << std::endl;
        return false;
    }
    return true;
}

bool Engine::initController()
{
    this->controller = new Controller(this->window);
    return true;
}

void TW_CALL CallbackButtonReset(void *clientData)
{
    SPH::reset = true;
}

void TW_CALL CallbackButtonNextFrame(void *clientData)
{
    SPH::nextFrame = true;
}

void TW_CALL CallbackButtonPlay(void *clientData)
{
    SPH::play = true;
}

void TW_CALL CallbackButtonPause(void *clientData)
{
    SPH::play = false;
}

And the controller :

//SEED INCLUDES
#include <Seed/Graphics/engine/control.hpp>
#include <Seed/Graphics/engine/scene.hpp>
#include <Seed/Graphics/engine/camera.hpp>

int Controller::context = 0;

Controller::Controller(GLFWwindow *window)
{
    //captur keys
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    glfwSetMouseButtonCallback(window, mouse_buttonID_callback);
    this->context = 0;
    glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);
}

Controller::~Controller()
{
}


void Controller::updateControl(GLFWwindow* window, Camera *cam, float deltaTime)
{
    //position of the camera
    glm::vec3 position = cam->getPosition();
    //horizontal and vertical angle
    float WAngle = cam->getWAngle();
    float HAngle = cam->getHAngle();
    //field of view
    const float initFoV = cam->getInitFoV();
    float near = cam->getNear();
    float far = cam->getFar();
    //speed move direction (keyboard)
    float speed = cam->getSpeed();
    //speed view direction (mouse)
    float mouseSpeed = cam->getMouseSpeed();

    float FoV = cam->getInitFoV();
    glm::vec3 direction;
    glm::vec3 up;


    /*if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
    {
        Controller::context += 1;
        Controller::context %= 2;
    }*/

    double xpos, ypos;
    //get mouse position on the screen
    glfwGetCursorPos(window, &xpos, &ypos);

    if (Controller::context == 0)
    {
        //reset position of mouse
        glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);

        //compute angles
        WAngle += mouseSpeed * float(WIDTH / 2 - xpos);
        HAngle += mouseSpeed * float(HEIGHT / 2 - ypos);

        //get direction of the camera
        direction = glm::vec3(cos(HAngle) * sin(WAngle), sin(HAngle), cos(HAngle) * cos(WAngle));
        //get right direction of the camera
        glm::vec3 right(sin(WAngle - 3.14f / 2.0f), 0, cos(WAngle - 3.14f / 2.0f));
        //get the up direction of the camera
        up = glm::normalize(glm::cross(right, direction));

        if (glfwGetKey(window, GLFW_KEY_KP_3) == GLFW_PRESS)
        {
            position += direction * speed;
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_1) == GLFW_PRESS)
        {
            position -= direction * speed;
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_6) == GLFW_PRESS)
        {
            position += right * speed;
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_4) == GLFW_PRESS)
        {
            position -= right * speed;
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_8) == GLFW_PRESS)
        {
            position += up * speed;
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_2) == GLFW_PRESS)
        {
            position -= up * speed;
        }
        //set the angle of the direction vector of the camera
        cam->setHAngle(HAngle);
        cam->setWAngle(WAngle);
        //update ViewMatrix
        cam->setViewMatrix(position, direction, up);
        //update Projection Matrix
        cam->setProjectionMatrix(FoV, WIDTH, HEIGHT, near, far);
    }
    else
    {
        //send position of the mouse to anttweakbar
        TwMouseMotion(xpos, ypos);
        if (glfwGetKey(window, GLFW_KEY_KP_0) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_0, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_1) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_1, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_2) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_2, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_3) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_3, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_4) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_4, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_5) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_5, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_6) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_6, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_7) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_7, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_8) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_8, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_9) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_9, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_KP_ENTER) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_KP_ENTER, GLFW_PRESS);
        }
        else if (glfwGetKey(window, GLFW_KEY_DELETE) == GLFW_PRESS)
        {
            TwEventKeyGLFW(GLFW_KEY_DELETE, GLFW_PRESS);
        }
    }
}

void mouse_buttonID_callback(GLFWwindow* window, int button, int action, int mods)
{
    //if action is press button
    if (action == GLFW_PRESS)
    {
        //we get the right and left button of the souris to send these to anttweakbar
        switch (button)
        {
            case GLFW_MOUSE_BUTTON_LEFT:
                TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_LEFT);
                break;
            case GLFW_MOUSE_BUTTON_RIGHT:
                Controller::context += 1;
                Controller::context %= 2;
                //Controller::context = 0;
                TwMouseButton(TW_MOUSE_PRESSED, TW_MOUSE_RIGHT);
                break;
        }
    }
    //if user release button we do the same thing that above
    else if (action == GLFW_RELEASE)
    {
        switch (button)
        {
            case GLFW_MOUSE_BUTTON_LEFT:
                TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_LEFT);
                break;
            case GLFW_MOUSE_BUTTON_RIGHT:
                //Controller::context = 1;
                TwMouseButton(TW_MOUSE_RELEASED, TW_MOUSE_RIGHT);
                break;
        }
    }

}

void Controller::initAntWeakBar(std::string name)
{
    //initialisation AntWeakBar
    TwInit(TW_OPENGL_CORE, NULL);

    //windows size for anttweakbar
    TwWindowSize(WIDTH, HEIGHT);

    //initialize bar
    this->bar = TwNewBar(name.c_str());
}

TwBar* Controller::getBar()
{
    return this->bar;
}

Have you got a solution?

1
Does your mouse_buttonID_callback function get called on Linux?Sam
yes, it get called. It's working. The input keys works too correctly. Just the input drag mouse isn't working.chtimy
Does glfwGetCursorPos return values that make sense?Sam
Yes it does. I've got xy coordinates screen. I'm tried to use <!-- glfwSwapInterval --> and the view is moving but it's very jerkychtimy
I'm solved problem. I don't know how but it's working. It's not GLFW, it's just with one condition on linux.chtimy

1 Answers

0
votes

Ok, the difference with windows is the following reason: On Linux, an condition must be used if the cursor had moved.

glfwGetCursorPos(window, &xpos, &ypos);
if(mouse_moving)
{update}

On Windows, just taking the new position of the cursor works, not on Linux.

glfwGetCursorPos(window, &xpos, &ypos);
{update}