zoukankan      html  css  js  c++  java
  • Camera_练习二

    试着创建你自己的LookAt函数,其中你需要手动创建一个我们在一开始讨论的观察矩阵。用你的函数实现来替换GLM的LookAt函数,看看它是否还能一样地工作

    1 glm::mat4 LookAt(glm::vec3 pos, glm::vec3 r, glm::vec3 u, glm::vec3 d){
    2     glm::mat4 a = glm::mat4(1.0f);
    3     a[0][0] = r.x; a[1][0] = r.y; a[2][0] = r.z;
    4     a[0][1] = u.x; a[1][1] = u.y; a[2][1] = u.z;
    5     a[0][2] = -d.x; a[1][2] = -d.y; a[2][2] = -d.z;
    6     glm::mat4 b = glm::mat4(1.0f);
    7     b = glm::translate(b, glm::vec3(-pos.x, -pos.y, -pos.z));
    8     return a*b;
    9 }
    View Code

    根据定义,由方向向量、右轴和上轴构成的矩阵与由摄像机坐标构成的矩阵相乘就得到LookAt矩阵了

    注意:

    1. 方向向量和我们定义的Front(摄像机的朝向)是相反的
    2. glm中矩阵的存储和现实中的矩阵是不同的,glm中矩阵的列对应着现实中矩阵的行

    最后还需调用glm::mat4 view = LookAt(camera.Position, camera.Right, camera.Up, camera.Front);即可

      1 #include <glad/glad.h>
      2 #include <GLFW/glfw3.h>
      3 #define STB_IMAGE_IMPLEMENTATION
      4 #include <stb/stb_image.h>
      5 
      6 #include <glm/glm.hpp>
      7 #include <glm/gtc/matrix_transform.hpp>
      8 #include <glm/gtc/type_ptr.hpp>
      9 
     10 #include <Shader/shader.h>
     11 #include <Camera/camera.h>
     12 
     13 #include <iostream>
     14 
     15 void framebuffer_size_callback(GLFWwindow* window, int width, int height);
     16 void mouse_callback(GLFWwindow* window, double xpos, double ypos);
     17 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
     18 void processInput(GLFWwindow *window);
     19 
     20 // settings
     21 const unsigned int SCR_WIDTH = 800;
     22 const unsigned int SCR_HEIGHT = 600;
     23 
     24 // camera
     25 Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
     26 float lastX = SCR_WIDTH / 2.0f;
     27 float lastY = SCR_HEIGHT / 2.0f;
     28 bool firstMouse = true;
     29 
     30 //timeing
     31 float deltaTime = 0.0f; // 当前帧与上一帧的时间差
     32 float lastFrame = 0.0f; // 上一帧的时间
     33 
     34 glm::mat4 LookAt(glm::vec3 pos, glm::vec3 r, glm::vec3 u, glm::vec3 d){
     35     glm::mat4 a = glm::mat4(1.0f);
     36     a[0][0] = r.x; a[1][0] = r.y; a[2][0] = r.z;
     37     a[0][1] = u.x; a[1][1] = u.y; a[2][1] = u.z;
     38     a[0][2] = -d.x; a[1][2] = -d.y; a[2][2] = -d.z;
     39     glm::mat4 b = glm::mat4(1.0f);
     40     b = glm::translate(b, glm::vec3(-pos.x, -pos.y, -pos.z));
     41     return a*b;
     42 }
     43 
     44 int main()
     45 {
     46     // glfw: initialize and configure
     47     // ------------------------------
     48     glfwInit();
     49     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
     50     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
     51     glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
     52 
     53 #ifdef __APPLE__
     54     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
     55 #endif
     56 
     57     // glfw window creation
     58     // --------------------
     59     GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
     60     if (window == NULL)
     61     {
     62         std::cout << "Failed to create GLFW window" << std::endl;
     63         glfwTerminate();
     64         return -1;
     65     }
     66     glfwMakeContextCurrent(window);
     67     glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
     68     glfwSetCursorPosCallback(window, mouse_callback);
     69     glfwSetScrollCallback(window, scroll_callback);
     70 
     71     // tell GLFW to capture our mouse
     72     glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
     73 
     74     // glad: load all OpenGL function pointers
     75     // ---------------------------------------
     76     if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
     77     {
     78         std::cout << "Failed to initialize GLAD" << std::endl;
     79         return -1;
     80     }
     81 
     82     // configure global opengl state
     83     // -----------------------------
     84     glEnable(GL_DEPTH_TEST);
     85 
     86     // build and compile our shader zprogram
     87     // ------------------------------------
     88     Shader ourShader("vs.in", "fs.in");
     89 
     90     // set up vertex data (and buffer(s)) and configure vertex attributes
     91     // ------------------------------------------------------------------
     92     float vertices[] = {
     93         -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
     94         0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
     95         0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
     96         0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
     97         -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
     98         -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
     99 
    100         -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
    101         0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
    102         0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
    103         0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
    104         -0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
    105         -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
    106 
    107         -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
    108         -0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
    109         -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
    110         -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
    111         -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
    112         -0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
    113 
    114         0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
    115         0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
    116         0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
    117         0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
    118         0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
    119         0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
    120 
    121         -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
    122         0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
    123         0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
    124         0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
    125         -0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
    126         -0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
    127 
    128         -0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
    129         0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
    130         0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
    131         0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
    132         -0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
    133         -0.5f, 0.5f, -0.5f, 0.0f, 1.0f
    134     };
    135     // world space positions of our cubes
    136     glm::vec3 cubePositions[] = {
    137         glm::vec3(0.0f, 0.0f, 0.0f),
    138         glm::vec3(2.0f, 5.0f, -15.0f),
    139         glm::vec3(-1.5f, -2.2f, -2.5f),
    140         glm::vec3(-3.8f, -2.0f, -12.3f),
    141         glm::vec3(2.4f, -0.4f, -3.5f),
    142         glm::vec3(-1.7f, 3.0f, -7.5f),
    143         glm::vec3(1.3f, -2.0f, -2.5f),
    144         glm::vec3(1.5f, 2.0f, -2.5f),
    145         glm::vec3(1.5f, 0.2f, -1.5f),
    146         glm::vec3(-1.3f, 1.0f, -1.5f)
    147     };
    148     unsigned int VBO, VAO;
    149     glGenVertexArrays(1, &VAO);
    150     glGenBuffers(1, &VBO);
    151 
    152     glBindVertexArray(VAO);
    153 
    154     glBindBuffer(GL_ARRAY_BUFFER, VBO);
    155     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    156 
    157     // position attribute
    158     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
    159     glEnableVertexAttribArray(0);
    160     // texture coord attribute
    161     glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
    162     glEnableVertexAttribArray(1);
    163 
    164 
    165     // load and create a texture 
    166     // -------------------------
    167     unsigned int texture1, texture2;
    168     // texture 1
    169     // ---------
    170     glGenTextures(1, &texture1);
    171     glBindTexture(GL_TEXTURE_2D, texture1);
    172     // set the texture wrapping parameters
    173     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    174     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    175     // set texture filtering parameters
    176     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    177     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    178     // load image, create texture and generate mipmaps
    179     int width, height, nrChannels;
    180     stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    181     unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
    182     if (data)
    183     {
    184         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    185         glGenerateMipmap(GL_TEXTURE_2D);
    186     }
    187     else
    188     {
    189         std::cout << "Failed to load texture" << std::endl;
    190     }
    191     stbi_image_free(data);
    192     // texture 2
    193     // ---------
    194     glGenTextures(1, &texture2);
    195     glBindTexture(GL_TEXTURE_2D, texture2);
    196     // set the texture wrapping parameters
    197     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    198     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    199     // set texture filtering parameters
    200     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    201     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    202     // load image, create texture and generate mipmaps
    203     data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
    204     if (data)
    205     {
    206         // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA
    207         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    208         glGenerateMipmap(GL_TEXTURE_2D);
    209     }
    210     else
    211     {
    212         std::cout << "Failed to load texture" << std::endl;
    213     }
    214     stbi_image_free(data);
    215 
    216     // tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
    217     // -------------------------------------------------------------------------------------------
    218     ourShader.use();
    219     ourShader.setInt("texture1", 0);
    220     ourShader.setInt("texture2", 1);
    221 
    222     // pass projection matrix to shader (as projection matrix rarely changes there's no need to do this per frame)
    223     // -----------------------------------------------------------------------------------------------------------
    224     //glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
    225     //ourShader.setMat4("projection", projection);
    226 
    227 
    228     // render loop
    229     // -----------
    230     while (!glfwWindowShouldClose(window))
    231     {
    232         float currentFrame = glfwGetTime();
    233         deltaTime = currentFrame - lastFrame;
    234         lastFrame = currentFrame;
    235 
    236         // input
    237         // -----
    238         processInput(window);
    239 
    240         // render
    241         // ------
    242         glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    243         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    244 
    245         // bind textures on corresponding texture units
    246         glActiveTexture(GL_TEXTURE0);
    247         glBindTexture(GL_TEXTURE_2D, texture1);
    248         glActiveTexture(GL_TEXTURE1);
    249         glBindTexture(GL_TEXTURE_2D, texture2);
    250 
    251         // activate shader
    252         ourShader.use();
    253 
    254         // pass projection matrix to shader (note that in this case it could change every frame)
    255         glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
    256         ourShader.setMat4("projection", projection);
    257 
    258         // camera/view transformation
    259 
    260         //glm::mat4 view = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
    261         //float radius = 10.0f;
    262         //float camX = sin(glfwGetTime()) * radius;
    263         //float camZ = cos(glfwGetTime()) * radius;
    264         //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));
    265 
    266         //glm::mat4 view = camera.GetViewMatrix();
    267         glm::mat4 view = LookAt(camera.Position, camera.Right, camera.Up, camera.Front);
    268         ourShader.setMat4("view", view);
    269 
    270         // render boxes
    271         glBindVertexArray(VAO);
    272         for (unsigned int i = 0; i < 10; i++)
    273         {
    274             // calculate the model matrix for each object and pass it to shader before drawing
    275             glm::mat4 model = glm::mat4(1.0f);
    276             model = glm::translate(model, cubePositions[i]);
    277             float angle = 20.0f * i;
    278             model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
    279             ourShader.setMat4("model", model);
    280 
    281             glDrawArrays(GL_TRIANGLES, 0, 36);
    282         }
    283 
    284         // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
    285         // -------------------------------------------------------------------------------
    286         glfwSwapBuffers(window);
    287         glfwPollEvents();
    288     }
    289 
    290     // optional: de-allocate all resources once they've outlived their purpose:
    291     // ------------------------------------------------------------------------
    292     glDeleteVertexArrays(1, &VAO);
    293     glDeleteBuffers(1, &VBO);
    294 
    295     // glfw: terminate, clearing all previously allocated GLFW resources.
    296     // ------------------------------------------------------------------
    297     glfwTerminate();
    298     return 0;
    299 }
    300 
    301 // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
    302 // ---------------------------------------------------------------------------------------------------------
    303 void processInput(GLFWwindow *window)
    304 {
    305     if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
    306         glfwSetWindowShouldClose(window, true);
    307 
    308     if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
    309         camera.ProcessKeyboard(FORWARD, deltaTime);
    310     if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
    311         camera.ProcessKeyboard(BACKWARD, deltaTime);
    312     if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
    313         camera.ProcessKeyboard(LEFT, deltaTime);
    314     if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
    315         camera.ProcessKeyboard(RIGHT, deltaTime);
    316 }
    317 
    318 // glfw: whenever the window size changed (by OS or user resize) this callback function executes
    319 // ---------------------------------------------------------------------------------------------
    320 void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    321 {
    322     // make sure the viewport matches the new window dimensions; note that width and 
    323     // height will be significantly larger than specified on retina displays.
    324     glViewport(0, 0, width, height);
    325 }
    326 
    327 void mouse_callback(GLFWwindow* window, double xpos, double ypos){
    328     if (firstMouse)
    329     {
    330         lastX = xpos;
    331         lastY = ypos;
    332         firstMouse = false;
    333     }
    334 
    335     float xoffset = xpos - lastX;
    336     float yoffset = lastY - ypos;
    337     //std::cout << ypos << std::endl;
    338     lastX = xpos;
    339     lastY = ypos;
    340 
    341     camera.ProcessMouseMovement(xoffset, yoffset);
    342 }
    343 
    344 // glfw: whenever the mouse scroll wheel scrolls, this callback is called
    345 // ----------------------------------------------------------------------
    346 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
    347 {
    348     camera.ProcessMouseScroll(yoffset);
    349 }
    View Code
  • 相关阅读:
    Cryptography I 学习笔记 --- 使用分组密码
    Cryptography I 学习笔记 --- 分组密码
    jQuery动画之自定义动画
    jQuery事件之一次性事件
    jQuery事件之自定义事件
    jQuery事件之解绑事件
    jQuery事件之绑定事件
    jQuery动画之停止动画
    JQuery动画之淡入淡出动画
    jQuery属性操作之值操作
  • 原文地址:https://www.cnblogs.com/ljy08163268/p/11959691.html
Copyright © 2011-2022 走看看