GLFW 鼠标,Linux 和 OpenGL

GLFW mouse, Linux & OpenGL

我在使用 GLFW 和拖动鼠标时遇到了问题。该程序不会获取鼠标在 Linux 上的位移。我需要你的帮助,因为在 windows 上它是有效的。是软件问题吗?

有代码:

//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;
}

和控制器:

//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;
}

你有解决办法吗?

好的,和windows的区别是以下原因: 在 Linux 上,如果光标已移动,则必须使用条件。

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

在 Windows 上,只需移动光标的新位置即可,而不是在 Linux 上。

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