c - OpenGL,第一人称相机翻译

标签 c opengl 3d camera coordinate-transformation

我一直在想如何让我的 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,它就可以完美工作......所以这不是矩阵的问题乘法

最佳答案

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

world to view

因此,必须首先将场景引用系统中的每个点和每个 vector 转换为视口(viewport)坐标。这可以通过下表轻松处理:

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


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

movement and rotation


您的代码应该看起来像这样:

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 );

    ....
}


进一步查看:

关于c - OpenGL,第一人称相机翻译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46508872/

相关文章:

c - 全局指针值丢失。 2个文件

c++ - OpenGL 库

c - 绕 Y 轴旋转 gluLookAt

html - WebGL模型简化

python - 在 3D 绘图中显示真彩色 2D RGB 纹理?

python - Python 中的 3D 网格图

C 缓冲内存分配

C 编程 - 使用递归求和

opengl - 在 OpenGL 中绘制带颜色的多边形会导致纹理颜色发生变化

ios - 深度纹理作为颜色附件