文章目录
- 环境
 - 代码
 
- CMakeLists.txt文件内容不变。
 - vertexShaderSource.vs
 - main.cpp
 
- 总结
 - 技术交流
 - 音视频领域其他技术文章的链接
 
- opengl相关文章
 - ffmpeg相关文章
 
- ffmpeg原理相关文章
 - ffmpeg源码分析相关文章
 - ffmpeg指令相关文章
 - ffmpeg报错相关文章
 
- libass相关文章
 - c/c++相关文章
 - linux相关文章
 
- 后面都是一些废话,不用看,刷分的
 
- 推广一个AI学习网站
 - 中国软件行业倡议书
 - 作者有话说
 - 关于内卷
 
 

环境
- 系统:ubuntu20.04
 - opengl版本:4.6
 - glfw版本:3.3
 - glad版本:4.6
 - cmake版本:3.16.3
 - gcc版本:10.3.0
 
在<opengl学习日记10-opengl使用多个纹理示例>的基础上,进行修改,实现变换效果。
代码
CMakeLists.txt文件内容不变。
vertexShaderSource.vs
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 transform;
void main()
{
        gl_Position = transform * vec4(aPos, 1.0f);
//        gl_Position = vec4(aPos, 1.0);
        TexCoord = vec2(aTexCoord.x,1.0 - aTexCoord.y);
}main.cpp
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "stbimage.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
#include <fstream>
#include <iosfwd>
#include <sstream>
#include <string>
//定义窗口大小
int SCR_WIDTH = 800;
int SCR_HEIGHT = 600;
std::string readFile(const std::string filename)
{
    std::string data;
    data = readFile(filename.c_str());
    return data;
}
std::string readFile(const char* filename)
{
    std::string data;
    std::ifstream infile;
    infile.open(filename);
    std::stringstream neirong;
    neirong << infile.rdbuf();
    infile.close();
    data = neirong.str();
    return data;
}
int main()
{
    std::cout << "Hello World!" << std::endl;
    std::cout << "初始化" << std::endl;
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "transformtions", NULL, NULL);
    if (window == NULL) {
        std::cout << "创建窗口失败" << std::endl;
        return -1;
    }
    glfwMakeContextCurrent(window);
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cout << "初始化glad失败" << std::endl;
        return -1;
    }
    std::cout << "顶点定义,VAO,VBO,EBO" << std::endl;
    float vertices[] = {
        0.5f, 0.5f, 0.0f,  1.0f, 1.0f,
        0.5f, -0.5f, 0.0f,  1.0f, 0.0f,
        -0.5f, -0.5f, 0.0f,  0.0f, 0.0f,
        -0.5f, 0.5f, 0.0f,  0.0f, 1.0f };
    //索引缓冲区
    unsigned int indices[] = { 0, 1, 3,
        1, 2, 3 };
    unsigned int VAO, VBO, 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);
    //定位点关系
    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);
    std::cout << "着色器定义" << std::endl;
    std::cout << "着色器定义:顶点着色器" << std::endl;
    std::string vertexShaderSource = readFile("vertexShaderSource.vs");
    const char* vertexShaderSourceCtr = vertexShaderSource.c_str();
    unsigned int vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSourceCtr, NULL);
    glCompileShader(vertexShader);
    int success;
    char infolog[512] = { 0 };
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(vertexShader, 512, NULL, infolog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
                  << infolog << std::endl;
    }
    std::cout << "着色器定义:片段着色器" << std::endl;
    std::string fragmentShaderSource = readFile("fragmentShaderSource.fs");
    const char* fragmentShaderSourceCtr = fragmentShaderSource.c_str();
    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSourceCtr, NULL);
    glCompileShader(fragmentShader);
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success) {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infolog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
                  << infolog << std::endl;
    }
    std::cout << "着色器定义:启用着色器程序" << std::endl;
    unsigned int shaderProgram;
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infolog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
                  << infolog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    std::cout << "纹理定义" << std::endl;
    unsigned int texture1;
    glGenTextures(1, &texture1);
    glBindTexture(GL_TEXTURE_2D, texture1);
    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);
    stbi_set_flip_vertically_on_load(true);
    std::cout << "读取纹理图片" << std::endl;
    int width, height, nrChannels;
    unsigned char* texturesData = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
    if (texturesData) {
        //绑定和纹理图片数据结合
        glTexImage2D(GL_TEXTURE_2D,
            0,
            GL_RGB,
            width,
            height,
            0,
            GL_RGB,
            GL_UNSIGNED_BYTE,
            texturesData);
        glGenerateMipmap(GL_TEXTURE_2D);
    } else {
        std::cout << "读取图片数据错误" << std::endl;
    }
    stbi_image_free(texturesData);
    std::cout << "纹理定义2" << std::endl;
    unsigned int texture2;
    glGenTextures(1, &texture2);
    glBindTexture(GL_TEXTURE_2D, texture2);
    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);
    std::cout << "读取纹理图片" << std::endl;
    //        int width, height, nrChannels;
    texturesData = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
    if (texturesData) {
        //绑定和纹理图片数据结合
        glTexImage2D(GL_TEXTURE_2D,
            0,
            GL_RGB,
            width,
            height,
            0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            texturesData);
        glGenerateMipmap(GL_TEXTURE_2D);
    } else {
        std::cout << "读取图片数据错误" << std::endl;
    }
    stbi_image_free(texturesData);
    glUseProgram(shaderProgram);
    glUniform1i(glGetUniformLocation((GLuint)shaderProgram, "texture1"), 0);
    glUniform1i(glGetUniformLocation((GLuint)shaderProgram, "texture2"), 1);
//    glm::mat4 trans = glm::mat4(1.0f);
//    trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
//    trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
    std::cout << "绘制" << std::endl;
    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture2);
        glUseProgram(shaderProgram);
        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(shaderProgram, "transform");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (const GLvoid *) 0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    std::cout << "内存释放" << std::endl;
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteBuffers(1, &EBO);
    glDeleteProgram(shaderProgram);
    glfwTerminate();
    return 0;
}总结
- 对于矩阵变换效果,如果静态变换效果,例如旋转30度,可以将矩阵变换数据放置在绘制流程之外(while外面),如果是动态变换效果,例如连续旋转,则需要将矩阵变换数据放置在绘制流程内(while内)
 
静态效果
glm::mat4 trans = glm::mat4(1.0f);
    trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
    trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
    std::cout << "绘制" << std::endl;
    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture2);
        glUseProgram(shaderProgram);
//        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(shaderProgram, "transform");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (const GLvoid *) 0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }动态效果
//    glm::mat4 trans = glm::mat4(1.0f);
//    trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
//    trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
    std::cout << "绘制" << std::endl;
    while (!glfwWindowShouldClose(window)) {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture1);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, texture2);
        glUseProgram(shaderProgram);
        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(shaderProgram, "transform");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (const GLvoid *) 0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }- 做效果变换一般是改变顶点着色器的内容,顶点变换了,效果才会跟着变,所以绑定的全局shader变量是顶点着色器内的
 
unsigned int transformLoc = glGetUniformLocation(shaderProgram, "transform");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));- 定义
glm::mat4时,需要使用glm::mat4 trans = glm::mat4(1.0f);的方式,在官网教程中示例使用glm::mat4 trans;有误,会导致图像不显示 
中国软件行业倡议书
精简软件开发,电脑性能越来越好,打出的程序安装包越来越大,磁盘,内存越吃越多,这不是好现象,手机同理,大家觉得呢,欢迎发表看法,各抒己见。
手机app随意读取用户通讯录,就是流氓行为,即使有时候弹窗提示是否授权,选择了否,但是他其实还是悄悄读取你的通讯录,并且随便给你的通讯录好友发推广信息,这一点是非常反感的,并且也触犯了用户的权益,这不仅是流氓行为,更是违法行为,某软件就不说了。
作者有话说
个人简介:多年工作工程经验,擅长linux下软件开发,qt,ffmpeg音视频二次开发。
欢迎各位叨扰作者,如果有什么项目合作,创业合伙需要研发,网站推广,猎头服务,内推等等,尽管来联系,对于能挣钱的事,作者可是很感兴趣的哦。
关于内卷
劝大家一句,不要内卷,内卷只能害了别人,害了自己。

                









