OpenGL调用窗口,方向键和鼠标

时间:2024-04-17 08:50:01
9.2 OpenGL调用窗口,方向键和鼠标
9.2.1 opengl调用窗口

OpenGL调用窗口步骤:

第一步:初始化 GLFW,初始化OpenGL,初始化窗口,初始化上下文

第二步:设置窗口大小和位置,设置输入输出

第三步:循环渲染

第四步:终止

示例代码:

#include <glew.h>
#include <glfw3.h>
#include <iostream>

void processInput(GLFWwindow* window)
{
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

int main()
{
  //第一步:初始化glfw,
    glfwInit();//初始化glfw
  	//glfwWindowHint初始化glfw的版本
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//主版本
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//次版本
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//配置
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);//mac上使用
    //初始化窗口
    GLFWwindow* window = glfwCreateWindow(800, 600, "learnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
   //初始化上下文
    glfwMakeContextCurrent(window); //将主线程设置为当前渲染环境

    //Init GLEW
    glewExperimental = true;
    if(glewInit() != GLEW_OK)
    {
        printf("Init GLEW failed.");
        glfwTerminate();
        return -1;
    }
  //第二步:设置窗口大小和位置
    glViewport(0, 0, 800, 600);//前两个参数窗口左下角的位置。后两个渲染窗口的宽度和高度
    while (!glfwWindowShouldClose(window))
    {
        processInput(window); ///设置输入输出
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//前面三个参数是RGB,后面一个参数是透明度
        glClear(GL_COLOR_BUFFER_BIT);
        glfwSwapBuffers(window);//函数在每次循环迭代开始时检查 GLFW 是否已被指示关闭
        glfwPollEvents();//函数检查是否触发了任何事件

    }
    glfwTerminate();//第四步:清理
    return 0;
}
9.2.2 opengl 调用方向键

调用方向键主要是考虑按键和移动速度,修改的办法是在上面调用窗口的设置函数processInput上进行修改;

void processInput(GLFWwindow *window)
{
    ...
    const float cameraSpeed = 0.05f; // adjust accordingly
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)//按下W键
        cameraPos += cameraSpeed * cameraFront;//cameraFront相机超向
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)//按下S键
        cameraPos -= cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)//按下A键
        cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)//按下D键
        cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
}
9.2.3 opengl调用鼠标

OpenGL 调用鼠标主要考虑鼠标的移动和缩放,主要是使用下面3个函数:

glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //隐藏并捕获光标
void mouse_callback(GLFWwindow* window, double xpos, double ypos);//监听鼠标移动事件xpos和ypos代表当前鼠标位置
glfwSetCursorPosCallback(window, mouse_callback)

计算鼠标光标步骤:

  1. 计算鼠标自上一帧以来的偏移量。
  2. 将偏移值添加到相机的偏航和俯仰值中。
  3. 为最小/最大音高值添加一些约束。
  4. 计算方向向量。

代码:

void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
    if (firstMouse)// initially set to true,保证初次使用不会大幅度跳跃
    {
        lastX = xpos;
        lastY = ypos;
        firstMouse = false;
    }
  
    float xoffset = xpos - lastX;
    float yoffset = lastY - ypos; 
    lastX = xpos;
    lastY = ypos;

    float sensitivity = 0.1f; //乘以灵敏度值,降低鼠标移动太剧烈
    xoffset *= sensitivity;
    yoffset *= sensitivity;

    yaw   += xoffset;//偏移值加入俯仰
    pitch += yoffset;//偏移值加入偏航

    if(pitch > 89.0f)///加入约束
        pitch = 89.0f;
    if(pitch < -89.0f)
        pitch = -89.0f;

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

(2)鼠标缩放

void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
    fov -= (float)yoffset;
    if (fov < 1.0f)
        fov = 1.0f;
    if (fov > 45.0f)
        fov = 45.0f; 
}

projection = glm::perspective(glm::radians(fov), 800.0f / 600.0f, 0.1f, 100.0f);  
glfwSetScrollCallback(window, scroll_callback);