重点:
需要采用glm库进行矩阵的功能操作。
矩阵进行操作的时候是存在顺序的:缩放->旋转->位移;
y'=y*缩放*旋转*位移
位移*旋转*缩放*y =y'
采用右向左读这个乘法。在组合矩阵时,先进行缩放操作,然后是旋转,最后才是位移,否则它们会(消极地)互相影响。比如,如果你先位移再缩放,位移的向量也会同样被缩放(译注:比如向某方向移动2米,2米也许会被缩放成1米)!
glm-0.9.8.5
链接:https://pan.baidu.com/s/1GsaewfRIDH5XnQSLweT93A?pwd=ay5h
提取码:ay5h
结果:
代码:
vertex.txt
- #version 330 core
- layout (location = 0) in vec3 aPos;
- layout (location = 1) in vec3 aColor;
- layout (location = 2) in vec2 aTexCoord;
-
- out vec3 ourColor;
- out vec2 TexCoord;
-
- uniform mat4 transform;
- void main()
- {
- gl_Position = transform * vec4(aPos, 1.0f);
- ourColor = aColor;
- TexCoord = aTexCoord;
- }
fragment.txt
- #version 330 core
- out vec4 FragColor;
-
- in vec3 ourColor;
- in vec2 TexCoord;
-
- uniform sampler2D texture1;
- uniform sampler2D texture2;
- uniform float factor;
-
- void main()
- {
- FragColor = mix(texture(texture1, TexCoord), texture(texture2, vec2(-TexCoord.x,TexCoord.y)), abs(sin(factor*0.2)));
- }
main.cpp
- #include <glad/glad.h>
- #include <GLFW/glfw3.h>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #include "Shader.h"
-
-
- #include <iostream>
- #define STB_IMAGE_IMPLEMENTATION
- #include "stb_image.h"
-
- void framebuffer_size_callback(GLFWwindow* window, int width, int height);
- void processInput(GLFWwindow* window);
-
- // settings
- const unsigned int SCR_WIDTH = 800;
- const unsigned int SCR_HEIGHT = 600;
-
- int main()
- {
- // glfw: initialize and configure
- // ------------------------------
- glfwInit();
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-
- #ifdef __APPLE__
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- #endif
-
- // glfw window creation
- // --------------------
- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
- if (window == NULL)
- {
- std::cout << "Failed to create GLFW window" << std::endl;
- glfwTerminate();
- return -1;
- }
- glfwMakeContextCurrent(window);
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
-
- // glad: load all OpenGL function pointers
- // ---------------------------------------
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
- {
- std::cout << "Failed to initialize GLAD" << std::endl;
- return -1;
- }
-
- // build and compile our shader zprogram
- // ------------------------------------
- Shader ourShader(".//text//vertex.txt", ".//text//fragment.txt");
-
- // set up vertex data (and buffer(s)) and configure vertex attributes
- // ------------------------------------------------------------------
- float vertices[] = {
- // positions // colors // texture coords
- 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, // first triangle
- 1, 2, 3 // second triangle
- };
- unsigned int VBO, VAO, EBO;
- glGenVertexArrays(1, &VAO);
- glGenBuffers(1, &VBO);
- glGenBuffers(1, &EBO);
-
- glBindVertexArray(VAO);
-
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
-
- // position attribute
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- // color attribute
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
- glEnableVertexAttribArray(1);
- // texture coord attribute
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
- glEnableVertexAttribArray(2);
-
-
- // load and create a texture
- // -------------------------
- unsigned int texture1, texture2;
- // texture 1
- // ---------
- glGenTextures(1, &texture1);
- glBindTexture(GL_TEXTURE_2D, texture1);
- // set the texture wrapping parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- // set texture filtering parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- // load image, create texture and generate mipmaps
- int width, height, nrChannels;
- //在图像加载时帮助我们翻转y轴
- stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
- // The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
- unsigned char* data = stbi_load(".//resource//container.jpg", &width, &height, &nrChannels, 0);
- if (data)
- {
- 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);
- 设置边缘颜色值
- //float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
- //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
- // texture 2
- // ---------
- glGenTextures(1, &texture2);
- glBindTexture(GL_TEXTURE_2D, texture2);
- // set the texture wrapping parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method)
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- // set texture filtering parameters
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- // load image, create texture and generate mipmaps
- data = stbi_load(".//resource//awesomeface.png", &width, &height, &nrChannels, 0);
- if (data)
- {
- // 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
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 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);
- // tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
- // -------------------------------------------------------------------------------------------
- ourShader.use(); // don't forget to activate/use the shader before setting uniforms!
- // either set it manually like so:
- glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
- // or set it via the texture class
- ourShader.setInt("texture2", 1);
-
-
- float factor = 0.0;
-
-
- // render loop
- // -----------
- while (!glfwWindowShouldClose(window))
- {
- // input
- // -----
- processInput(window);
-
- // render
- // ------
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- // bind textures on corresponding texture units
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture1);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texture2);
-
- // render container
- ourShader.use();
- factor = glfwGetTime();
- ourShader.setFloat("factor", factor);
-
- //旋转缩放矩阵
- glm::mat4 trans;
- GLM希望它的角度是弧度制的,绕z轴旋转
- trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
- //进行平移
- trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
- unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
- glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
-
-
- glBindVertexArray(VAO);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
-
- // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
- // -------------------------------------------------------------------------------
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
-
- // optional: de-allocate all resources once they've outlived their purpose:
- // ------------------------------------------------------------------------
- glDeleteVertexArrays(1, &VAO);
- glDeleteBuffers(1, &VBO);
- glDeleteBuffers(1, &EBO);
- // glfw: terminate, clearing all previously allocated GLFW resources.
- // ------------------------------------------------------------------
- glfwTerminate();
- return 0;
- }
- // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
- // ---------------------------------------------------------------------------------------------------------
- void processInput(GLFWwindow* window)
- {
- if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
- glfwSetWindowShouldClose(window, true);
- }
- // glfw: whenever the window size changed (by OS or user resize) this callback function executes
- // ---------------------------------------------------------------------------------------------
- void framebuffer_size_callback(GLFWwindow* window, int width, int height)
- {
- // make sure the viewport matches the new window dimensions; note that width and
- // height will be significantly larger than specified on retina displays.
- glViewport(0, 0, width, height);
- }