移动和环顾相机冲突

时间:2014-11-17 04:20:24

标签: opengl 3d camera glfw opengl-3

我正在使用GLFW在OpenGL中渲染一些东西。我创建了一个Camera类,允许移动和环顾相机。单独完成时这些工作正常,但当它们一起使用时,会发生以下情况:

向前移动相机时,旋转会变慢,旋转会将相机重置到原始位置。

向后,向左或向右移动相机时,旋转会导致所有内容消失。我现在正在渲染的唯一东西是直接在相机前面的两个三角形,所以我不知道相机最终会看到什么。它也会偶尔像上面一样重置摄像机位置,但只能先向后移动。

代码相对简单,整个源代码为here, mainly in the Camera, Entity, and main source and header files,但我还会在下面包含相关内容。

这是我为GLFW的关键回调设置并处理动作的功能:

void keyCallback(GLFWwindow * window, int key, int scancode, int action, int mods)
{
    switch(key)
    {
        case GLFW_KEY_W:
            cam->move(glm::vec3(0.0, 0.0, -0.05));
            break;
        case GLFW_KEY_S:
            cam->move(glm::vec3(0.0, 0.0, 0.05));
            break;
        case GLFW_KEY_A:
            cam->move(glm::vec3(-0.05, 0.0, 0.0));
            break;
        case GLFW_KEY_D:
            cam->move(glm::vec3(0.05, 0.0, 0.0));
            break;
        case GLFW_KEY_ESCAPE:
            glfwSetWindowShouldClose(window, GL_TRUE);
            break;
        default:
            break;
    }
}

这是处理鼠标移动和环顾相机的功能:

void cursorMoveCallback(GLFWwindow * window, double xpos, double ypos)
{
    printf("Mouse Moved to (%f, %f)\n", xpos, ypos);

    // Change camera angle
    glm::vec3 cameraMovement;

    // Change in x (rotation about y axis)
    if(xpos > 0)
        cameraMovement.x = -0.0005;
    else if (xpos < 0)
        cameraMovement.x = 0.0005;

    // Change in y (rotation about x axis)
    if(ypos > 0)
        cameraMovement.y = 0.0005;
    else if(ypos < 0)
        cameraMovement.y = -0.0005;

    // Reset Cursor position
    glfwSetCursorPos(window, 0, 0);


    // Change Position of Camera
    cameraMovement += Camera::getCurrentCamera()->getDirection();
    Camera::getCurrentCamera()->setDirection(cameraMovement);
}

移动相机:

glm::vec3 Camera::move(glm::vec3 translation)
{
    int dims = viewMatrix.length() - 1;
    // Apply translation
    for (int i = 0; i < dims; i++)
        viewMatrix[dims][i] -= translation[i];

    // Update viewMatrix
    Program::updateViewMatrix(viewMatrix);

    return Entity::move(translation);
}

glm::vec3 Entity::move(glm::vec3 translation)
{
    // Move by amount
    position += translation;

    // Return new position
    return position;
}

用相机看:

glm::vec3 Camera::setDirection(glm::vec3 newDirection)
{
    viewMatrix = glm::lookAt(newDirection, position, glm::vec3(0.0, 1.0, 0.0));

    Program::updateViewMatrix(viewMatrix);

    return Entity::setDirection(newDirection);
}

glm::vec3 Entity::setDirection(glm::vec3 newDirection)
{
    // Set direction of entity
    direction = newDirection;

    // Return new direction of entity
    return direction;
}

Program::updateViewMatrix()调用只是遍历所有活动的OpenGL程序,并为视图矩阵设置制服。如果有任何其他相关代码会产生影响,请告诉我。

我的猜测是,由于回调,我遇到了某种线程问题,或者尝试同时移动和环顾四周存在问题。

更新1:我已将参数的顺序修正为glm::lookAt()。这解决了消失的问题,但在移动之后,旋转似乎比它应该慢。

2 个答案:

答案 0 :(得分:1)

问题是glm :: lookAt(eye,center,up)需要的其他参数不是你提供的:

  • 眼睛是相机在太空中的位置
  • 中心是相机看到的点。重要提示:这是一个职位,而不是一个方向
  • up是向上矢量,这是一个方向。

有关详细信息,可能会发现this post非常有用。

答案 1 :(得分:0)

在进行glDraw ...调用之前,您应该在需要之前设置统一值,即在绘图代码中。如果在事件处理程序中的某处设置它们,事件处理程序和绘图之间发生的任何事情都可能会覆盖您放在那里的值。这就是你发生的事情:你的两个相机类实例都写到同一个位置,只有其中一个可以赢。