OpenGL笔记十四之GLM数学库的配置与使用

OpenGL笔记十四之GLM数学库的配置与使用

—— 2024-07-20 中午

bilibili赵新政老师的教程看后笔记

code review!

文章目录

  • OpenGL笔记十四之GLM数学库的配置与使用
    • 1.旋转变换运行效果
    • 2.平移变换运行效果
    • 3.缩放变换运行效果
    • 4.复合变换:先旋转 再平移运行效果
    • 5.复合变换:先平移 后旋转运行效果
    • 6.每一帧都旋转运行效果
    • 7.关键代码
      • 7.1.vs
      • 7.2.fs
      • 7.3.main.cpp关键片段
      • 7.4.shader.h关键片段
      • 7.5.shader.cpp关键片段
      • 7.6.core.h中要把代码包含进来

把GLM文件夹拷贝thirdParty/include文件夹下

1.旋转变换运行效果

在这里插入图片描述

2.平移变换运行效果

在这里插入图片描述

3.缩放变换运行效果

在这里插入图片描述

4.复合变换:先旋转 再平移运行效果

在这里插入图片描述

5.复合变换:先平移 后旋转运行效果

在这里插入图片描述

6.每一帧都旋转运行效果

注意:每一帧都是从起始位姿旋转而至
在这里插入图片描述

7.关键代码

7.1.vs

在这里插入图片描述

代码

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aUV;out vec3 color;
out vec2 uv;uniform mat4 transform;//aPos作为attribute(属性)传入shader
//不允许更改的
void main()
{vec4 position = vec4(aPos, 1.0);position = transform * position;gl_Position = position;color = aColor;uv = aUV;
}

7.2.fs

在这里插入图片描述

代码

#version 330 core
out vec4 FragColor;in vec3 color;
in vec2 uv;uniform sampler2D sampler;void main()
{FragColor = texture(sampler, uv);
}

7.3.main.cpp关键片段

在这里插入图片描述

在这里插入图片描述

main.cpp完整代码

#include <iostream>#include "glframework/core.h"
#include "glframework/shader.h"
#include <string>
#include <assert.h>//断言
#include "wrapper/checkError.h"
#include "application/Application.h"
#include "glframework/texture.h"/*
*┌────────────────────────────────────────────────┐
*│ 目	   标: 初步学习GLM库的平移/旋转/缩放
*│ 讲    师: 赵新政(Carma Zhao)
*│ 拆分目标:
*					-1 引入GLM的头文件
*					-2 更改vertexShader,加入uniform变量mat4 transform
*					-3 使用传入的transform给我们的顶点坐标进行变换
*					-4 为shader类增加uniform矩阵传输的功能
*					-5 使用矩阵做复合变换
*					-6 连续转动三角形(动画)
*└────────────────────────────────────────────────┘
*/GLuint vao;
Shader* shader = nullptr;
Texture* texture = nullptr;
glm::mat4 transform(1.0f);void OnResize(int width, int height) {GL_CALL(glViewport(0, 0, width, height));std::cout << "OnResize" << std::endl;
}void OnKey(int key, int action, int mods) {std::cout << key << std::endl;
}void doRotationTransform() {//构建一个旋转矩阵,绕着z轴旋转45度角//rotate函数:用于生成旋转矩阵//bug1:rotate必须得到一个float类型的角度,c++的template//bug2:rotate函数接受的不是角度(degree),接收的弧度(radians)//注意点:radians函数也是模板函数,切记要传入float类型数据,加f后缀transform = glm::rotate(glm::mat4(1.0f),glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
}//平移变换
void doTranslationTransform() {transform = glm::translate(glm::mat4(1.0f), glm::vec3(0.5f, 0.0f, 0.0f));
}//缩放变换
void doScaleTransform() {transform = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f, 0.5f, 1.0f));
}//复合变换
void doTransform() {glm::mat4 rotateMat = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));glm::mat4 translateMat = glm::translate(glm::mat4(1.0f), glm::vec3(0.5f, 0.0f, 0.0f));//先旋转 再平移// transform = translateMat * rotateMat;//先平移 后旋转transform = rotateMat * translateMat;
}float angle = 0.0f;
void doRotation() {angle += 2.0f;//每一帧都会“重新”构建一个旋转矩阵transform = glm::rotate(glm::mat4(1.0f), glm::radians(angle), glm::vec3(0.0, 0.0, 1.0));
}void prepareVAO() {//1 准备positions colorsfloat positions[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f,  0.5f, 0.0f,};float colors[] = {1.0f, 0.0f,0.0f,0.0f, 1.0f,0.0f,0.0f, 0.0f,1.0f,};float uvs[] = {0.0f, 0.0f,1.0f, 0.0f,0.5f, 1.0f,};unsigned int indices[] = {0, 1, 2,};//2 VBO创建GLuint posVbo, colorVbo, uvVbo;glGenBuffers(1, &posVbo);glBindBuffer(GL_ARRAY_BUFFER, posVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);glGenBuffers(1, &colorVbo);glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);glGenBuffers(1, &uvVbo);glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glBufferData(GL_ARRAY_BUFFER, sizeof(uvs), uvs, GL_STATIC_DRAW);//3 EBO创建GLuint ebo;glGenBuffers(1, &ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);//4 VAO创建glGenVertexArrays(1, &vao);glBindVertexArray(vao);//5 绑定vbo ebo 加入属性描述信息//5.1 加入位置属性描述信息glBindBuffer(GL_ARRAY_BUFFER, posVbo);glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);//5.2 加入颜色属性描述数据glBindBuffer(GL_ARRAY_BUFFER, colorVbo);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0);//5.3 加入uv属性描述数据glBindBuffer(GL_ARRAY_BUFFER, uvVbo);glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (void*)0);//5.4 加入ebo到当前的vaoglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBindVertexArray(0);
}void prepareShader() {shader = new Shader("assets/shaders/vertex.glsl","assets/shaders/fragment.glsl");
}void prepareTexture() {texture = new Texture("assets/textures/goku.jpg", 0);
}void render() {//执行opengl画布清理操作GL_CALL(glClear(GL_COLOR_BUFFER_BIT));//绑定当前的programshader->begin();shader->setInt("sampler", 0);shader->setMatrix4x4("transform", transform);//绑定当前的vaoGL_CALL(glBindVertexArray(vao));//发出绘制指令GL_CALL(glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0));GL_CALL(glBindVertexArray(0));shader->end();
}int main() {if (!app->init(800, 600)) {return -1;}app->setResizeCallback(OnResize);app->setKeyBoardCallback(OnKey);//设置opengl视口以及清理颜色GL_CALL(glViewport(0, 0, 800, 600));GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));prepareShader();prepareVAO();prepareTexture();// doRotationTransform();// doTranslationTransform();// doScaleTransform();doTransform();while (app->update()) {// doRotation();render();}app->destroy();return 0;
}

7.4.shader.h关键片段

void setMatrix4x4(const std::string& name, glm::mat4 value);

shader.h完整代码

#pragma once#include "core.h"
#include<string>class Shader {
public:Shader(const char* vertexPath, const char* fragmentPath);~Shader();void begin();//开始使用当前Shadervoid end();//结束使用当前Shadervoid setFloat(const std::string& name, float value);void setVector3(const std::string& name, float x, float y, float z);void setVector3(const std::string& name, const float* values);void setInt(const std::string& name, int value);void setMatrix4x4(const std::string& name, glm::mat4 value);
private://shader program//type:COMPILE LINKvoid checkShaderErrors(GLuint target,std::string type);private:GLuint mProgram{ 0 };
};

7.5.shader.cpp关键片段

void Shader::setMatrix4x4(const std::string& name, glm::mat4 value) {//1 通过名称拿到Uniform变量的位置LocationGLint location = GL_CALL(glGetUniformLocation(mProgram, name.c_str()));//2 通过Location更新Uniform变量的值//transpose参数:表示是否对传输进去的矩阵数据进行转置glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value));
}

shader.cpp完整代码

#include"shader.h"
#include"../wrapper/checkError.h"#include<string>
#include<fstream>
#include<sstream>
#include<iostream>Shader::Shader(const char* vertexPath, const char* fragmentPath) {//声明装入shader代码字符串的两个stringstd::string vertexCode;std::string fragmentCode;//声明用于读取vs跟fs文件的inFileStreamstd::ifstream vShaderFile;std::ifstream fShaderFile;//保证ifstream遇到问题的时候可以抛出异常vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);try {//1 打开文件vShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);//2 将文件输入流当中的字符串输入到stringStream里面std::stringstream vShaderStream, fShaderStream;vShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();//3 关闭文件vShaderFile.close();fShaderFile.close();//4 将字符串从stringStream当中读取出来,转化到code String当中vertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (std::ifstream::failure& e) {std::cout << "ERROR: Shader File Error: " << e.what() << std::endl;}const char* vertexShaderSource = vertexCode.c_str();const char* fragmentShaderSource = fragmentCode.c_str();//1 创建Shader程序(vs、fs)GLuint vertex, fragment;vertex = glCreateShader(GL_VERTEX_SHADER);fragment = glCreateShader(GL_FRAGMENT_SHADER);//2 为shader程序输入shader代码glShaderSource(vertex, 1, &vertexShaderSource, NULL);glShaderSource(fragment, 1, &fragmentShaderSource, NULL);//3 执行shader代码编译 glCompileShader(vertex);//检查vertex编译结果checkShaderErrors(vertex, "COMPILE");glCompileShader(fragment);//检查fragment编译结果checkShaderErrors(fragment, "COMPILE");//4 创建一个Program壳子mProgram = glCreateProgram();//6 将vs与fs编译好的结果放到program这个壳子里glAttachShader(mProgram, vertex);glAttachShader(mProgram, fragment);//7 执行program的链接操作,形成最终可执行shader程序glLinkProgram(mProgram);//检查链接错误checkShaderErrors(mProgram, "LINK");//清理glDeleteShader(vertex);glDeleteShader(fragment);
}
Shader::~Shader() {}void Shader::begin() {GL_CALL(glUseProgram(mProgram));
}void Shader::end() {GL_CALL(glUseProgram(0));
}void Shader::setFloat(const std::string& name, float value) {//1 通过名称拿到Uniform变量的位置LocationGLint location = GL_CALL(glGetUniformLocation(mProgram, name.c_str()));//2 通过Location更新Uniform变量的值GL_CALL(glUniform1f(location, value));
}void Shader::setVector3(const std::string& name, float x, float y, float z) {//1 通过名称拿到Uniform变量的位置LocationGLint location = GL_CALL(glGetUniformLocation(mProgram, name.c_str()));//2 通过Location更新Uniform变量的值GL_CALL(glUniform3f(location, x, y, z));
}//重载 overload
void Shader::setVector3(const std::string& name, const float* values) {//1 通过名称拿到Uniform变量的位置LocationGLint location = GL_CALL(glGetUniformLocation(mProgram, name.c_str()));//2 通过Location更新Uniform变量的值//第二个参数:你当前要更新的uniform变量如果是数组,数组里面包括多少个向量vec3GL_CALL(glUniform3fv(location, 1, values));
}void Shader::setInt(const std::string& name, int value) {//1 通过名称拿到Uniform变量的位置LocationGLint location = GL_CALL(glGetUniformLocation(mProgram, name.c_str()));//2 通过Location更新Uniform变量的值glUniform1i(location, value);
}void Shader::setMatrix4x4(const std::string& name, glm::mat4 value) {//1 通过名称拿到Uniform变量的位置LocationGLint location = GL_CALL(glGetUniformLocation(mProgram, name.c_str()));//2 通过Location更新Uniform变量的值//transpose参数:表示是否对传输进去的矩阵数据进行转置glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value));
}void Shader::checkShaderErrors(GLuint target, std::string type) {int success = 0;char infoLog[1024];if (type == "COMPILE") {glGetShaderiv(target, GL_COMPILE_STATUS, &success);if (!success) {glGetShaderInfoLog(target, 1024, NULL, infoLog);std::cout << "Error: SHADER COMPILE ERROR" << "\n" << infoLog << std::endl;}}else if (type == "LINK") {glGetProgramiv(target, GL_LINK_STATUS, &success);if (!success) {glGetProgramInfoLog(target, 1024, NULL, infoLog);std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl;}}else {std::cout << "Error: Check shader errors Type is wrong" << std::endl;}
}

7.6.core.h中要把代码包含进来

core.h

#pragma once//注意:glad头文件必须在glfw引用之前引用
#include <glad/glad.h>
#include <GLFW/glfw3.h>//GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>

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

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

相关文章

OpenTeleVision复现及机器人迁移

相关信息 标题 Open-TeleVision: Teleoperation with Immersive Active Visual Feedback作者 Xuxin Cheng1 Jialong Li1 Shiqi Yang1 Ge Yang2 Xiaolong Wang1 UC San Diego1 MIT2主页 https://robot-tv.github.io/链接 https://robot-tv.github.io/resources/television.pdf代…

八股文之java基础

jdk9中对字符串进行了一个什么优化&#xff1f; jdk9之前 字符串的拼接通常都是使用进行拼接 但是的实现我们是基于stringbuilder进行的 这个过程通常比较低效 包含了创建stringbuilder对象 通过append方法去将stringbuilder对象进行拼接 最后使用tostring方法去转换成最终的…

独立开发者系列(31)——fastadmin项目的二次开发

在前面构建项目的fastadmin入门 里面&#xff0c;我们已经能快速搭建该体系和根据数据表建立最简单的CURD项目。类似练手的图书管理系统&#xff0c;内部项目修改管理&#xff0c;也对系统进行了简单的部署。这梳理拿到真正项目的开发流程。 默认的开发目录和代码程序运行的是p…

【Linux系统化学习】数据链路层

目录 数据链路层解决的问题 以太网 认识局域网 以太网帧格式 两个问题 认识MAC地址 认识MTU ARP协议 ARP协议的作用 ARP数据报格式 ARP协议的工作流程 数据链路层解决的问题 对于TCP/IP四层协议来说&#xff0c;数据链路层才是真正从传送数据进行跑腿办事情的&…

excel批量新建多个同类型的表格

背景引入 比如&#xff0c;一个企业有多个部门&#xff0c;现在需要按照某一个excel表模板收集各个部门的信息&#xff0c;需要创建数十个同类型表格&#xff0c;且标题要包含部门名称。 1.修改模板表格标题 在一个文件夹下面放入需要发放给各个部门的表格&#xff0c;将标题…

微软蓝屏事件暴露的网络安全问题

目录 1.概述 2.软件更新流程中的风险管理和质量控制机制 2.1.测试流程 2.2.风险管理策略 2.3.质量控制措施 2.4.小结 3.预防类似大规模故障的最佳方案或应急响应对策 3.1. 设计冗余系统 3.2. 实施灾难恢复计划 3.3. 建立高可用架构 3.4. 类似规模的紧急故障下的响应…

Kotlin泛型实化

内联函数 reified实现 1. 内联函数 内联函数中的代码会在编译的时候自动被替换到调用它的地方&#xff0c;这样的话也就不存在什么泛型擦除的问题了&#xff0c;因为代码在编译之后会直接使用实际的类型来替代内联函数中的泛型声明。 2. reified关键字 在Kotlin中&#xff0…

秒杀优化: 记录一次bug排查

现象 做一人一单的时候&#xff0c;为了提升性能&#xff0c;需要将原来的业务改造成Lua脚本加Stream流的方式实现异步秒杀。 代码改造完成&#xff0c;使用Jmeter进行并发测试&#xff0c;发现redis中的数据和预期相同&#xff0c;库存减1&#xff0c;该用户也成功添加了进去…

【Node】npm i --legacy-peer-deps,解决依赖冲突问题

文章目录 &#x1f356; 前言&#x1f3b6; 一、问题描述✨二、代码展示&#x1f3c0;三、运行结果&#x1f3c6;四、知识点提示 &#x1f356; 前言 npm i --legacy-peer-deps&#xff0c;解决依赖冲突问题 &#x1f3b6; 一、问题描述 node执行安装指令时出现报错&#xff…

ES中的数据类型学习之ALIAS

Alias field type | Elasticsearch Guide [7.17] | Elastic 这里只针对data type的alias&#xff0c;暂时不说 index的alias。直接实战开始 PUT trips { "mappings": { "properties": { "distance": { "type": &…

Linux、Windows和macOS上使用Telnet

文章目录 LinuxWindowsmacOS 在Linux、Windows和macOS上使用Telnet时&#xff0c;不同的系统有不同的工具和设置方法。以下是在这些系统上使用Telnet的简要说明&#xff1a; Linux 在Linux上&#xff0c;Telnet通常是通过telnet命令来使用的。首先&#xff0c;你需要确保你的系…

前端:Vue学习-3

前端&#xff1a;Vue学习-3 1. 自定义指令2. 插槽2.1 插槽 - 后备内容&#xff08;默认值&#xff09;2.2 插槽 - 具名插槽2.3 插槽 - 作用域插槽 3. Vue - 路由3.1 路由模块封装3.2 声明式导航 router-link 高亮3.3 自定义匹配的类名3.4 声明式导肮 - 跳转传参3.5 Vue路由 - 重…

[题解]CF1401E.Divide Square(codeforces 05)

题目描述 There is a square of size 106106106106 on the coordinate plane with four points (0,0)(0,0) , (0,106)(0,106) , (106,0)(106,0) , and (106,106)(106,106) as its vertices. You are going to draw segments on the plane. All segments are either horizonta…

【数据结构】顺序表(ArrayList的具体使用)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;欢迎大佬指点&#xff01; 欢迎志同道合的朋友一起加油喔 &#x1f4aa;&#x1f4aa;&#x1f4aa; 谢谢你这么帅…

VSCode STM32嵌入式开发插件记录

要卸载之前搭建的VSCode嵌入式开发环境了&#xff0c;记录一下用的插件。 1.Cortex-Debug https://github.com/Marus/cortex-debug 2.Embedded IDE https://github.com/github0null/eide 3.Keil uVision Assistant https://github.com/jacksonjim/keil-assistant/ 4.RTO…

政安晨【零基础玩转各类开源AI项目】基于Ubuntu系统部署MimicMotion :利用可信度感知姿势指导生成高质量人体运动视频

目录 项目介绍 项目相关工作 图像/视频生成的扩散模型 姿势引导的人体动作转移 生成长视频 方法实践 与最先进方法的比较 消融研究 部署验证 1. 下载项目&#xff1a; 2. 建立环境 3. 下载参数模型 A. 下载 DWPose 预训练模型&#xff1a;dwpose B. 从 Huggingfa…

DDD(3)-领域驱动设计之如何建模

前言 上一篇&#xff1a;从领域驱动到模型驱动中我们讨论到&#xff0c;领域驱动设计的核心思想是保持业务-模型-代码的一致性&#xff0c;模型作为沟通业务和代码的工具&#xff0c;至关重要&#xff0c;今天这篇文章就来讨论DDD中建模的一些思考和方法。 什么是建模 虽然看…

基于SSM的高考志愿选择辅助系统

基于SSM的高考志愿选择辅助系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台 前台首页 院校展示 后台 后台首页 学校管理 摘要 随着高考制度的不断完…

【Drone】drone编译web端 防墙策略 | 如何在被墙的状态drone顺利编译npm

一、drone编译防墙版本 1、web端drone kind: pipeline type: docker name: ui steps:- name: build_projectimage: node:20-slim depends_on: [clone]volumes:- name: node_modulespath: /drone/src/node_modulescommands:- pwd- du -sh *- npm config set registry https://…

测试——Selenium

内容大纲: 什么是自动化测试 什么是Selenium Selenium工作原理 Selenium环境搭建 Selenium API 目录 1. 什么是自动化测试 2. 什么是Selenium 3. Selenium工作原理 4. Selenium环境搭建(java) 5. Selenium API 5.1 定位元素 5.1.1 CSS选择器定位元素 5.1.2 XPath定位元…