opengl日记11-opengl的transformtions变换示例

文章目录

  • 环境
  • 代码
    • CMakeLists.txt文件内容不变。
    • vertexShaderSource.vs
    • main.cpp
  • 总结
  • 参考

在这里插入图片描述

环境

  • 系统: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;
}

总结

  1. 对于矩阵变换效果,如果静态变换效果,例如旋转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();}
  1. 做效果变换一般是改变顶点着色器的内容,顶点变换了,效果才会跟着变,所以绑定的全局shader变量是顶点着色器内的
        unsigned int transformLoc = glGetUniformLocation(shaderProgram, "transform");glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));
  1. 定义glm::mat4时,需要使用glm::mat4 trans = glm::mat4(1.0f);的方式,在官网教程中示例使用glm::mat4 trans;有误,会导致图像不显示

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/760215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电子资金转账系统的分类、应用及其对银行业的影响

科技的飞速发展&#xff0c;计算机网络技术已广泛应用于各个领域&#xff0c;其中之一就是电子资金转账&#xff08;Electronic Funds Transfer&#xff0c;简称EFT&#xff09;系统。EFT系统作为金融业务电子化的重要实现手段&#xff0c;正逐步改变着传统银行业务的运作方式&…

Blender 3D建模要点

3d模型可以为场景的仿真模拟带来真实感&#xff0c;它还有助于更轻松地识别场景中的所有内容。 例如&#xff0c;如果场景中的所有对象都是简单的形状&#xff0c;如立方体和圆形&#xff0c;则很难在仿真中区分对象。 1、碰撞形状与视觉形状 像立方体和球体这样的简单形状&a…

开发指南015-前端缓存的信息

平台前端架构启动后&#xff0c;在store里存储了很多信息&#xff0c;可以通过getter取到&#xff1a; 1)访问token import { getToken } from /utils/qlm_auth getToken()可以获取该值 为空则没有登录 2) 用户信息 this.$store.getters.userId // 用户ID this.$sto…

大厂面试-- [VueReact] 对虚拟DOM的理解?虚拟DOM主要做了什么?虚拟DOM本身是什么?

什么是虚拟DOM ​ 从本质上讲&#xff0c;Virtual Dom是一个Javascript对象&#xff0c;通过对象的方式来表示DOM结构。将页面的状态抽象为JS对象的形式&#xff0c;配合不同的渲染工具&#xff0c;将使跨平台渲染成为可能。通过事物处理机制&#xff0c;将多次DOM修改的结果一…

鸿蒙Harmony应用开发—ArkTS-属性动画

组件的某些通用属性变化时&#xff0c;可以通过属性动画实现渐变过渡效果&#xff0c;提升用户体验。支持的属性包括width、height、backgroundColor、opacity、scale、rotate、translate等。布局类改变宽高的动画&#xff0c;内容都是直接到终点状态&#xff0c;例如文字、can…

Linux 标准IO介绍

一、Linux文件的种类 常规文件r目录文件d字符设备文件c块设备文件b管道文件p套接字文件s符号链接文件(相当于Windows快捷方式&#xff09;l 二、标准I/O 1、概念 I&#xff1a;input 输入设备 比如键盘鼠标都是Input设备 O&#xff1a;output 输出设备 比如显示器 优…

英国政府发布云SCADA(数据采集与监控系统)安全指南

近期&#xff0c;英国国家网络安全中心 (NCSC) 发布了安全指南&#xff0c;用以帮助使用运营技术 (OT) 的组织确定是否应将其监控和数据采集 (SCADA) 系统迁移到云端。 出于安全原因&#xff0c;SCADA 系统传统上与互联网甚至本地企业网络隔离&#xff0c;但云可以提供许多好处…

在家有电脑手机怎么赚钱?整理了六种在家做副业的方法

如果你在家空闲时间比较多&#xff0c;有电脑有手机&#xff0c;一定要做的六种副业&#xff01; 无论你现在是什么身份&#xff0c;如果能够利用自己的空余时间&#xff0c;去做一份副业&#xff0c;那么你的自信心会得到大大地提升&#xff01; 分享六种我觉得很值得尝试的副…

JDBC基础(CRUD)使用详解(mysql)

1. 什么是JDBC JDBC,即Java Database Connectivity,java数据库连接.是一种用于执行SQL语句的Java API,它是 Java中的数据库连接规范.这个API由 java.sql.*,javax.sql.* 包中的一些类和接口组成,它为Java 开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访…

Docker安装部署RabbitMQ(单机版)

文章目录 1.1.下载镜像1.2.安装MQ 本篇文章探讨的是单机部署 环境:Centos7 1.1.下载镜像 方式一&#xff1a;在线拉取 docker pull rabbitmq:3.8-management方式二&#xff1a;从本地加载 【1】将该镜像包上传到虚拟机的tmp目录 【2】上传到虚拟机中后&#xff0c;切换到存…

词令直达微信二维码如何生成关键词口令?

什么是词令直达微信二维码&#xff1f; 词令直达微信二维码是指商家生成指定的词令关键词口令后&#xff0c;可将商家的个人微信、企业微信、微信群、微信公众号、微信小程序等二维码关联到已生成的词令。用户使用词令微信小程序关键词口令直达工具&#xff0c;输入商家的词令…

MySQL表的增删改查---多表查询和联合查询

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

Python 数据分析模块pandas 如何创建DataFrame

以下用两种方式分别创建DataFrame。 import pandas as pd#原始数据存储在列表中 names [Alice,Deric,Amanda,Petter] ages [34,24,33,35] incomes [50000,65000,46000,69000]# 使用字典创建 DataFrame data {names:names,ages:ages,incomes:incomes} df1 pd.DataFrame(da…

冰岛人[天梯赛]

文章目录 题目描述思路AC代码 题目描述 输入样例 15 chris smithm adam smithm bob adamsson jack chrissson bill chrissson mike jacksson steve billsson tim mikesson april mikesdottir eric stevesson tracy timsdottir james ericsson patrick jacksson robin patrickss…

IDEA启动提示Downloading pre-built shared indexes

提示内容&#xff1a; Download pre-built shared indexes Reduce the indexing time and CPU load with pre-built JDK shared indexes Always download Download once Dontt show again Configure... "Download pre-built shared index" 是IDEA中的一个功能选…

ORA-600 2662快速恢复之Patch scn工具---惜分飞

有客户数据库启动报ORA-600 2662错误 SQL> recover database; 完成介质恢复。 SQL> alter database open ; alter database open * 第 1 行出现错误: ORA-00603: ORACLE server session terminated by fatal error ORA-00600: internal error code, arguments: [2662], […

AI如何支持慈善组织

为各种有意义的事业提供支持&#xff0c;无论是努力寻找治愈疾病的方法、研发使生活更轻松的技术&#xff0c;还是为有需要的人提供服务&#xff0c;都是无比崇高的使命。提供捐款或是投入时间支持的捐助者和志愿者往往对他们选择支持的事业的目标、服务和资源分配存有诸多疑虑…

Linux系统如何使用tcpdump实时监控网络速度:方法与技巧解析

在网络管理和故障排查中&#xff0c;了解网络速度是一个重要的环节。而tcpdump&#xff0c;作为一个强大的网络数据包分析工具&#xff0c;不仅可以用于分析数据包的内容&#xff0c;还能用于实时监控网络速度。本文将介绍Linux系统如何使用tcpdump来实时监控网络速度。 首先&…

工大智信智能听诊智慧医疗的创新

智能听诊器&#xff0c;智慧医疗的新突破 工大智信智能听诊器是一款结合了先进技术和医疗专业知识的创新产品。它以其独特的优势&#xff0c;为医疗行业带来了前所未有的突破和变革。 传统听诊器依赖于医生的主观判断和经验&#xff0c;而工大智信智能听诊器采用了先进的传感技…

CV论文--2024.3.21

1、Chain-of-Spot: Interactive Reasoning Improves Large Vision-Language Models 中文标题&#xff1a;Chain-of-Spot&#xff1a;交互式推理改进大型视觉语言模型 简介&#xff1a;在视觉语言理解领域&#xff0c;模型在解释和推理视觉内容方面的熟练程度已经成为许多应用的…