一: 首先就是关于几个坐标系统的概括:

  1. 局部坐标是对象相对于局部原点的坐标,也是物体起始的坐标。
  2. 下一步是将局部坐标变换为世界空间坐标,世界空间坐标是处于一个更大的空间范围的。这些坐标相对于世界的全局原点,它们会和其它物体一起相对于世界的原点进行摆放。
  3. 接下来我们将世界坐标变换为观察空间坐标,使得每个坐标都是从摄像机或者说观察者的角度进行观察的。
  4. 坐标到达观察空间之后,我们需要将其投影到裁剪坐标。裁剪坐标会被处理至-1.0到1.0的范围内,并判断哪些顶点将会出现在屏幕上。
  5. 最后,我们将裁剪坐标变换为屏幕坐标,我们将使用一个叫做视口变换(Viewport Transform)的过程。
  6. 视口变换将位于-1.0到1.0范围的坐标变换到由glViewport函数所定义的坐标范围内。(坐标原点在左下角)
  7. 最后变换出来的坐标将会送到光栅器,将其转化为片段。随后送入片段着色器。

二: 再推荐一个很好理解的教程:opengl-tutorials

三:五个空间

  1. 局部空间:局部空间是指物体所在的坐标空间,即对象最开始所在的地方。有可能你创建的所有模型都以(0, 0, 0)为初始位置(译注:然而它们会最终出现在世界的不同位置)。所以,你的模型的所有顶点都是在局部空间中:它们相对于你的物体来说都是局部的。
  2. 世界空间:如果我们将我们所有的物体导入到程序当中,它们有可能会全挤在世界的原点(0, 0, 0)上,这并不是我们想要的结果。我们想为每一个物体定义一个位置,从而能在更大的世界当中放置它们。
  3. 观察空间:观察空间经常被人们称之OpenGL的摄像机(Camera)(所以有时也称为摄像机空间(Camera Space)或视觉空间(Eye Space))。观察空间是将世界空间坐标转化为用户视野前方的坐标而产生的结果。因此观察空间就是从摄像机的视角所观察到的空间。而这通常是由一系列的位移和旋转的组合来完成,平移/旋转场景从而使得特定的对象被变换到摄像机的前方。
  4. 裁剪空间:在一个顶点着色器运行的最后,OpenGL期望所有的坐标都能落在一个特定的范围内,且任何在这个范围之外的点都应该被裁剪掉(Clipped)。被裁剪掉的坐标就会被忽略,所以剩下的坐标就将变为屏幕上可见的片段。

四:三个矩阵

  1. 模型矩阵:是一种变换矩阵,它能通过对物体进行位移、缩放、旋转来将它置于它本应该在的位置或朝向。我们将物体局部坐标变换到场景/世界中的不同位置。
  2. 观察矩阵:它被用来将世界坐标变换到观察空间。

    2.1 将摄像机向后移动,和将整个场景向前移动是一样的。

    2.2 我们以相反于摄像机移动的方向移动整个场景。因为我们想要往后移动,并且OpenGL是一个右手坐标系(Right-handed System),所以我们需要沿着z轴的正方向移动。我们会通过将场景沿着z轴负方向平移来实现。它会给我们一种我们在往后移动的感觉。
  3. 投影矩阵:它指定了一个范围的坐标,比如在每个维度上的-1000到1000。投影矩阵接着会将在这个指定的范围内的坐标变换为标准化设备坐标的范围(-1.0, 1.0)。所有在范围外的坐标不会被映射到在-1.0到1.0的范围之间,所以会被裁剪掉。

    3.1 投影:由投影矩阵创建的观察箱(Viewing Box)被称为平截头体(Frustum),每个出现在平截头体范围内的坐标都会最终出现在用户的屏幕上。将特定范围内的坐标转化到标准化设备坐标系的过程(而且它很容易被映射到2D观察空间坐标)。

    3.2 透视除法:一旦所有顶点被变换到裁剪空间,最终的操作——透视除法(Perspective Division)将会执行,在这个过程中我们将位置向量的x,y,z分量分别除以向量的齐次w分量;透视除法是将4D裁剪空间坐标变换为3D标准化设备坐标的过程。这一步会在每一个顶点着色器运行的最后被自动执行。

    3.3 正射投影矩阵(Orthographic Projection Matrix):正射平截头体直接将平截头体内部的所有坐标映射为标准化设备坐标,因为每个向量的w分量都没有进行改变;如果w分量等于1.0,透视除法则不会改变这个坐标。创建一个正射投影矩阵,我们可以使用GLM的内置函数。

    3.4 透视投影矩阵(Perspective Projection Matrix):顶点坐标的每个分量都会除以它的w分量,距离观察者越远顶点坐标就会越小。这是也是w分量非常重要的另一个原因,它能够帮助我们进行透视投影。最后的结果坐标就是处于标准化设备空间中的。在GLM中可以这样创建一个透视投影矩阵。
glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);//第三和第四个参数设置了平截头体的近和远平面。我们通常设置近距离为0.1f,而远距离设为100.0f。所有在近平面和远平面内且处于平截头体内的顶点都会被渲染。

五:Z缓冲:解决一些理应被遮挡的面,因为绘制次序靠后,竟然变成可见的问题

  1. 也被称为深度缓冲(Depth Buffer)。GLFW会自动为你生成这样一个缓冲(就像它也有一个颜色缓冲来存储输出图像的颜色)。
  2. 深度测试:深度值存储在每个片段里面(作为片段的z值),当片段想要输出它的颜色时,OpenGL会将它的深度值和z缓冲进行比较,如果当前的片段在其它片段之后,它将会被丢弃,否则将会覆盖。这个过程称为深度测试(Depth Testing),它是由OpenGL自动完成的。
  3. 如果我们想要确定OpenGL真的执行了深度测试,首先我们要告诉OpenGL我们想要启用深度测试;它默认是关闭的。我们可以通过glEnable函数来开启深度测试。
  4. 因为我们使用了深度测试,我们也想要在每次渲染迭代之前清除深度缓冲(否则前一帧的深度信息仍然保存在缓冲中)。就像清除颜色缓冲一样,我们可以通过在glClear函数中指定DEPTH_BUFFER_BIT位来清除深度缓冲:

OpenGL中的坐标系统详细概括:包括Z缓冲的更多相关文章

  1. (原)关于OpenGL中的几个坐标系统的理解

    在我们使用opengl做图像处理的过程中,其中必不可少的基本都会用到顶点着色器和片元着色器. 完整的渲染管线图: 那么在这两个着色器程序中,我们需要绘制我们的图像的时候,他们的坐标和位置对应关系是如何 ...

  2. GLSL 在OpenGL中向shader传递信息【转】

    http://blog.csdn.net/hgl868/article/details/7872219 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为shade ...

  3. 【GLSL教程】(三)在OpenGL中向shader传递信息 【转】

    http://blog.csdn.net/racehorse/article/details/6634830 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为sh ...

  4. openGL中的gl,glu,glut

    OpenGL函数库相关的API有核心库(gl).实用库(glu).辅助库(aux).实用工具库(glut).窗口库(glx.agl.wgl)和扩展函数库等.gl是核心,glu是对gl的部分封装.glx ...

  5. (转)OpenGL中位图的操作(glReadPixels,glDrawPixels和glCopyPixels应用举例)

    (一)BMP文件格式简单介绍 BMP文件是一种像素文件,它保存了一幅图象中所有的像素.这种文件格式可以保存单色位图.16色或256色索引模式像素图.24位真彩色图象,每种模式种单一像素的大小分别为1/ ...

  6. 【opengl】OpenGL中三维物体显示在二维屏幕上显示的变换过程

    转自:http://blog.sina.com.cn/s/blog_957b9fdb0100zesv.html 为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模 ...

  7. OPenGL中的缓冲区对象

    引自:http://blog.csdn.net/mzyang272/article/details/7655464 在许多OpenGL操作中,我们都向OpenGL发送一大块数据,例如向它传递需要处理的 ...

  8. Linux OpenGL 实践篇-4 坐标系统

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

  9. OpenGL中的拾取模式( Picking)

    1. Opengl中的渲染模式有三种:(1)渲染模式,默认的模式:(2)选择模式, (3)反馈模式.如下 GLint glRenderMode(GLenum mode) mode可以选取以下三种模式之 ...

随机推荐

  1. URAL - 1029 dp

    题意: n层楼,每层楼有m个房间.找出一个路径从第一层到达第M层,使得路径上的所有数的和是所有可达路径中最小的,每次上到下一层以后就不能再上去,依次输出路径上的各点在所在层的列数. 题解: 参考链接: ...

  2. Educational Codeforces Round 89 (Rated for Div. 2) C. Palindromic Paths (思维)

    题意:有一个\(n\)x\(m\)的矩阵,从\((1,1)\)出发走到\((n,m)\),问最少修改多少个数,使得所有路径上的数对应相等(e.g:\((1,2)\)和\((n-1,m)\)或\((2, ...

  3. LeetCode刷题笔记 - 12. 整数转罗马数字

    学好算法很重要,然后要学好算法,大量的练习是必不可少的,LeetCode是我经常去的一个刷题网站,上面的题目非常详细,各个标签的题目都有,可以整体练习,本公众号后续会带大家做一做上面的算法题. 官方链 ...

  4. 超易懂!原来SOLID原则要这么理解!

    说到 SOLID 原则,相信有过几年工作经验的朋友都有个大概印象,但就是不知道它具体是什么.甚至有些工作了十几年的朋友,它们对 SOLID 原则的理解也停留在表面.今天我们就来聊聊 SOLID 原则以 ...

  5. [Golang]-1 Slice与数组的区别

    目录 数组 1.创建数组: 2.数组是值拷贝传递: 切片(slice) 1.首先看看slice的源码结构: 2.slice的创建: 3.slice使用make创建 4.切片作为参数传递 5.Golan ...

  6. meidi

    最近觉得某些公司的选择题也是很基础,非常值得总结回味.今天做了美的的笔试,20道选择题(单选14+6多选).特此记录如下(部分忘了烦请见谅): 1. 是我昨晚刚刚总结的List,Set,Map的区别: ...

  7. HDU 3065 病毒侵袭持续中(AC自动机 模板)题解

    题意:给出主串中每个模式串的个数 思路:毒瘤出题人多组数据没说给的是多组数据. 板子: struct Aho{ struct state{ int next[130]; int fail, cnt; ...

  8. HDU 3920 Clear All of Them I(状压DP)题解

    题意:2n个点,一个起点,开n枪,每枪必须打两个点,花费为起点到其中一点距离加上两点距离.问打完2n个点的最小花费. 思路:很显然应该dp状态,然后枚举i j两个空位置去填,那么复杂度$O(20 * ...

  9. SQL Tutorials & MySQL & SQL Server

    SQL Tutorials SQL MySQL https://www.mysql.com/ $ mysql --version # mysql Ver 8.0.21 for osx10.15 on ...

  10. codesign wants to access key 密码是什么

    codesign wants to access key 密码是什么 真正的是开机密码,不是 apple id 密码 https://developer.apple.com/forums/thread ...