簡體   English   中英

在Open GL 2.0和glm中創建第一人稱相機

[英]Creating a First Person camera in Open GL 2.0 and glm

我對Open GL和c ++都很陌生,並且遇到了創建第一人稱相機的問題。 我不理解矩陣數學,所以這對我來說更加困難。 到目前為止,為了計算相機的旋轉,我已經為此做了:

void CameraFP::calculate_view()  {
    m_view = glm::rotate(m_view, this->get_rotation_x(), glm::vec3(1, 0, 0));
    m_view = glm::rotate(m_view, this->get_rotation_y(), glm::vec3(0, 1, 0));
}

每次更新調用都會調用該函數。

為了通過mous處理相機的旋轉,我做了以下工作:

void CameraFP::process_mouse(sf::Window *app)  {
    GLfloat mouse_x = app->GetInput().GetMouseX();
    GLfloat mouse_y = app->GetInput().GetMouseY();

    GLfloat mouse_x_delta = std::max(mouse_x, old_mouse_x) - std::min(mouse_x, old_mouse_x);
    GLfloat mouse_y_delta = std::max(mouse_y, old_mouse_y) - std::min(mouse_y, old_mouse_y);

    y_rot += mouse_x_delta / (float)app->GetWidth();
    x_rot += mouse_y_delta / (float)app->GetHeight();

    this->old_mouse_x = mouse_x;
    this->old_mouse_y = mouse_y;

    app->SetCursorPosition(app->GetWidth() / 2, app->GetHeight() / 2);
}

為了處理運動,我做了以下事情:

void CameraFP::process_keyboard(sf::Window *app)  {
    const sf::Input *input = &app->GetInput();

    if (input->IsKeyDown(sf::Key::W))  {
        position.z += 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        position.z -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        position.x -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        position.x += 1.0f / 100.0f;
    }
}

我的問題在於我的相機不會朝着您所面對的方向移動,並且它永遠不會停止旋轉:/。 另外,如果你能指點我的指南或Matrix數學上的東西會很棒:)

編輯2: '

我剛開始一個新的過程鼠標功能,它沿着屏幕的x軸移動,正確地為相機旋轉。 但是,如果我向左或向右移動鼠標並不重要,兩個動作都會向右旋轉。 與3d空間中的x軸相同,但這是向下發生的。 關於是什么導致這個的任何想法?

void CameraFP::process_mouse(sf::Window *app)  {
    GLfloat mouse_x = app->GetInput().GetMouseX();
    GLfloat mouse_y = app->GetInput().GetMouseY();

    GLfloat mouse_x_delta = old_mouse_x - mouse_x;
    GLfloat mouse_y_delta = old_mouse_y - mouse_y;

    if (mouse_x_delta > 0)  {
        y_rot += mouse_x_delta / (float)app->GetWidth() * 0.1f;
    } else if (mouse_x_delta < 0)  {
        y_rot -= mouse_x_delta / (float)app->GetWidth() * 0.1f;
    }
    if (mouse_y_delta > 0)  {
        x_rot += mouse_y_delta / (float)app->GetWidth() * 0.1f;
    } else if (mouse_y_delta < 0)  {
        x_rot -= mouse_y_delta / (float)app->GetWidth() * 0.1f;
    }


    if (mouse_x != old_mouse_x)  {
        m_view = glm::rotate(m_view, y_rot, glm::vec3(0, 1, 0));
    }
    if (mouse_y != old_mouse_y)  {
        m_view = glm::rotate(m_view, x_rot, glm::vec3(1, 0, 0));
    }

    this->old_mouse_x = mouse_x;
    this->old_mouse_y = mouse_y;

    app->SetCursorPosition(app->GetWidth() / 2, app->GetHeight() / 2);
}

我現在沒有時間查找我的相機代碼,但我現在可以告訴你的是,你的運動計算是完全錯誤的。
您沒有考慮相機旋轉。 你必須做這樣的事情:

if (input->IsKeyDown(sf::Key::W))  {
    position.z += sin(camera_rot_y);
}
else if (input->IsKeyDown(sf::Key::S))  {
    position.z -=  sin(camera_rot_y);
}

if (input->IsKeyDown(sf::Key::A))  {
    position.x -=  cos(camera_rot_y);
}
else if (input->IsKeyDown(sf::Key::D))  {
    position.x +=  cos(camera_rot_y);
}

你也可以使用“else if”,因為你不能同時前進和后退。^^

另外,為什么在以下代碼中使用std :: min()和max()?

GLfloat mouse_x_delta = std::max(mouse_x, old_mouse_x) - std::min(mouse_x, old_mouse_x);
GLfloat mouse_y_delta = std::max(mouse_y, old_mouse_y) - std::min(mouse_y, old_mouse_y);

如果要以相反的方向旋轉,則需要獲得負增量,這對於您的代碼是不可能的。 擺脫min()和max()函數。

順便說一句:我的相機代碼不是最有效的(使用旋轉代替直接計算),但它的工作原理。

你沒有在CameraFPm_view顯示positionCameraFP ,但我認為問題在這里:

void CameraFP::process_keyboard(sf::Window *app)  {
    const sf::Input *input = &app->GetInput();

    if (input->IsKeyDown(sf::Key::W))  {
        position.z += 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        position.z -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        position.x -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        position.x += 1.0f / 100.0f;
    }
}

您必須將矩陣與此轉換和m_view相乘。 矩陣乘法是矩陣的重要順序。 首先必須是m_view因為它是主矩陣,並且您希望從m_view旋轉向前移動。 但是有glm命名空間,並且有方法glm::translate ,它們以正確的順序相乘,你只需創建glm::vec3作為該方法的參數(用x,y,z進行轉換)。

(如果你使用相對位置 ......只有框架之間的差異)

所以你必須改變它:

void CameraFP::process_keyboard(sf::Window *app)  {
    const sf::Input *input = &app->GetInput();

    glm::vec3 pos;
    if (input->IsKeyDown(sf::Key::W))  {
        pos.z += 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::S))  {
        pos.z -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::A))  {
        pos.x -= 1.0f / 100.0f;
    }
    if (input->IsKeyDown(sf::Key::D))  {
        pos.x += 1.0f / 100.0f;
    }

    //Make translation
    m_view = glm::translate(m_view, pos);

    //Values at position 12, 13, 14 are translation x, y, z
    //Save absolute position of camera
    position = glm::vec3(m_view[12], m_view[13], m_view[14]);

}

PS:抱歉我的英語不好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM