向量有一个方向和一个大小。如果一个向量有2个维度,它表示一个平面的方向(想象一下2D的图像),当它有3个维度的时候它可以表达一个3D世界的方向。
可以把这些2D向量当做z坐标为0的3D向量。

向量的点乘(内积):简单来说就是可以判断向量方向的相似性


向量外积:简单来说就是可以得到其法向量

向量的加法可以被定义为是分量的(Component-wise)相加,即将一个向量中的每一个分量加上另一个向量的对应分量。
v = (4, 2)和k = (1, 2)相加得到(4+1,2+2)

向量的减法等于加上第二个向量的相反向量。两个向量的相减会得到这两个向量指向位置的差。

我们使用勾股定理(Pythagoras Theorem)来获取向量的长度(Length)/大小(Magnitude)。如果你把向量的x与y分量画出来,该向量会和x与y分量为边形成一个三角形。



texture.vs
- #version 330 core
- layout (location = 0) in vec3 aPos;
- layout (location = 1) in vec2 aTexCorrd;
-
- out vec2 TexCoord;
-
- uniform mat4 transform;
- void main()
- {
- gl_Position = transform * vec4(aPos, 1.0);
- TexCoord=vec2(aTexCorrd.x,1.0-aTexCorrd.y);
- }
texture.fs
- #version 330 core
- out vec4 FragColor;
-
- in vec3 ourColor;
- in vec2 TexCoord;
-
- uniform float mixValue;
-
- //texture sampler
- uniform sampler2D textureone;
- uniform sampler2D texturetwo;
-
- void main()
- {
- FragColor = mix(texture(textureone,TexCoord),texture(texturetwo,TexCoord),mixValue);
- }
shader.h
- #pragma once
-
- #include
- #include
- #include
- #include
- #include
-
-
- class Shader {
- public:
- //程序ID
- unsigned int ID;
-
- //构造器读取并构建着色器
- Shader(const char* vertexPath, const char* fagmentPath) {
- std::string vertexCode;
- std::string fragmentCode;
- std::ifstream vShaderFile;
- std::ifstream fShaderFile;
-
- vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
- fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
-
- try {
- vShaderFile.open(vertexPath);
- fShaderFile.open(fagmentPath);
- std::stringstream vShaderStream, fShaderStream;
- vShaderStream << vShaderFile.rdbuf();
- fShaderStream << fShaderFile.rdbuf();
- vShaderFile.close();
- fShaderFile.close();
- vertexCode = vShaderStream.str();
- fragmentCode = fShaderStream.str();
- }
- catch (std::ifstream::failure& e) {
- std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;
- }
- const char* vShaderCode = vertexCode.c_str();
- const char* fShaderCode = fragmentCode.c_str();
-
- //2.complie shaders
- unsigned int vertex, fragment;
- //vertex shader
- vertex = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertex, 1, &vShaderCode, NULL);
- glCompileShader(vertex);
- checkCompileErros(vertex, "VERTEX");
- //fragment Shader
- fragment = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragment, 1, &fShaderCode, NULL);
- glCompileShader(fragment);
- checkCompileErros(fragment, "FRAGMENT");
- //shader Program
- ID = glCreateProgram();
- glAttachShader(ID, vertex);
- glAttachShader(ID, fragment);
- glLinkProgram(ID);
- checkCompileErros(ID, "PROGAM");
-
- glDeleteShader(vertex);
- glDeleteShader(fragment);
-
-
- }
- //使用/激活程序
- void use() {
- glUseProgram(ID);
- }
- //uniform工具函数
- void setBool(const std::string& name, bool value) const {
- glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
- }
- void setInt(const std::string& name, int value) const {
- glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
- }
- void setFloat(const std::string& name, float value) const {
- glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
- }
-
-
- private:
- void checkCompileErros(unsigned int shader, std::string type) {
- int success;
- char infoLog[1024];
- if (type != "PROGRAM") {
- glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
- if (!success) {
- glGetShaderInfoLog(shader, 1024, NULL, infoLog);
- std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
- }
- }
- else
- {
- glGetProgramiv(shader, GL_LINK_STATUS, &success);
- if (!success)
- {
- glGetProgramInfoLog(shader, 1024, NULL, infoLog);
- std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
- }
- }
- }
- };
main.cpp
下载glm
Tags · g-truc/glm (github.com)
- #include
- #include
-
- #include
- #include "stb_image.h"
- #include
- #include "shader.h"
-
- #include
- #include
- #include
- 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;
-
- float mixValue = 0.2f;
-
- int main() {
-
- //1.初始化配置
- 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, GLFW_TRUE);
- #endif // __APPLE__
-
- //2.gltf 窗口创建
- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);
- if (window == NULL) {
- std::cout << "Failed to create GLFW window" << std::endl;
- glfwTerminate();
- return -1;
- }
-
- glfwMakeContextCurrent(window);
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
-
- //3. 加载所有GL函数指针
- if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
- std::cout << "Failed to initialize GLAD" << std::endl;
- return -1;
- }
-
- Shader ourShader("./texture.vs", "./texture.fs");
-
- //4. 设置顶点数据
- float vertices[] = {
- // positions // colors // texture coords
- 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // top right
- 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
- -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
- -0.5f, 0.5f, 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);//元素缓冲对象:Element Buffer Object,EBO
-
- glBindVertexArray(VAO);
-
- //复制顶点数组到缓冲区中供opengl使用
- 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);
-
-
- //设置顶点属性指针
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
- glEnableVertexAttribArray(0);
- //设置纹理属性指针
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
- glEnableVertexAttribArray(1);
-
- //加载和创建纹理
- unsigned int textureone,texturetwo;
- glGenTextures(1, &textureone);
- glBindTexture(GL_TEXTURE_2D, textureone);
- //设置纹理环绕参数
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- //设置纹理过滤参数
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- //加载图像和生成mipmaps
- int width, height, nrChannels;
- stbi_set_flip_vertically_on_load(true);
- std::string filePath = R"(D:\CPlusProject\LearnOpenGL\DataSet\container.jpg)";
- unsigned char* data = stbi_load(filePath.c_str(), &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);
-
-
- glGenTextures(1, &texturetwo);
- glBindTexture(GL_TEXTURE_2D, texturetwo);
- //设置纹理环绕参数
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- //设置纹理过滤参数
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- //加载图像和生成mipmaps
- filePath = R"(D:\CPlusProject\LearnOpenGL\DataSet\awesomeface.png)";
- unsigned char* data2 = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);
-
- if (data2) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);
- glGenerateMipmap(GL_TEXTURE_2D);
- }
- else {
- std::cout << "Failed to load texture" << std::endl;
- }
-
- stbi_image_free(data2);
-
-
-
- ourShader.use();
- glUniform1i(glGetUniformLocation(ourShader.ID, "textureone"), 0);//二选一
- ourShader.setInt("texturetwo", 1);//二选一
-
-
- //glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f);
- 译注:下面就是矩阵初始化的一个例子,如果使用的是0.9.9及以上版本
- //glm::mat4 trans = glm::mat4(1.0f);
- //trans = glm::translate(trans, glm::vec3(1.0f, 1.0f, 0.0f));
- //vec = trans * vec;
- //std::cout << vec.x << vec.y << vec.z << std::endl;
-
- glm::mat4 trans = glm::mat4(1.0f);
- trans = glm::rotate(trans, glm::radians(90.f), glm::vec3(0.0, 0.0, 1.0));
- trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
- unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
- glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
-
- //5. 循环渲染
- while (!glfwWindowShouldClose(window)) {
- processInput(window);
-
- // render
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- //绑定纹理
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureone);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texturetwo);
-
-
- ourShader.setFloat("mixValue", mixValue);
-
-
- ourShader.use();
- glBindVertexArray(VAO);
- glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
-
- glfwSwapBuffers(window);
- glfwPollEvents();
-
- }
-
- glDeleteVertexArrays(1, &VAO);
- glDeleteBuffers(1, &VBO);
- glDeleteBuffers(1, &EBO);
-
- 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);
-
- if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
- std::cout << "up" << std::endl;
- mixValue += 0.001f;
- if (mixValue >= 1.0f) {
- mixValue = 1.0f;
- }
- }
-
- if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
- {
- std::cout << "down" << std::endl;
- mixValue -= 0.001f; // change this value accordingly (might be too slow or too fast based on system hardware)
- if (mixValue <= 0.0f)
- mixValue = 0.0f;
- }
- std::cout << "mixValue:" << mixValue <
- }
-
- // 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);
- }

6. 持续旋转
要让箱子随着时间推移旋转,我们必须在游戏循环中更新变换矩阵。也就是在while结构体中。
在这里我们先把箱子围绕原点(0, 0, 0)旋转,之后,我们把旋转过后的箱子位移到屏幕的右下角。
- //5. 循环渲染
- while (!glfwWindowShouldClose(window)) {
- processInput(window);
-
- // render
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- //绑定纹理
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureone);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texturetwo);
-
-
- ourShader.setFloat("mixValue", mixValue);
-
- glm::mat4 trans = glm::mat4(1.0f);
- trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
- trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
- unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
- glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
-
-
- ourShader.use();
- glBindVertexArray(VAO);
- glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
-
- glfwSwapBuffers(window);
- glfwPollEvents();
-
- }

7. 先平移后旋转And先旋转后平移
上面的例子是先平移后旋转,下面的代码是先旋转后平移
- //5. 循环渲染
- while (!glfwWindowShouldClose(window)) {
- processInput(window);
-
- // render
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- //绑定纹理
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureone);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texturetwo);
-
-
- ourShader.setFloat("mixValue", mixValue);
-
-
- glm::mat4 trans = glm::mat4(1.0f);
- //先平移后旋转
- //trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
- //trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
-
- //先旋转后平移
- 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));
-
-
- ourShader.use();
- glBindVertexArray(VAO);
- glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
-
- glfwSwapBuffers(window);
- glfwPollEvents();
-
- }

8. 绘制两个三角形,不同的显示方式
尝试再次调用glDrawElements画出第二个箱子,只使用变换将其摆放在不同的位置。让这个箱子被摆放在窗口的左上角,并且会不断的缩放(而不是旋转)。(sin函数在这里会很有用,不过注意使用sin函数时应用负值会导致物体被翻转)。
- //5. 循环渲染
- while (!glfwWindowShouldClose(window)) {
- processInput(window);
-
- // render
- glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
- //绑定纹理
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, textureone);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, texturetwo);
-
-
- ourShader.setFloat("mixValue", mixValue);
-
-
- glm::mat4 trans = glm::mat4(1.0f);
- //先平移后旋转
- //trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
- //trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
-
- //先旋转后平移
- 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));
-
-
- ourShader.use();
- glBindVertexArray(VAO);
- glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
-
-
- //second transformation
- trans = glm::mat4(1.0f);
- trans = glm::translate(trans, glm::vec3(-0.5f, 0.5f, 0.0f));
- float scaleAmount = static_cast<float>(sin(glfwGetTime()));
- trans = glm::scale(trans, glm::vec3(scaleAmount, scaleAmount, scaleAmount));
- glUniformMatrix4fv(transformLoc, 1, GL_FALSE, &trans[0][0]);// this time take the matrix value array's first element as its memory pointer value
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
-
-
- glfwSwapBuffers(window);
- glfwPollEvents();
-
- }
