OpenGL中顶点经过顶点着色器后会变为标准设备坐标系。标准设备坐标系的各坐标的取值范围是[-1,1],超过这个范围的点将会被剔除。而这个变换的过程可描述为顶点在几个坐标系统的变换,这几个坐标系统为:

    模型空间(Local Sapce)

    世界空间(world Space)

    观察空间(View Space)

    裁切空间(Clip Space)

    屏幕空间(Projection Space)

  OpenGL的顶点变换为标准设备坐标系的点就是按:模型空间->世界空间->观察空间->裁切空间->屏幕空间 顺序进行变化的。为什么要分这么多个阶段的变化?这个主要是为了方便适应不同的变换需求,比如在进行物体移动的时候,使用世界坐标系会比较的方便。那这些坐标空间到底是什么了?我们接下来一个一个解释。

  模型空间

  表示模型最初所在的空间,即当时构建这个模型时的坐标空间。比如上一节中绘制三角形时所给的三个顶点的坐标就时模型坐标系下的坐标位置,每一个x,y,z的取值范围都是[-1,1]。

  世界空间

  想象一下,我们构造模型的时候通常是一个一个的构建的,每个模型都是相对模型坐标系的(0,0,0)点进行的建模,这个时候如果我们把这些模型都放在一起,可以想象它们将叠在一起,这个当然不是我们想要的,这个时候就需要另一个坐标系来描述它们的方位关系了。比如场景中有一个人和一辆车,它们在构建时都在(0,0,0)点,现在我们在这个基础上把人放在(-2,0,0)的位置,把车放在(10,0,0)的位置,而这两个坐标就是世界空间中的坐标。所以世界坐标系描述的时所有三维模型的相对关系。

  观察空间

  观察空间可以这么理解:在世界空间摆放好我们的模型之后,我们需要找一个位置和角度来观察它们,我们观察到的画面即我们要渲染的画面,而以我们眼睛为基点构建的空间即为观察空间。观察空间是把世界空间的点转换为视线前方的点的而产生的结果。它通常由一些平移和旋转矩阵组合成。

  裁切空间

  我们人眼的观察范围是有限的,计算机模拟人眼视野,所以OpenGL渲染的顶点应该都在一个视野范围内,这个视野范围即我们所谓的裁切空间,超出这个范围的点就被裁切掉。裁切空间定义在标准设备坐标系上的,坐标的取值范围是(-1,1),但我们观察空间中的顶点是三维的,如果要把三维的顶点映射为二维的点,我们需要定义一个投影矩阵把观察空间的点映射到裁切空间。投影就是将三维物体投射到二维平面的过程,投影可分为正投影和透视投影。

正投影

  正投影比较简单,他的平截头体是一个长方体,在这个长方体内的顶点可见,其它点则剔除。这个长方体可以由left,right,bottom,top,near,far这几个参数确定,其中near和far表示近平面和远平面。投影可以看作是把三维画面投影在近平面,可以想象,因为远平面和近平面一样大,所以投影对于物体的大小没有影响,可以推断:在着色器使用齐次坐标,顶点着色器透视除法所使用的w为1,即(x/w,y/w,z/w,1),w=1。

透视投影

  在实际生活中常见的现象是离我们越远的物体越小,越近的物体越大。这个效果就是透视,最直观的现象即使两条平行线在远处会相交,如铁路上的铁轨。要实现这种透视的效果我们需要一个梯状的平截头体,这个平截头体的参数定义可同正投影使用6个参数,也可使用指定fov的方式定义。与正投影相比,透视投影的远平面更大,这样越远的物体投影到近平面时就越小,即w是一个与z相关的值。

具体的投影矩阵推导可参见:

http://blog.csdn.net/wangdingqiaoit/article/details/51589825

  屏幕空间

  屏幕空间可理解为显示器屏幕上定义的坐标空间,有两种定义,一种是以左上角为(0,0)点,右下角为(width,height),其中width和height是屏幕的宽和高;一种是左下角为(0,0)点,右上角为(width,height)。

  MVP

  把顶点从模型空间变换到裁切空间,我们需要经过:模型空间->世界空间->观察空间->裁切空间的3个变换阶段,这3个变换可用3个矩阵表示,分别是模型矩阵、观察矩阵和投影矩阵,把这3个变化矩阵组合到一起即为模型空间到裁切空间的矩阵变换:

   

的发达第

Linux OpenGL 实践篇-4 坐标系统的更多相关文章

  1. Linux OpenGL 实践篇-6 光照

    经典光照模型 经典光照模型通过单独计算光源成分得到综合光照效果,然后添加到物体表面特定点,这些成分包括:环境光.漫反射光.镜面光. 环境光:是指不是来特定方向的光,在经典光照模型中基本是个常量. 漫反 ...

  2. Linux OpenGL 实践篇-5 纹理

    纹理 在之前的实践中,我们所渲染的物体的表面颜色都是纯色或者根据顶点位置计算出的一个颜色,这种方式在表现物体细节方面是比较吃资源的,因为我们每增加一个细节,我们就需要定义更多的顶点及其属性.所以美术人 ...

  3. Linux OpenGL 实践篇-3 绘制三角形

    本次实践是绘制两个三角形,重点理解顶点数组对象和OpenGL缓存的使用. 顶点数组对象 顶点数组对象负责管理一组顶点属性,顶点属性包括位置.法线.纹理坐标等. OpenGL缓存 OpenGL缓存实质上 ...

  4. Linux OpenGL 实践篇-2 创建一个窗口

    OpenGL 作为一个图形接口,并没有包含窗口的相关内容,但OpenGL使用必须依赖窗口,即必须在窗口中绘制.这就要求我们必须了解一种窗口系统,但不同的操作系统提供的创建窗口的API都不相同,如果我们 ...

  5. Linux OpenGL 实践篇-1 OpenGL环境搭建

    本次实践所使用环境为CentOS 7. 参考:http://www.xuebuyuan.com/1472808.html OpenGL开发环境搭建: 1.opengl库安装 opengl库使用mesa ...

  6. Linux OpenGL 实践篇-16 文本绘制

    文本绘制 本文主要射击Freetype的入门理解和在OpenGL中实现文字的渲染. freetype freetype的官网,本文大部分内容参考https://www.freetype.org/fre ...

  7. Linux OpenGL 实践篇-15-图像数据操作

    OpenGL图像数据操作 之前的实践中,我们在着色器中的输入输出都是比较固定的.比如在顶点或片元着色器中,顶点属性的输入和帧缓存的颜色值:虽然我们可以通过纹理或者纹理缓存对象(TBO)来读取任意的内存 ...

  8. Linux OpenGL 实践篇-14-多实例渲染

    多实例渲染 OpenGL的多实例渲染是一种连续执行多条相同的渲染命令的方法,并且每条命令产生的结果都有轻微的差异,通常用于渲染大量的几何物体. 设想一个场景,比如太空,我们需要渲染数以万记的星球,如果 ...

  9. Linux OpenGL 实践篇-13-geometryshader

    几何着色器 几何着色器是位于图元装配和片元着色器之前的一个着色器阶段,是一个可选阶段.它的输入是一个图元的完整的顶点信息,通常来自于顶点着色器,但如果细分计算着色器启用的话,那输入则是细分计算着色器的 ...

随机推荐

  1. Redis的安装和部署

    基本知识 1.Redis的数据类型: 字符串.列表(lists).集合(sets).有序集合(sorts sets).哈希表(hashs) 2.Redis和memcache相比的独特之处: (1)re ...

  2. Algorithm --> 树中求顶点A和B共同祖先

    树中求顶点A和B共同祖先 题目: 给定一颗树,以及两个顶点A和B,求最近的共同祖先,和包含的子顶点个数? 比如:给定如下图的树,以及顶点13和8,则共同祖先为3,以3为root的子顶点共有8个

  3. [poj-2985]The k-th Largest Group_Treap+并查集

    The k-th Largest Group poj-2985 题目大意:给你n只猫,有两种操作:1.将两只猫所在的小组合并.2.查询小组数第k大的小组的猫数. 注释:1<=n,m<=20 ...

  4. 利用CSS3制作网页动画

    如何在网页中实现动画效果动态图片 flashjavascriptcss3变形是一些效果的集合如平移 旋转 缩放 倾斜效果每个效果都可以称为变形(transfrom) 它们可以分别操控元素发生平移.旋转 ...

  5. 使用cocopod管理第三方

    扭捏了两年多一直不愿意使用cocopod来管理第三方,一直感觉直接拖拽第三方就挺方便的,直到今天使用第三方库WebViewJavascriptBridge,拖拽一直有问题,不得已研究.使用了cocop ...

  6. Git详细教程(2)---多人协作开发

    Git可以完成两件事情: 1. 版本控制 2.多人协作开发 如今的项目,规模越来越大,功能越来越多,需要有一个团队进行开发. 如果有多个开发人员共同开发一个项目,如何进行协作的呢. Git提供了一个非 ...

  7. 2018.3.28html学习笔记

    <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">      ...

  8. Beta冲刺第二天

    一.昨天的困难 没困难 二.今天进度 局部测试并修复出现的bug 1.林洋洋:修复登录页面显示问题,修复日程查询问题 2.黄腾达:修复创建协作开始时间和结束时间没做检验的问题 3.张合胜:修复页面内容 ...

  9. 20162321王彪-实验二-Java面向对象程序设计

    实验二Java面向对象程序设计 实验内容一 初步掌握单元测试和TDD 什么是单元测试:单元测试时开发者编写的一小段代码,用于检测被测代码的一个很小的,很明确的功能是否正确.执行单元测试,是为了证明某段 ...

  10. C语言--第14.15周作业

    一. 7-3 将数组中的数逆序存放 1.代码 #include 2<stdio.h> int main() { int a[10]; int i, n, s; scanf("%d ...