计算机图形学 | 实验六:旋转立方体

news/2024/5/11 5:02:14/文章来源:https://blog.csdn.net/ProgramNovice/article/details/130582294

计算机图形学 | 实验六:旋转立方体

  • 计算机图形学 | 实验六:旋转立方体
    • Z-缓冲
    • GLM函数库
    • PVM矩阵
    • PVM矩阵的使用

华中科技大学《计算机图形学》课程

MOOC地址:计算机图形学(HUST)

计算机图形学 | 实验六:旋转立方体

在正式搭建环境之前,我们先来介绍一下读完下面的部分你会了解些什么。

  • 绘制出旋转立方体需要的新知识
  • 认识一些 OpenGL的新功能

接下来,我们来介绍一下绘制旋转立方体。绘制效果如下:

在这里插入图片描述

Z-缓冲

Z-缓存(Z-Buffer):这是一项处理 3D物体深度信息的技术,它对不同物体和同一物体不同部分的当前 Z坐标进行纪录,也就是在 3D环境中,每个像素会利用一组数据资料来定义像素在显示时的纵深度(即 Z轴坐标值)。在进行着色时,对那些在其他物体背后的结构进行消隐,使它们不被显示出来。

在 OpenGL 中,坐标映射到屏幕屏幕空间后,其 z值即最终 z-缓冲的值,只需记录每个屏幕像素点的 z 值,并与当前绘制的片元的 z值进行比对,即可判断物体是否遮挡或被遮挡。实际应用中,我们只需要开启深度测试即可。

glEnable(GL_DEPTH_TEST);

GLM函数库

GLM是 OpenGL Mathematics的缩写,它是一个只有头文件的库,也就是说我们只需包含对应的头文件就行了,不用链接和编译。GLM可以在它们的网站上下载。把头文件的根目录复制到你的 includes文件夹,就可以使用这个库了。使用这个库,好处就在于我们只需要输入特定参数,就可以生成我们需要的矩阵。

PVM矩阵

PVM矩阵即 P:projection;V:view;M:model。其中,model矩阵对应从局部坐标系到世界坐标系的变换,模型矩阵是一种转换矩阵,它能通过对对象进行平移、缩放、旋转来将它置于它本应该在的位置或方向。

view矩阵对应从世界坐标系到观察坐标系的变换,观察坐标系就是从摄像机的角度观察到的坐标系。而这通常是由一系列的平移和旋转的组合来平移和旋转场景从而使得特定的对象被转换到摄像机前面。

projection 矩阵对应从观察坐标系到剪裁空间的变换,它指定了坐标的范围,例如,每个维度都是从-1000到 1000。投影矩阵接着会将在它指定的范围内的坐标转换到标准化设备坐标系中(-1.0,1.0)。所有在在范围(-1.0,1.0)外的坐标都不会被绘制出来并且会被裁剪。由投影矩阵创建的观察区域被称为平截头体,且每个出现在平截头体范围内的坐标都会最终出现在用户的屏幕上。将一定范围内的坐标转化到标准化设备坐标系的过程(而且它很容易被映射到 2D观察空间坐标)被称之为投影,因为使用投影矩阵能将 3维坐标投影到很容易映射的2D标准化设备坐标系中。

一旦所有顶点被转换到裁剪空间,最终的操作——透视划分将会执行,在这个过程中我们将位置向量的 x,y,z分量分别除以向量的齐次 w分量;透视划分是将 4维裁剪空间坐标转换为 3维标准化设备坐标。这一步会在每一个顶点着色器运行的最后被自动执行。 在这一阶段之后,坐标经过转换的结果将会被映射到屏幕空间(由glViewport设置)且被转换成片段。

PVM矩阵的使用

那么如何在实践中使用 pvm矩阵呢,首先我们需要引入 GLM函数库的头文件,我们所需要用到的功能都在这三个头文件中。

#include <glm/glm.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp>

然后我们需要设置 view矩阵的相关参数。

glm::vec3 camera_position = glm::vec3(0.0f, 0.0f, 3.0f); // 摄像机位置
=glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f); // 摄像机方向 
glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f); // 摄像机上向量

然后我们需要设置 projection矩阵的视野 fov:

float fov = 45.0f;

进入主循环之后我们先计算 model矩阵,首先我们需要创建一个 model矩阵,然后 glm:translate函数是进行平移变换的矩阵,将物体平移(0.0,0.0,0.0)位置,然后进行旋转,第二个参数为旋转的角度,第三个参数为旋转轴。最后进行缩放 glm::vec3变量的三个值分别代表 x,y,z方向的缩放比例。

glm::mat4 model(1);//model矩阵,局部坐标变换至世界坐标 
model = glm::translate(model, glm::vec3(0.0,0.0,0.0)); 
model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f)); 
model = glm::scale(model, glm::vec3(1.0f,1.0f,1.0f));

为了得到我们需要的 view矩阵,我们需要先创建一个 mat4 view矩阵,通过 glm中的 rotate函数去计算,第一个是相机的位置,第二个参数是相机所正对的目标的坐标,这里使用 camera_position+camera_front(相机的方向),进行向量的加法之后可以获得相机正对的坐标,第三个参数是相机的上向量。

glm::mat4 view(1);//view矩阵,世界坐标变换至观察坐标系 
view = glm::lookAt(camera_position, camera_position + camera_front, camera_up);

在 GLM中可以这样创建一个透视投影矩阵,它的第一个参数定义了 fov的值,它表示的是视野,并且设置了观察空间的大小。对于一个真实的观察效果,它的值经常设置为 45.0,但想要看到更多结果你可以设置一个更大的值。第二个参数设置了宽高比,由视口的高除以宽。第三和第四个参数设置了平截头体的近和远平面。我们经常设置近距离为 0.1而远距离设为 100.0。所有在近平面和远平面的顶点且处于平截头体内的顶点都会被渲染。

glm::mat4 projection(1);//projection矩阵,投影矩阵 
projection = glm::perspective(glm::radians(fov), (float)screen_width / screen_height, 0.1f, 100.0f);

我们之前的操作都只是得到 model,view和 projection矩阵,但是不能忘记将这三个矩阵传入到着色器,否则着色器是没有办法使用的。

glGetUniformLocation 可以获得某个着色器中参数的位置,第一个参数为着色器 id,第二个参数为该参数的名称。

int model_location = glGetUniformLocation(shader.ID, "model");
// 获取着色器内某个参数的位置

glUniformMatrix4fv是向指定位置传入一个 4X4的矩阵值。通过这两个函数我们将 pvm矩阵传入着色器中。

glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));// 写入参数值

最后,在着色器中,对于矩阵的乘法,由于不符合乘法交换律,所以我们应当注意相乘顺序。

gl_Position = projection * view * model * vec4(aPos, 1.0);

整个绘制旋转立方体的程序的新知识点介绍就到此为止,效果如下:

在这里插入图片描述

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

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

相关文章

单词词义、词性、例句查询python代码

单词发音、词义、词性、例句查询、输出结果更简洁&#xff0c;一次可查多个单词 运行该代码&#xff0c;命令窗口输入单词&#xff0c;单词用“/”分开&#xff0c;例如&#xff1a;noisy/problem/community/neighbor 可以更多。先安装两个python包requests、 beautifulsoup4&…

卖一辆亏5.8万美元!福特的困扰

随着电动化进入关键的「抢量」周期&#xff0c;加上年初掀起的降价潮&#xff0c;对于还无法适应转型节奏的传统汽车制造商来说&#xff0c;现在是一个艰难的时刻。 本月初&#xff0c;福特首席执行官Jim Farley表示&#xff0c;电动汽车市场的降价是"令人担忧的趋势"…

2023/5/8总结

JAVA基础知识&#xff08;2&#xff09; 1.方法 1、方法定义 格式&#xff1a;public static void 方法名&#xff08;&#xff09;{ //方法体 } 2、方法调用 格式&#xff1a;方法名&#xff08;&#xff09;&#xff1b; 3、方法的通用格式 public static 返回值类型方法名&…

车载测试-can报文解析规则实例

报文解析 报文组成 一般报文主要有以下几个参数&#xff08;比较全的情况下&#xff09; 例 解析报文时主要用到的是帧ID和帧数据 帧ID 接收到的帧ID是十六进制的形式&#xff0c;由29位标识符转换的&#xff0c;目前大多数的通信协议中都直接给出了相应的帧ID&#xff0c…

mathtype不激活能用吗 mathtype产品密钥如何取得

在文档中输入数学式子时一般会用到mathtype&#xff0c;虽然mathtype为广大用户提供了一定期限的试用期&#xff0c;但试用期后如果没有成为正式用户&#xff0c;那么部分功能可能就用不了了。有些小伙伴可能会对mathtype不激活能用吗&#xff0c;mathtype产品密钥如何取得这两…

kt:reified和sam转换(Single Abstract Method Conversions)

什么是refied关键字 ​由于我们都知道Kotlin和Java一样都存在着泛型擦除问题&#xff0c;而Kotlin它知道Java所带来的这个问题&#xff0c;所以对此Kotlin留了一个后门&#xff0c;就是通过inline函数保证使得泛型类的类型实参在运行时能够保留&#xff0c;这样的操作 Kotlin 中…

git简介和使用、基础命令

文章目录 一、git的安装与配置二、Git工作区原理三、Git的使用和仓库的创建四、Git的常用操作五、配置公钥六、IDEA中配置Git 一、git的安装与配置 https://tortoisegit.org/ 下载对应版本安装即可 注意&#xff1a;配置中输入邮箱和密码一定要和自己的git账户一致 git的配置…

copilot 逆向

原文&#xff1a; copilot-explorer | Hacky repo to see what the Copilot extension sends to the server 对我来说&#xff0c;Github Copilot 极其有用。它经常能神奇地读懂我的想法并给出有用的建议。最让我惊讶的是&#xff0c;它能够从周围的代码中正确地“猜测”出函数…

设计模式 -- 备忘录模式

前言 月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂) 央是一片海洋,海乃百川,代表着一块海绵(吸纳万物) 泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出) 月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容 希望大家一起坚持这个过程,也同…

电脑cpu占用率高?怎么办?1分钟快速解决!

案例&#xff1a;电脑cup过高怎么办&#xff1f; 【我的电脑运行缓慢&#xff0c;导致我学习和工作的效率很低。刚刚查看了一下电脑&#xff0c;发现它的cpu占用率很高。有没有小伙伴知道如何解决此电脑cpu过高的问题&#xff1f;】 电脑是我们生活中不可缺少的工具&#xff…

1— .Net MVC之控制器

在上下文中使用的控制器 问题 答案 什么是控制器&#xff1f; 控制器包含用于接收请求、更新应用程序状态或模型以及选择将发送给客户端的响应的逻辑 控制器有什么用&#xff1f; 控制器是MVC项目的核心&#xff0c;并包含Web应用程序的逻辑 如何使用控制器&#xff1f; …

接口自动化测试神器:Python+Requests+Unittest让你的测试用例飞起来

B站首推&#xff01;2023最详细自动化测试合集&#xff0c;小白皆可掌握&#xff0c;让测试变得简单、快捷、可靠 随着互联网的发展&#xff0c;越来越多的应用程序采用了分布式架构&#xff0c;并通过API接口进行数据交换。因此&#xff0c;接口自动化测试已经成为了保证软件质…

过滤器对前端请求参数进行解码URLDecoder,接口接收参数类型为map,解码无效问题

文章目录 一、前言二、设计思路三、代码实现四、启动测试五、过滤器解码无效六、源码跟踪七、解决方案八、再次重启测试九、总结 一、前言 最近做的一个公司项目&#xff0c;因为客户需要对特殊字符做搜索&#xff0c;但是前端的请求参数无法传递到后端&#xff0c;所以前端对…

光耦继电器和普通继电器的区别概述

光耦继电器和普通继电器都是电气传感器元件中的一种&#xff0c;其都能够将电能转化成机械能&#xff0c;并实现各种开关控制和保护控制。但光耦继电器与普通继电器最大的区别在于其输入电路与输出电路之间通过光电转换器件&#xff0c;而不是实现物理接触。本文将从结构、工作…

Spring MVC——Rest风格

REST&#xff08;Representational State Transfer&#xff09; 当我们想表示一个网络资源的时候&#xff0c;可以使用两种方式: 我们分别用查询id为1的用户信息与保存用户信息举例传统风格资源描述形式 http://localhost/user/getById?id1http://localhost/user/saveUser RES…

记一次azkaban调度异常处理

一、背景 预发布环境使用的数据库性能比较低&#xff0c;根据业务测试的需求&#xff0c;需要将数据库更换成 稳定高性能的数据库。更换业务数据库后azkaban定时任务失败 二、数据库服务信息 说明&#xff1a;该部分使用代号来代替&#xff0c;非真实信息 该数据库存储了azka…

linux彻底卸载mysql步骤

第一步&#xff0c;先查看是否安装了mysql mysql -u root -p 如果提示bash: mysql: command not found...则没有安装过mysql 如果提示需要输入密码&#xff0c;那就证明安装了mysql 第二步&#xff0c;查看mysql运行状态并关闭 先查看下mysql的运行状态&#xff08;如果已经…

电脑缺少msvcp140.dll怎么办,缺少msvcp140一键修复方法

电脑缺少msvcp140.dll怎么办&#xff1f;这个问题相信不少小伙伴都遇到过&#xff0c;msvcp140.dll文件是很多软件跟游戏运行必须用到的文件&#xff0c;如果丢失或者损坏&#xff0c;很多软件都会无法打开运行。其实知道知道方法&#xff0c;修复起来其实也不会很难&#xff0…

OAK相机如何将 YOLO NAS 模型转换成blob格式?

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手…

k8s pv pvc的使用

k8s pv pvc的使用 安装nfs服务器 yum install rpcbind nfs-utils -y systemctl enable rpcbind systemctl enable nfs systemctl start rpcbind systemctl start nfsmkdir -p /root/data/sc-data [rootmaster sc-data]# cat /etc/exports /root/data/sc-data 192.168.1.0/24(…