【OpenGL学习】(八)图形变换

OpenGL图形变换介绍:https://learnopengl-cn.github.io/01%20Getting%20started/07%20Transformations

【OpenGL学习】(八)图形变换


本项目将通过变换矩阵,对【OpenGL学习】(七)纹理单元 中的图形进行缩放,旋转和平移。

项目链接: https://github.com/BinaryAI-1024/OpenGLPorjects/tree/master/transformations

顶点着色器transform.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.0); // 坐标变换TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

片段着色器transform.fs:

#version 330 core
out vec4 FragColor;in vec3 ourColor;
in vec2 TexCoord;// texture samplers
uniform sampler2D texSampler1;
uniform sampler2D texSampler2;void main()
{// 在两个纹理之间进行线性插值 (80% container, 20% awesomeface)FragColor = mix(texture(texSampler1, TexCoord), texture(texSampler2, TexCoord), 0.2);
}

transfomations.cpp

#define STB_IMAGE_IMPLEMENTATION
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stb_image.h>#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>#include <filesystem.h>
#include <shader_s.h>#include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;int main()
{// 初始化GLFW并配置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); // Mac OS X需要前向兼容
#endif// 创建窗口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(加载OpenGL函数指针)if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){std::cout << "Failed to initialize GLAD" << std::endl;return -1;}// 编译着色器程序Shader ourShader("transform.vs", "transform.fs");// 顶点数据和缓冲区设置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 VBO, VAO, EBO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);// 绑定VAOglBindVertexArray(VAO);// 绑定VBO并传输顶点数据glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 绑定EBO并传输索引数据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 texture1, texture2;// 纹理1 - 容器纹理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);// 加载图像数据int width, height, nrChannels;stbi_set_flip_vertically_on_load(true); // 翻转y轴unsigned char* data = stbi_load(FileSystem::getPath("resources/container.jpg").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);// 纹理2 - 笑脸纹理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);// 加载图像数据(注意这是PNG有透明通道)data = stbi_load(FileSystem::getPath("resources/awesomeface.png").c_str(), &width, &height, &nrChannels, 0);if (data){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);// 设置着色器中的采样器对应的纹理单元ourShader.use();ourShader.setInt("texSampler1", 0); // 纹理单元0ourShader.setInt("texSampler2", 1); // 纹理单元1// 渲染循环while (!glfwWindowShouldClose(window)){// 输入处理processInput(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);// ========== 矩阵变换部分 ==========// 1. 创建变换矩阵(初始化为单位矩阵)glm::mat4 transform = glm::mat4(1.0f);// 2. 应用平移变换(向右0.5单位,向下0.5单位)transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));// 3. 应用旋转变换(绕z轴旋转,旋转角度基于当前时间)// glfwGetTime()返回程序运行时间(秒)transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));// 4. 图形每个轴都缩放为0.5倍transform = glm::scale(transform, glm::vec3(0.5, 0.5, 0.5));// 矩阵变换的执行顺序是反向的:// 实际效果是:物体先缩小,再旋转,最后平移// 使用着色器程序并设置变换矩阵uniformourShader.use();unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");// 将矩阵传输给着色器glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));// 渲染四边形glBindVertexArray(VAO);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);// 交换缓冲区并查询IO事件glfwSwapBuffers(window);glfwPollEvents();}// 清理资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);// 终止GLFWglfwTerminate();return 0;
}void processInput(GLFWwindow* window)
{if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)glfwSetWindowShouldClose(window, true);
}void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height); 
}

运行结果:

在这里插入图片描述

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

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

相关文章

从理论到实战:解密大型语言模型的核心技术与应用指南

一、Transformer&#xff1a;语言理解与生成的基石 Transformer 架构的出现&#xff0c;彻底改变了自然语言处理&#xff08;NLP&#xff09;的格局。它以“注意力”为核心&#xff0c;将全局依赖的捕捉效率推向新高。下面用 图简要概览其数据流&#xff1a; 从上图可见&#…

kali换源

在Kali Linux中切换软件源可以提高软件下载速度&#xff0c;下面为你介绍切换源的方法。 一、备份原配置文件 首先备份原配置文件&#xff0c;避免操作失误导致问题&#xff1a; sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak二、编辑源配置文件 使用以下命令编…

从决策树到随机森林:Python机器学习里的“树形家族“深度实战与原理拆解

引言 在机器学习的算法森林中&#xff0c;有一对"树形兄弟"始终占据着C位——决策树像个逻辑清晰的"老教授"&#xff0c;用可视化的树状结构把复杂决策过程拆解成"是/否"的简单判断&#xff1b;而它的进阶版随机森林更像一支"精英军团&quo…

uniapp,每次请求时,中断上次请求

1.封装uni.request import {BASE_URL} from "/config/config.js"import store from "/store/index.js"; class RequestManager {constructor() {this.requestTasks new Map() // 存储所有请求任务this.baseURL BASE_URLthis.header {Content-Type: app…

DuDuTalk | 武汉赛思云科技有限公司通过武汉市人工智能企业认定!

近日&#xff0c;2025年武汉市人工智能企业名单正式公布&#xff01;武汉赛思云科技有限公司&#xff08;以下简称赛思云科技&#xff09;凭借卓越的技术实力与创新成果&#xff0c;成功入选武汉市人工智能企业。这是对公司长期深耕AI语音智能领域、推动数字化转型的高度认可&a…

STM32实现傅里叶变换精确计算采样电流值

以下是基于离散傅里叶变换(DFT)算法在单片机上实现精确电流值计算的全流程指南,结合硬件选型、算法优化、代码实现及实际应用场景分析,综合多篇技术文档的实践要点: ⚙️ 一、系统设计核心要点 硬件选型与配置 单片机选择:优先采用带硬件浮点单元(FPU)的STM32F4/F7系列…

python 爬虫 下载视频

测试 OK II 在开发者工具里面 直接搜索m3u8 可以直接找相对应连接地址继续分析 这个m3u8 url地址是从哪里过来的 在什么地方有 III 我们想要视频数据 <m3u8连接> 在 网页源代码里面有获取整个视频内容 --》分为N个视频片段《ts文件》-->在m3u8连接里面--> 视频播放…

希尔伯特空间:无穷维度的几何世界

希尔伯特空间&#xff1a;无穷维度的几何世界 从量子物理到信号处理&#xff0c;希尔伯特空间为现代科学与工程提供了强大的数学框架 引言&#xff1a;无限维度的舞台 在数学和物理学的广阔领域中&#xff0c;希尔伯特空间扮演着至关重要的角色。这个完备的内积空间不仅推广了…

Transformer结构与代码实现详解

参考&#xff1a; Transformer模型详解&#xff08;图解最完整版&#xff09; - 知乎https://zhuanlan.zhihu.com/p/338817680GitHub - liaoyanqing666/transformer_pytorch: 完整的原版transformer程序&#xff0c;complete origin transformer programhttps://github.com/lia…

Adobe InDesign 2025

Adobe InDesign 2025(ID2025)桌面出版软件和在线发布工具,报刊杂志印刷排版设计软件。Adobe InDesign中文版主要用于传单设计,海报设计,明信片设计,电子书设计,排版,手册设计,数字杂志,iPad应用程序和在线交互文档。它是首款支持Unicode文本处理的主流DTP应用程序,率先使用新型…

Linux下获取指定时间内某个进程的平均CPU使用率

一、引言 通过pidstat工具可以测量某个进程在两个时间点之间的平均CPU利用率。 二、pidstat工具的安装 pidstat属于sysstat套件的一部分。以Ubuntu系统为例&#xff0c;执行下面命令下载安装sysstat套件&#xff1a; apt-get install sysstat 执行完后&#xff0c;终端执行p…

1.4 蜂鸟E203处理器NICE接口详解

一、NICE接口的概念 NICE&#xff08;Nuclei Instruction Co-unit Extension&#xff09;接口是蜂鸟E203处理器中用于扩展自定义指令的协处理器接口&#xff0c;基于RISC-V标准协处理器扩展机制设计。它允许用户在不修改处理器核流水线的情况下&#xff0c;通过外部硬件加速特…

Oracle 递归 + Decode + 分组函数实现复杂树形统计进阶(第二课)

在上篇文章基础上&#xff0c;我们进一步解决层级数据递归汇总问题 —— 让上级部门的统计结果自动包含所有下级部门数据&#xff08;含多级子部门&#xff09;&#xff0c;并新增请假天数大于 3 天的统计维度。通过递归 CTE、DECODE函数与分组函数的深度结合&#xff0c;实现真…

MySQL 数据类型全面指南:详细说明与关键注意事项

MySQL 数据类型全面指南&#xff1a;详细说明与关键注意事项 MySQL 提供了丰富的数据类型&#xff0c;合理选择对数据库性能、存储效率和数据准确性至关重要。以下是所有数据类型的详细说明及使用注意事项&#xff1a; 一、数值类型 整数类型 类型字节有符号范围无符号范围说…

leetcode437-路径总和III

leetcode 437 思路 利用前缀和hash map解答 前缀和在这里的含义是&#xff1a;从根节点到当前节点的路径上所有节点值的总和 我们使用一个 Map 数据结构来记录这些前缀和及其出现的次数 具体思路如下&#xff1a; 初始化&#xff1a;创建一个 Map &#xff0c;并将前缀和 …

UI前端与数字孪生融合探索新领域:智慧家居的可视化设计与实现

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 一、引言&#xff1a;智慧家居的数字化转型浪潮 在物联网与人工智能技术的推动下&#xff0c…

数据结构知识点总结--绪论

1.1 数据结构的基本概念 1.1.1 基本概念和术语 主要涉及概念有&#xff1a; 数据、数据元素、数据对象、数据类型、数据结构 #mermaid-svg-uyyvX6J6ofC9rFSB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-uyyvX6…

pip install mathutils 安装 Blender 的 mathutils 模块时,编译失败了

你遇到的问题是因为你试图通过 pip install mathutils 安装 Blender 的 mathutils 模块时&#xff0c;编译失败了&#xff0c;主要原因是&#xff1a; 2018年 的老版本也不行 pip install mathutils2.79 ❌ 报错核心总结&#xff1a; 缺失头文件 BLI_path_util.h&#xff1a;…

编译安装交叉工具链 riscv-gnu-toolchain

参考链接&#xff1a; https://zhuanlan.zhihu.com/p/258394849 1&#xff0c;下载源码 git clone https://gitee.com/mirrors/riscv-gnu-toolchain 2&#xff0c;进入目录 cd riscv-gnu-toolchain 3&#xff0c;去掉qemu git rm qemu 4&#xff0c;初始化 git submodule…

复制 生成二维码

一、安装插件 1、复制 npm install -g copy-to-clipboard import copy from copy-to-clipboard; 2、生成二维码 & 下载 npm install -g qrcode import QRCode from qrcode.react; 二、功能&#xff1a;生成二维码 & 下载 效果图 1、常规使用&#xff08;下载图片模糊…