PDA

View Full Version : mouse movement problem



3DPrgmer
09-02-2016, 06:17 AM
Hi,

i need your help again.
This is my old glut code:


void mouseMove(int x, int y)
{
if (mouseHold.buttonLeft)
{
camera.rotation_y += (x - mouseHold.x) * 0.15;
camera.rotation_x += (y - mouseHold.y) * 0.15;

}
if (mouseHold.buttonRight)
{
camera.translate_x += (x - mouseHold.x) * 0.06;
camera.translate_y -= (y - mouseHold.y) * 0.06;
}
if (mouseHold.buttonMiddle)
{
camera.translate_z += (y - mouseHold.y) * 0.1;
}
mouseHold.x = x;
mouseHold.y = y;
}

void mousePress(int button, int state, int x, int y)
{
if (button == MOUSE_LEFT_BUTTON && state == 0) // Left pressed
mouseHold.buttonLeft = true;
else if (button == MOUSE_LEFT_BUTTON && state == 1) // Left release
mouseHold.buttonLeft = false;
else if (button == MOUSE_MIDDLE_BUTTON && state == 0) // Middle pressed
mouseHold.buttonMiddle = true;
else if (button == MOUSE_MIDDLE_BUTTON && state == 1) // Middle release
mouseHold.buttonMiddle = false;
else if (button == MOUSE_RIGHT_BUTTON && state == 0) // Right pressed
mouseHold.buttonRight = true;
else if (button == MOUSE_RIGHT_BUTTON && state == 1) // Right release
mouseHold.buttonRight = false;

mouseHold.x = x;
mouseHold.y = y;
}

main function:
glutMouseFunc(mousePress);
glutMotionFunc(mouseMove);




and here is my new one with glfw


struct {
double posX;
double posY;
bool leftHold;
bool middleHold;
bool rightHold;
} mouse;

struct {
float rotX = 0;
float rotY = 0;
float rotZ = 0;
float transX = 0;
float transY = 0;
float transZ = 0;
} movement;

void processInteraction(GLFWwindow *window)
{
static double lastTime = glfwGetTime();
double currentTime = glfwGetTime();

if (currentTime - lastTime < 1)
return;

glfwGetCursorPos(window, &mouse.posX, &mouse.posY);

if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
mouse.leftHold = true;
else if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_RELEASE)
mouse.leftHold = false;
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS)
mouse.middleHold = true;
else if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_RELEASE)
mouse.middleHold = false;
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS)
mouse.rightHold = true;
else if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_RELEASE)
mouse.rightHold = false;

if (mouse.leftHold)
{
double newX, newY;
glfwGetCursorPos(window, &newX, &newY);

movement.rotX += (newY - mouse.posY) * 0.15;
movement.rotY += (newX - mouse.posX) * 0.15;
}

if (mouse.rightHold)
{
double newX, newY;
glfwGetCursorPos(window, &newX, &newY);

movement.transX += (newX - mouse.posX);
movement.transY -= (newY - mouse.posY);

std::cout << movement.transX << " " << movement.transY << std::endl;
}
}

void calcMatrices(oglVariables &scene)
{
scene.matrix.model = glm::mat4(
glm::vec4(1, 0, 0, movement.transX),
glm::vec4(0, 1, 0, movement.transY),
glm::vec4(0, 0, 1, movement.transZ),
glm::vec4(0, 0, 0, 1)
);
scene.matrix.mvp = scene.matrix.projection * scene.matrix.view * scene.matrix.model;
}


main.cpp:



int main(int argc, char** argv)
{
oglVariables scene;

// init everything
setupGLFW();
scene.window = createWindow();
setupGLEW();
initVariables(scene);
glBindVertexArray(scene.vertexArrayID);

// monitor key press
glfwSetInputMode(scene.window, GLFW_STICKY_KEYS, GL_TRUE);

// set background color
glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f);

// enable z-order
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

// load object to OGL
glBindBuffer(GL_ARRAY_BUFFER, scene.vertexBufferID);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(scene.object.data) * scene.object.data.size(),
scene.object.data.data(),
GL_STATIC_DRAW
);

// load color to OGL
glBindBuffer(GL_ARRAY_BUFFER, scene.colorBufferID);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(scene.object.color) * scene.object.color.size(),
scene.object.color.data(),
GL_STATIC_DRAW
);

// Main loop
do {
processInteraction(scene.window);
calcMatrices(scene);

// clear the scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// use shader prgram
glUseProgram(scene.shaderPrgmID);

// tell shader transformation
glUniformMatrix4fv(scene.matrix.id, 1, GL_FALSE, &scene.matrix.mvp[0][0]);

// open attribute position
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, scene.vertexBufferID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

// open attribute color
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, scene.colorBufferID);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

// draw object
glDrawArrays(GL_TRIANGLES, 0, 3*12);

// close attributes
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

glfwSwapBuffers(scene.window);
glfwPollEvents();
}
while (glfwGetKey(scene.window, GLFW_KEY_ESCAPE) != GLFW_PRESS
&& glfwWindowShouldClose(scene.window) == 0);

cleanUp(scene);

return 0;
}


the old worked just fine. But this new one does not. I don't know why. Sometimes it moves, but it's more a jumping in integer steps. And when it jumps somewhere the cube is totally deformed. Also when i change the size of the window, the cube stands somewhere in the left lower corner instead of centred.
Any ideas about that??


I uploaded my program here: https://www.dropbox.com/s/v66mqdghs99gc2u/MeshViewer2_pre_alpha.rar?dl=0
first the newer one is executed (you can use the right mouse button to move the cube)
and when you close it, the old one is executed. (you can use the left mouse button to rotate, the right to move and the middle button to zoom but not the wheel it didn't worked)
That way you may understand better what i want to do.

john_connor
09-02-2016, 06:42 AM
http://www.glfw.org/docs/latest/input_guide.html#cursor_pos


If you wish to be notified when the cursor moves over the window, set a cursor position callback.


glfwSetCursorPosCallback(window, cursor_pos_callback);

void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos)
{
// here your code
}



if you do this, you can just use the same code like in your glut version


http://www.glfw.org/docs/latest/window_guide.html#window_size

If you wish to be notified when a window is resized, whether by the user or the system, set a size callback.


glfwSetWindowSizeCallback(window, window_size_callback);

void window_size_callback(GLFWwindow* window, int width, int height)
{
// here your code
glViewport(0, 0, width, height);// resize the area to which openGL renders
}



you have to call "glViewport(0, 0, width, height)" when you resize your window

ps:
dependend on these values (width / height), you have to re-calculate your projection matrix (in MVP)

3DPrgmer
09-02-2016, 09:43 AM
wow these callback function are actually what i was looking for. Thank you very much :D


==EDIT==

my cube isn't displayed as cube anymore. i recalculate the matrices every frame. And my perspective is defined like this:
scene.matrix.projection = glm::perspective(monitor.fov, float(monitor.witdh / monitor.heigh), monitor.minView, monitor.maxView);

What is wrong with it??

==EDIT2==



void calcMatrices(oglVariables &scene)
{
scene.matrix.projection = glm::perspective(monitor.fov, float(monitor.witdh / monitor.heigh), monitor.minView, monitor.maxView);
scene.matrix.view = glm::lookAt(
glm::vec3(monitor.transX, monitor.transY, monitor.transZ),
glm::vec3(monitor.transX, monitor.transY, monitor.transZ - 1),
glm::vec3(0, 1, 0)
);
scene.matrix.model = glm::mat4(1.0f);
glm::rotate(scene.matrix.model, monitor.rotX, glm::vec3(1, 0, 0));
glm::rotate(scene.matrix.model, monitor.rotY, glm::vec3(0, 1, 0));
glm::rotate(scene.matrix.model, monitor.rotZ, glm::vec3(0, 0, 1));

scene.matrix.mvp = scene.matrix.projection * scene.matrix.view * scene.matrix.model;
}


rotX = 10, rotY = 10, rotZ=10;
why is my cube not rotated?? is there something wrong with my calculation or do i need to search somewhere else for the problem??

==EDTI3==

i was so stupid. But maybe others have the same problem.
glm::rotate returns a matrix. It does not take a matrix reference and modifies it.

about the first, i need to calc the aspect ratio with two float values instead of two integer and cast the result to float.