2014-11-17 34 views
0

我正在使用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程序并为视图矩阵设置统一。请让我知道是否有其他可能会有所作为的相关代码。

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

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

+0

glm :: lookAt不会将方向作为第一个参数。看看这个[问题](http://stackoverflow.com/questions/21830340/understanding-glmlookat)。 – BDL

+0

@BDL似乎解决了大部分问题。我在我的代码中的任何地方都有错,所以它一直在工作,直到我尝试同时更改它们。三角形不再消失,但四处移动后看起来很慢。任何想法可能会造成这种情况? – danielunderwood

+0

单独更改订单是不够的。 lookat需要您在空间中提供两个位置,相机的位置和想要查看的位置。对我来说,你的代码看起来像是你提供了一个你想要看的方向。 – BDL

回答

1

的问题是,GLM ::的lookAt(眼,心,向上)预计,其他参数比你提供:

  • 眼睛是摄像机在空间中的位置
  • 中心的地步相机看着。重要提示:这是一个位置,而不是方向
  • up是向上的向量,这是一个方向。

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

0

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

+0

这当然是需要做的事情。我正在寻找一种方法来使这些调用不那么频繁,但由于某种原因,没有考虑将它放在渲染循环中;不幸的是,它似乎没有解决这个问题。 – danielunderwood