opengl 坐标系

news2025/6/9 23:02:21

概述

    为了将坐标从一个坐标系统转换成另一个坐标,我们需要经历几个变换(1:模型 2:观察 3:投影)
    我们的顶点坐标起始于局部坐标,然后变成世界坐标,观察坐标,剪裁坐标 最后以屏幕坐标的形式结束

坐标系统

在这里插入图片描述

    将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分步进行的,也就是类似于流水线那样子。在流水线中,物体的顶点在最终转化为屏幕坐标之前还会被变换到多个坐标系统(Coordinate System)。将物体的坐标变换到几个过渡坐标系(Intermediate Coordinate System)的优点在于,在这些特定的坐标系统中,一些操作或运算更加方便和容易,这一点很快就会变得很明显。对我们来说比较重要的总共有5个不同的坐标系统:

    局部空间(Local Space,或者称为物体空间(Object Space))
    世界空间(World Space)                                           模型矩阵
    观察空间(View Space,或者称为视觉空间(Eye Space))                观察矩阵
    裁剪空间(Clip Space)                                            投影: 正投投影,透视投影
    屏幕空间(Screen Space)
    这就是一个顶点在最终被转化为片段之前需要经历的所有不同状态。

局部空间

    局部坐标是对象相对于局部原点的坐标,也是物体的起始坐标

世界空间坐标

    下一步骤是将局部空间转换成世界空间坐标,世界空间坐标是处于一个更大的空间范围的。这些坐标相对于世界的全局原点,它们会和其它物体一起相对于世界的原点进行摆放。
    从局部空间转换成世界空间 通过 (模型矩阵)

观察空间

    接下来我们将世界空间坐标变换成观察空间坐标,使的每个坐标都是从摄像机或者观察者的的角度观察的

    从世界空间转换成观察空间通过(视图矩阵)

剪裁空间

    坐标到达观察坐标后,我们需要将其投影到剪裁坐标,剪裁坐标会被处理至 -1-1的范围内并判断哪些顶点将会出现在屏幕上。

    将顶点坐标从查看空间转换成剪裁空间 通过(投影矩阵)

    投影矩阵: 分为两种:
            1: 正投影
            2: 透视投影(基本用透视投影)

投影坐标

    最后,我们将裁剪坐标变换为屏幕坐标,我们将使用一个叫做视口变换(Viewport Transform)的过程。视口变换将位于-1.0到1.0范围的坐标变换到由glViewport函数所定义的坐标范围内。最后变换出来的坐标将会送到光栅器,将其转化为片段

模型矩阵

    我们首先创建一个模型矩阵,这个模型矩阵包含了位移,缩放,与旋转操作,他们会被应用到所有物体的顶点上,以变换他们到全局的世界空间。
   
    作用: 使用模型矩阵 将局部空间转变成 世界空间

    glm::mat4 model;
    model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));

视图矩阵

    作用: 将世界空间转变成 观察空间
    glm::mat4 view;
    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

投影矩阵

    作用:将观察空间转换成 剪裁空间
    glm::mat4 projection;
    projection = glm::perspective(glm::radians(45.0f), screenWidth / screenHeight, 0.1f, 100.0f);

模型 与 顶点着色器关联

  • 三个模型 以制服的形式存在。并和顶点着色器相乘

      #version 330 core
      layout (location = 0) in vec3 aPos;
      ...
      uniform mat4 model;
      uniform mat4 view;
      uniform mat4 projection;
    
      void main()
      {
              // note that we read the multiplication from right to left
              gl_Position = projection * view * model * vec4(aPos, 1.0);
      ...
      }
    
  • 将模型 发送到着色器上(每一帧完成过后 就应该发送)

      发送方式:(其中一种)
              int modelLoc = glGetUniformLocation(ourShader.ID, "model");
              glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    

学习网站:
https://learnopengl.com/Getting-started/Coordinate-Systems
代码存储网址:
https://github.com/heisai/Learn-opengl/tree/master/opengl6

展示结果:

在这里插入图片描述

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

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

相关文章

BUUCTF-MD5强弱比较-MD5()的万能密码-tornado框架注入-中文电码

第六周 第三次 目录 学习到的知识 1.MD5强弱比较可以都可以使用数组绕过 2.基于MD5()的万能密码 ffifdyop WEB [BJDCTF2020]Easy MD5 ​编辑[护网杯 2018]easy_tornado Crypto 信息化时代的步伐 凯撒?替换?呵呵! Misc 神秘龙卷风 学习到的…

c/c++:数据类型,常量变量,标识符,有符号整型,无符号unsigned,字符类型,字符串类型,实数类型,浮点型,科学计数法

c/c:数据类型,常量变量,标识符,有符号整型,无符号unsigned,字符类型,字符串类型,实数类型,浮点型,科学计数法 2022找工作是学历、能力和运气的超强结合体&am…

C++ Primer 第7章 类 - 上(零基础学习C++,精简学习笔记)

🤖 作者简介:努力的clz ,一个努力编程的菜鸟 🐣🐤🐥 👀 文章专栏:C Primer 学习笔记 📔专栏简介: 本专栏是博主学习 C Primer 的学习笔记,因为…

【NX2023/1847】UG软件安装详细指南教程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录安装包一、安装包内容检查二、安装步骤1.安装JAVA_WIN64.exe2.运行Launch.exe3.安装许可3.直接重启电脑(小白直接重启稳妥)4.重启后继续运行L…

网络威胁情报项目:为什么仍然很疯狂

大约五年前,向首席信息安全官( CISO)询问他们的网络威胁情报 (CTI) 计划时,得到了两种截然不同的回答。 资源丰富的大型企业正在投资他们的威胁情报计划,目的是为了战术、运营和战略目的更好地实施它。 规模较小、资…

Day942.独立编译调试 -系统重构实战

独立编译调试 Hi,我是阿昌,今天学习记录的是关于独立编译调试的内容。 当组件做 独立的版本演进时,如果开发在本地每次修改代码时,都需要进行集成打包验证,反而会影响日常的开发效率。所以如果能够让组件独立进行编译…

Object方法

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版,配图更多,CSDN博文图片需要手动上传,因此文章配图较少,看不懂的可以去菜鸡博客参考一下配图! 系列文章目录 前端系列文章——传送门 JavaScript系列文章—…

Node.js -- 模块化

1.模块化的基本概念 模块化是指解决一个复杂问题时,自顶向下逐层吧系统划分成若干模块的过程。对于整个系统来说,模块是可组合,分解和更换的单元。 将代码进行模块化拆分的好处: 提高代码的复用性提高代码的可维护性可以实现按…

元宇宙:新的数字模式——元宇宙会场

一、引言 元宇宙是一个充满无限可能的虚拟空间,人们可以在其中创建和参与各种虚拟场景和体验。元宇宙技术的兴起,为传统的会场提供了一个新的方向。元宇宙会场将线下会场的物理空间转化为虚拟空间,通过数字技术和互联网实现了人们在虚拟环境…

我的第一台电脑的故事

第一台电脑啊,多么遥远的故事了,又似乎就在眼前。今天重回往事,就简单记录一下吧。 🌱缘起 那是初一,至今已13年,遂觉遥远,而又是立志我学习的起点,至今还在校园,又觉就…

断开连接图的 BFS

在上一篇文章中,仅对特定顶点执行 BFS,即假设所有顶点都可以从起始顶点到达。但是在断开连接的图或所有顶点都无法访问的任何顶点的情况下,之前的实现将不会给出所需的输出,因此在这篇文章中,在 BFS 中进行了修改。 所有顶点都是可达的。因此,对于上图,简单的BFS就可以…

【消息队列】细说Kafka消费者位移机制

什么是位移 位移说白了就是消费者消费对应的Topic的分区的消费位置,之前存储到ZK中,后来转移到Kafka默认的Topic中。结构是采用keyvalue形势存储的,key是groupIdtopic分区号,value是offset的值。 而上述的存储就在_consumer_offse…

微信小程序02

小程序tabBar 普通页面跳转到 带有tabBar页面的时候不能使用 wx.navigateTo() 小程序中跳转到选项卡页面使用 wx.switchTab()跳转 到底部 onReachBottom() 函数 ,, 在下拉刷新显示取消loading : wx.showNavigationBarLoading() wx.hideNavi…

深入讲解Linux内核中常用的数据结构和算法

Linux内核代码中广泛使用了数据结构和算法,其中最常用的两个是链表和红黑树。 链表 Linux内核代码大量使用了链表这种数据结构。链表是在解决数组不能动态扩展这个缺陷而产生的一种数据结构。链表所包含的元素可以动态创建并插入和删除。链表的每个元素都是离散存…

【网络原理】网络通信与协议

✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 目 录一. 网络发展史二. 网络通信基础1. IP地址2. 端口号3. 认识协议(核心概念)4. 五元组5. 协议分层6. 封装和分用一. 网络发展史 独立模式:计…

C++入门demo(从最简单的案例学习C++)

通过案例学习Cdemo01 在屏幕上输出内容demo02 规格不同的箱子(变量)demo03 物品存放(变量赋值)demo04 交换物品(变量之间交换数值)demo05 消失的重量(隐式类型变换)demo06 游泳池的容…

Melis4.0[D1s]:7.lvgl添加物理按键

文章目录1.lvgl注册keypad驱动1.1 在melis的ADC按键中发送消息1.1.1 创建消息队列,并初始化1.1.2 扫描按键时,发送按下和松开消息1.2 编写读取按键的回调函数1.3 lvgl按键驱动注册2.在gui中测试物理按键效果2.1 测试效果参考资料: 1.韦东山老…

第七章 基于 RNN 的生成文本

目录7.1 使用语言模型生成文本7.1.1 使用 RNN 生成文本的步骤7.1.2 文本生成的实现7.1.3 更好的文本生成7.2 seq2seq 模型7.2.1 seq2seq 的原理7.2.2 时序数据转换的简单尝试7.2.3 可变长度的时序数据7.2.4 加法数据集7.3 seq2seq 的实现7.3.1 Encoder类7.3.2 Decoder类7.3.3 S…

静态时序分析Static Timing Analysis3——特殊路径(多周期、半周期、伪路径)的时序检查

文章目录前言一、多周期路径1、建立时间检查2、保持时间检查二、半周期路径1、建立时间检查2、保持时间检查三、伪路径前言 2023.4.12 一、多周期路径 对于建立时间,要设置为N(向后移);对于保持时间,要设置为N-1&…

9.8.0.32:ProEssentials数据可视化2D和3D图表:Crack

下面是我们的Winforms、Wpf、C MFC、VCL、ActiveX图表组件示例项目中的屏幕捕获。 有关下图,请参见我们的示例项目和演示中的030。 ProEssentials Winforms 图表, WPF 图表, C/MFC/VCL 图表. Gigasoft拥有20多年帮助企业开发大型客户端和嵌入式图表项目的经验。图…