使用glm数学库
数学知识参考3d数学部分 opengl glfwGetTime()时间函数
glm数学库
cpp #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp>矩阵和向量初始化
cpp //矩阵初始化 glm::mat4 mat = glm::mat4(1.0f) //向量初始化 glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f);基础方法
- 位移
glm::translate - 旋转
glm::rotate - 缩放
glm::scale
- 位移
简单示例
使用transform- 顶点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); } - 传递 transform值给Shader
cpp unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform"); glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
- 顶点Shader
完整代码
#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; }