【问题标题】:OpenGL weird rotation result with mouseOpenGL奇怪的鼠标旋转结果
【发布时间】:2020-12-04 15:57:17
【问题描述】:

所以我正在开发一个 3D 绘画应用程序。我设法制作了一个基本的渲染器和模型加载器。

我创建了一个相机系统,可以使用它在场景中导航(鼠标/键盘),但这不是我想要的,所以我将相机设为静态,现在我尝试旋转/平移/缩放模型本身。我设法实现了平移和缩放。对于平移,我根据鼠标更改 x/y 位置,对于缩放,我根据鼠标滚动添加或减去 z 轴。

但现在我希望能够用鼠标旋转 3d 模型。示例:当我按住鼠标右键并向上移动鼠标时,模型应该在它的 x 轴(间距) 上旋转,如果我将鼠标向左/向右移动,它应该在 上旋转y 轴(偏航)。而我就是做不到。

下面的代码我得到屏幕上光标的 xpos/ypos,计算偏移量和“试图旋转立方体”。唯一的问题是 如果我将鼠标向上移动,模型将在 x 轴和 y 轴上旋转并稍微倾斜,反之亦然。

这是我的渲染循环中的代码:

    shader.use();
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), 
    (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.01f, 100.0f);
    shader.setMat4f("projection", projection);

    glm::mat4 view = camera.getViewMatrix();
    shader.setMat4f("view", view);

    glm::mat4 modelm = glm::mat4(1.0f);
    modelm = glm::translate(modelm, object_translation);
    // Should rotate cube according to mouse movement
    //modelm = glm::rotate(modelm, glm::radians(angle), glm::vec3(0.0f));
    shader.setMat4f("model", modelm);

    renderer.draw(model, shader);

这是我处理鼠标移动回调的调用:

void mouseCallback(GLFWwindow* window, double xpos, double ypos)
{
if (is_rotating)
{
    if (is_first_mouse)
    {
        lastX = xpos;
        lastY = ypos;
        is_first_mouse = false;
    }

    // xpos and ypos are the cursor coords i get those with the 
    mouse_callback
    double xoffset = xpos - lastX;
    double yoffset = lastY - ypos;

    lastX = xpos;
    lastY = ypos;

    object_rotation.y += xoffset; // If i use yoffset the rotation flips
    object_rotation.x += yoffset;

    rotation_angle += (xoffset + yoffset) * 0.25f;
}
}

鼠标平移效果很好,旋转也不能这么说。

【问题讨论】:

  • 如果没有更多信息,人们将无法帮助您。请描述您遇到的错误以及您的预期。并提供Minimal, Reproducible Example。您当前的代码 sn-ps 并不能告诉我们太多信息。
  • 大胆猜测:当您认为您使用度数时,您使用的是弧度
  • @user253751 Degress 给出了最差(超快)的旋转。
  • @AbdelbakiBoukerche 感谢您的编辑,请点赞!在编辑之前没有足够的信息继续下去。我对 GLM 不熟悉,但从外观上看,您正在旋转 翻译。您是否尝试过 first 旋转?
  • @Human-Compiler 是的,它不起作用,模型开始围绕世界原点而不是本地原点旋转。

标签: c++ opengl mouse glm-math


【解决方案1】:

我修好了。经过一些研究和询问后,我被告知你只能一次旋转一次,而我试图同时做两个 x/y 轴。一旦我分开两次旋转。 对象现在将先在 x 轴上旋转,然后在 y 轴上旋转问题已解决。

代码应该是这样的:

    shader.use();
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH/(float)SCR_HEIGHT, 0.01f, 100.0f);
    shader.setMat4f("projection", projection);

    glm::mat4 view = camera.getViewMatrix();
    shader.setMat4f("view", view);

    glm::mat4 modelm = glm::mat4(1.0f);
    modelm = glm::scale(modelm, glm::vec3(1.0f));
    modelm = glm::translate(modelm, glm::vec3(0.0f, 0.0f, -5.0f));
    // Handle x-axis rotation
    modelm = glm::rotate(modelm, glm::radians(object_orientation_angle_x), glm::vec3(object_rotation_x, 0.0f, 0.0f));
    // Handle y-axis rotation
    modelm = glm::rotate(modelm, glm::radians(object_orientation_angle_y), glm::vec3(0.0f, object_rotation_y, 0.0f));
    shader.setMat4f("model", modelm);

    renderer.draw(model, shader);

【讨论】:

    【解决方案2】:

    您将旋转作为欧拉角存储在 object_rotation 中。

    我建议你使用:

    glm::mat4 rotation = glm::eulerAngleYX(object_rotation.y, object_rotation.x); // pitch then yaw
    

    glm::mat4 rotation = glm::eulerAngleXY(object_rotation.x, object_rotation.y); // yaw then roll
    

    在您的情况下,两者都应该完成工作,我建议您将来将这些信息存储在您的相机(眼睛,向上,中心)而不是您的对象中,一切都会变得更加简单。

    【讨论】:

      猜你喜欢
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      相关资源
      最近更新 更多