使用glm数学库

数学知识参考3d数学部分 opengl glfwGetTime()时间函数

  1. glm数学库 cpp #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp>

  2. 矩阵和向量初始化 cpp //矩阵初始化 glm::mat4 mat = glm::mat4(1.0f) //向量初始化 glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f);

  3. 基础方法

    1. 位移 glm::translate
    2. 旋转 glm::rotate
    3. 缩放 glm::scale
  4. 简单示例 使用transform

    1. 顶点Shader cpp #version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTexCoord; out vec2 TexCoord; uniform mat4 transform; //传递tranform矩阵,包含旋转偏移缩放量 void main() { gl_Position = transform * vec4(aPos, 1.0f); TexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y); }
    2. 传递 transform值给Shader cpp unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
  5. 完整代码

        #include "glad/glad.h"
        #include "GLFW/glfw3.h"
        //图片库
        #define STB_IMAGE_IMPLEMENTATION
        #include "stb_image.h"
        //glm OpenGL Math库
        #include "glm/glm.hpp"
        #include "glm/gtc/matrix_transform.hpp"
        #include "glm/gtc/type_ptr.hpp"
        #include "shader.h"
        #include <iostream>
        using namespace std;
        const int wWidth = 800, wHeight = 600;
        const char* wName = "LearnOpenGL";
        float vertices[] = {
            //位置                    // 基础颜色          // 题图uv
                0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f, // top right
                0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f, // bottom right
               -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom left
               -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f  // top left 
        };
        unsigned int indices[] = {
            0, 1, 3, //  第一个三角形
            1, 2, 3  //  第二个三角形
        };
        void framebuffer_size_callback(GLFWwindow* window, int width, int height)
        {
            glViewport(0, 0, width, height);
        }
        void processInput(GLFWwindow *window)
        {
            if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
                glfwSetWindowShouldClose(window, true);
        }
        int main()
        {
            //1. 初始化
            if (glfwInit() == GLFW_FALSE)
            {
                cout << "init glfw fail";
                return 1;
            }
            //2. 基本设置
            glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
            glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
            glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        #if __APPLE__
            glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
        #endif
            //3. 创建窗口
            GLFWwindow *window = glfwCreateWindow(wWidth, wHeight, wName, nullptr, nullptr);
            if (window == nullptr)
            {
                cout << "Failed to create GLFW window";
                goto TERMINATE;
                //return 1;
            }
            //4. 当前主线程上下文窗口
            glfwMakeContextCurrent(window);
            //5. 使用glad管理OpenGL指针。
            if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
            {
                std::cout << "Failed to initialize GLAD" << std::endl;
                goto TERMINATE;
                //return 1;
            }
            //6. 设置视口
            glViewport(0, 0, wWidth, wHeight);
            //7. 设置resize回调,对应刷新视口
            glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
            Shader shader("res/shaders/sample_vertex_transoform.shader", "res/shaders/sample_fragment_transoform.shader");
            unsigned int VBO, VAO, EBO;
            glGenVertexArrays(1, &VAO);
            glBindVertexArray(VAO);
            glGenBuffers(1, &VBO);
            glBindBuffer(GL_ARRAY_BUFFER, VBO);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
            glGenBuffers(1, &EBO);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
            //1. 指定顶点的顶点属性的结构,顶点 3个float,从0开始,整体每一组数据8个。
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
            //2. 指定颜色的顶点属性的结构,三色 3个float,从3开始,整体每一组数据8个。
            glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
            glEnableVertexAttribArray(1);
            //3. 指定uv的顶点属性的结构,uv 2个float,从6开始,整体每一组数据8个。
            glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
            glEnableVertexAttribArray(2);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
            glBindVertexArray(0);
            unsigned int texture1, texture2;
            //加载贴图1
            glGenTextures(1, &texture1);
            glBindTexture(GL_TEXTURE_2D, texture1);
            // 设置 wrapping 参数
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            // 设置  filtering 参数
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            // 加载解析贴图文件
            int width, height, nrChannels;
            stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
            unsigned char* data = stbi_load("./res/textures/container.jpg", &width, &height, &nrChannels, 0);
            if (data)
            {
                //第一个 GL_RGB 将被转换的格式, 第二个GL_RGB原始文件的格式, 格式不匹配会报错。
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
                glGenerateMipmap(GL_TEXTURE_2D);
            }
            else
            {
                std::cout << "Failed to load texture" << std::endl;
            }
            stbi_image_free(data);
            //加载贴图2
            glGenTextures(1, &texture2);
            glBindTexture(GL_TEXTURE_2D, texture2);
            //  设置 wrapping 参数
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
            // 设置  filtering 参数
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            // l加载解析贴图文件
            data = stbi_load("./res/textures/awesomeface.png", &width, &height, &nrChannels, 0);
            if (data)
            {
                //第一个 GL_RGB 将被转换的格式, 第二个GL_RGB原始文件的格式, 格式不匹配会报错。
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
                glGenerateMipmap(GL_TEXTURE_2D);
            }
            else
            {
                std::cout << "Failed to load texture" << std::endl;
            }
            stbi_image_free(data);
            //指定采样器贴图储存的位置
            shader.use();
            shader.setInt("texture1", 0);
            shader.setInt("texture2", 1);
            while (!glfwWindowShouldClose(window))
            {
                processInput(window);
                glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
                glClear(GL_COLOR_BUFFER_BIT);
                // bind Texture1
                glActiveTexture(GL_TEXTURE0);
                glBindTexture(GL_TEXTURE_2D, texture1);
                // bind Texture2
                glActiveTexture(GL_TEXTURE1);
                glBindTexture(GL_TEXTURE_2D, texture2);
                glm::mat4 transform = glm::mat4(1.0f); 
                transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
                transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
                shader.use();
                unsigned int transformLoc = glGetUniformLocation(shader.ID, "transform");
                glUniformMatrix4fv(transformLoc, (float)glfwGetTime(), GL_FALSE, glm::value_ptr(transform));
                glBindVertexArray(VAO);
                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
                glfwSwapBuffers(window);
                glfwPollEvents();
            }
            glDeleteVertexArrays(1, &VAO);
            glDeleteBuffers(1, &VBO);
            glDeleteBuffers(1, &EBO);
        TERMINATE:
            glfwTerminate();
            return 0;
        }

文章作者: Yonggang Long
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yonggang Long !
 上一篇
2022-08-10 Yonggang Long
下一篇 
2022-08-10 Yonggang Long
  目录