【问题标题】:OpenGL, First Person Camera TranslationOpenGL,第一人称相机翻译
【发布时间】:2017-10-01 03:11:07
【问题描述】:

我一直想知道如何让我的 FPS 相机根据相机的方向基本向前和向后移动,但我一直失败得很惨,我想知道如何以最佳方式做到这一点,就像现在我的代码是在我的三角形后面切换方向(w 变成 s 并且 s 变成 w)并且通常不起作用(移动有时,对角线而不是向前),旋转完美,但平移搞砸了我的矩阵......

void glfwCursorCallback(GLFWwindow* window, double x, double y) {
    camera.rx += (x - camera.lcx) * 0.01f;
    camera.ry += (y - camera.lcy) * 0.01f;
    kmMat4RotationYawPitchRoll(&camera.mat, camera.ry , camera.rx, 0.0f);
    camera.lcx = x;
    camera.lcy = y;
}
...
kmMat4PerspectiveProjection(&projection, 90.0f, aspect, 0.1f, 1000.f);
float x = 0.0f, y = 0.0f, z = -1.0f;
while(!glfwWindowShouldClose(window)) {
    if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
        /* pitch - ry */
        x += 0.1*sin(camera.ry)*cos(camera.rx);
        y += 0.1*sin(camera.ry)*sin(camera.rx);
        z += 0.1*cos(camera.ry);
    }
    if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
        x -= 0.1*sin(camera.ry)*cos(camera.rx);
        y -= 0.1*sin(camera.ry)*sin(camera.rx);
        z -= 0.1*cos(camera.ry);
    }

    glClear(GL_COLOR_BUFFER_BIT);
    kmMat4Translation(&transform, x, y, z);
    kmMat4Multiply(&object, &camera.mat, &transform);
    kmMat4Multiply(&final, &projection, &object);
    glUniformMatrix4fv(shader.mpm, 1, GL_FALSE, final.mat);
    ...

我不知道怎么做,因为我以前从来没有做过,所以我希望这里有经验的人能给我一些建议!

编辑:目的是让相机根据方向向前移动。此外,如果我省略 xy 并将 z 设置为 +- 0.1...,它也能完美运行...所以这不是矩阵乘法的问题

【问题讨论】:

    标签: c opengl 3d camera coordinate-transformation


    【解决方案1】:

    虽然在世界中 X 轴指向右侧,Y 轴指向前方,Z 轴指向顶部,但在视口中 X 轴指向左侧,Y 轴向上,Z 轴不在视图中(注意在右手系统中,Z 轴是 X 轴和 Y 轴的叉积)。

    因此,必须首先将场景参考系统中的每个点和每个矢量转换为视口坐标。这可以通过下表轻松处理:

     x  y  z
    --------
     1  0  0  | x' =  x
     0  0  1  | y' =  z
     0 -1  0  | z' = -y
    


    此外,您必须逐步更改相机矩阵,而不是总结运动和旋转。这意味着您必须计算当前移动和当前旋转矩阵。将移动和旋转应用到相机并保持相机用于循环的下一个循环。在循环的下一个循环中,您必须使用上一个循环中操纵的相机,并且您必须应用新的移动和旋转。这会导致相机增量变化,始终基于其当前位置和方向。


    你的代码应该是这样的:

    double currenYaw    = 0.0;
    double currentPitch = 0.0;
    double currentX     = 0.0;
    double currentY     = 0.0;
    
    void glfwCursorCallback( GLFWwindow* window, double x, double y )
    {
        currenYaw    += (x - currentX) * 0.01;
        currentPitch += (currentY - y) * 0.01;
        currentX      = x;
        currentY      = y;
    }
    

    glfwGetCursorPos( _wnd, &currentX, &currentY );
    while(!glfwWindowShouldClose(window)) {
    
        float x = 0.0f, y = 0.0f, z = 0.0f;
        if ( glfwGetKey(_wnd, GLFW_KEY_W) == GLFW_PRESS )
            y = 0.1f;
        if ( glfwGetKey(_wnd, GLFW_KEY_S) == GLFW_PRESS ) {
            y = -0.1f;
        if ( glfwGetKey(_wnd, GLFW_KEY_D) == GLFW_PRESS )
            x = 0.1f;
        if ( glfwGetKey(_wnd, GLFW_KEY_A) == GLFW_PRESS ) {
            x = -0.1f;
        if ( glfwGetKey(_wnd, GLFW_KEY_Q) == GLFW_PRESS )
            z = -0.1f;
        if ( glfwGetKey(_wnd, GLFW_KEY_E) == GLFW_PRESS ) {
            z = 0.1f;
    
        // movment
        kmMat4 yaw_matrix; 
        kmMat4Translation( &transform, x, z, -y );
    
        // yaw
        kmMat4 yaw_matrix;
        kmMat4RotationY( &yaw_matrix, currenYaw );
        currenYaw = 0.0;
    
        // pitch
        kmMat4 pitch_matrix;
        kmMat4RotationX( &pitch_matrix, currentPitch );
        currentPitch = 0.0;
    
        // roatation = pitch_matrix * yaw_matrix
        kmMat4 roatation;
        kmMat4Multiply( &roatation, &yaw_matrix, &yaw_matrix );
    
        // change the camera matrix incrementally
        kmMat4Multiply( &camera.mat, &transform, &camera.mat );
        kmMat4Multiply( &camera.mat, &roatation, &camera.mat );
    
        ....
    }
    


    进一步了解:

    【讨论】:

    • 我想向相机移动,并将该值存储更多次 (x,y,z) 我不只是想在轴上移动一个固定的量,我是已经做得很好了
    • 您的“解决方案”使三角形成为世界的中心,相机围绕它旋转,所以不是我要找的东西,我正在寻找 FP 相机
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多