OpenGL学习7——相机

2021-06-19  本文已影响0人  蓬篙人

1. 相机/视空间

glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget);
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection));
glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight);

2. Look At

glm::mat4 view;
view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f),
                   glm::vec3(0.0f, 0.0f, 0.0f),
                   glm::vec3(0.0f, 1.0f, 0.0f));
const float radius = 10.0f;
float camX = sin(glfwGetTime()) * radius;
float camZ = cos(glfwGetTime()) * radius;
glm::mat4 view;
view = glm::lookAt(glm::vec3(camX, 0.0f, camZ), glm::vec3(0.0f, 0.0f, 0.0f),
                   glm::vec3(0.0f, 1.0f, 0.0f));

3. 用键盘控制相机位置

glm::vec3 cameraPos   = glm::vec3(0.0f,  0.0f,  3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f,  0.0f, -1.0f);
glm::vec3 cameraUp    = glm::vec3(0.0f,  1.0f,  0.0f);
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
void processInput(GLFWwindow* window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);

    const float cameraSpeed = 2.5f * deltaTime;  // 根据需要调整
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
        cameraPos += cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
        cameraPos -= cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
        cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
        cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
}

4. 改进相机移动速度

// 定义两个追踪变量(全局)
float deltaTime = 0.0f;   // 当前帧与上一帧的时间
float lastFrame = 0.0f;   // 上一帧的渲染时间
// 计算(渲染循环中)
float currentTime = glfwGetTime();
deltaTime = currentTime - lastFrame;
lastFrame = currentTime;
const float cameraSpeed = 2.5f * deltaTime;

5. 鼠标控制相机

5.1 欧拉角与相机的方向矢量

glm::vec3 direction;
direction.x = cos(glm::radians(yaw));
direction.z = sin(glm::radians(yaw));
direction.y = sin(glm::radians(pitch));
direction.x = cos(glm::radians(yaw) * cos(glm::radians(pitch)));
direction.y = sin(glm::radians(pitch));
direction.z = sin(glm::radians(yaw) * cos(glm::radians(pitch)));
// yaw初始值
yaw = -90.0f;

5.2 通过鼠标设置相机方向矢量

下面通过获取鼠标的水平移动设置yaw值,通过鼠标的垂直移动设置pitch值。

glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// 函数原型
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
glfwSetCursorPosCallback(window, mouse_callback);
// 定义全局变量
float lastX = 400, lastY = 300;   // 初始化为屏幕中心位置
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
//---------------------回调函数
// 放置初次进入出现跳跃
if (firstMouse)
{
    lastX = xpos;
    lastY = ypos;
    firstMouse = false;
}
// 4.1 计算偏移量
float xoffset = xpos - lastX;
float yoffset = lastY - ypos;  // 相反,y是从底到上
lastX = xpos;
lastY = ypos;
// 放置鼠标移动太过距离
const float sensitivity = 0.1f;
xoffset *= sensitivity;
yoffset *= sensitivity;
// 4.2 
yaw += xoffset;
pitch += yoffset;
// 4.3
if (pitch > 89.0f)
    pitch = 89.0f;
if (pitch < -89.0f)
    pitch = -89.0f;
// 4.4
glm::vec3 direction;
direction.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
direction.y = sin(glm::radians(pitch));
direction.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraFront = glm::normalize(direction);

5.3 鼠标滚轮进行变焦(zoom)

glfwSetScrollCallback(window, scroll_callback);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
    fov -= (float)yoffset;
    // 将视野限制在1.0到45.0之间
    if (fov < 1.0f)
        fov = 1.0f;
    if (fov > 45.0f)
        fov = 45.0f;
}
glm::mat4 projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);
上一篇 下一篇

猜你喜欢

热点阅读