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}
我在使用 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}