OpenGL几何变换---翻译http://www.songho.ca/opengl/gl_projectionmatrix.html
Overview
几何数据——顶点位置,和法向量(normal vectors),在OpenGL 管道raterization 处理过程之前可通过顶点运算(Vertex Operation)和基本组合运算改变这些数据。

Object Coordinates
对象的本地坐标系——任何变换之前的最初位置.为了变换(transformation)这些对象,可以调用glRotate(),glTranslatef(),glScalef()这些方法。
Eye Coordinates
使用GL_MODELVIEW矩阵和Object 坐标相乘所得。在OpenGL中用GL_MODELVIEW将对象对象空间(Object Space)变换到视觉空间(eye space)。GL_MODELVIEW
矩阵是模型矩阵(Model Matrix)和视觉矩阵(View Matrix)的组合 (
)。其中,Model 变换指的是将Object Space转换到World Space
(译注:World Space指的是OpenGL中的三维空间),而View 变换是将World space变换到eye space。

注意:在OpenGL中没有单独的camera(view) matrix。因此,为了模拟camera或者view的变换,其中的场景(3D物体和光照)必须通过和view相反的方向变换。也就是说,OpenGL总是将camera定义在(0,0,0)点,并且强制在eye space坐标系的-Z轴方向,而且不能变换。关于GL_MODELVIEW Matrix的详细资料可以查看此处:http://www.songho.ca/opengl/gl_transform.html#modelview
标准向量(Normal vectors)——从对象坐标系(Object coordinates)变换到视觉坐标系(eye coordinates),它是用来计算光照(lighting calculation)的.注意标准向量(Normal vectors)的变换和顶点的不同。其中视觉矩阵(view matrix)是GL_MODELVIEW逆矩阵的转置矩阵和标准向量(Normal vector是)相乘所得,即:

更多关于标准向量变换(Normal Vector Transformation)的资料可连接到此处:http://www.songho.ca/opengl/gl_normaltransform.html
剪切面坐标系(Clip Coordinates)
视觉坐标系和GL_PROJECTION矩阵相乘,得到剪切面坐标系。GL_PROJECTION矩阵定义了可视的空间(截头锥体)(译注:关于什么是截头锥体,我还查了下资料,发现它是这个样子的:



,这个就是投影的效果啦)以及顶点数据如何投影到屏幕上(视角或者正交化(orthogonal)),它被称为剪切面坐标系的原因是(x,y,z)变换之后
要和±w比较。更多关于GL_PROJECTION矩阵的资料可见:http://www.songho.ca/opengl/gl_transform.html#projection

标准化设备坐标系(NDC)
将剪切面坐标系除以w所得(关于w的讨论可见此处:,http://www.songho.ca/math/homogeneous/homogeneous.html),它被称为视角除法(perspective division)
.它更像是窗口坐标系,只是还没有转换或者缩小到屏幕像素。其中它取值范围在3个轴向从-1到1标准化了。

窗口坐标系(Window Coordinates)/屏幕坐标系(Screen Coordinates)
将标准化设备坐标系(NDC)应用于视口转换。NDC将缩小和平移以便适应屏幕的透视。窗口坐标系最终传递给OpenGL的管道处理变成了fragment。glViewPort()函数
用来定义最终图片映射的投影区域。同样,glDepthRange()用来决定窗口坐标系的z坐标。窗口坐标系由下面两个方法给出的参数计算出来
glViewPort(x,y,w,h);
glDepthRange(n,f);

视口转换公式很简单,通过NDC和窗口坐标系的线性关系得到:

OpenGL 转换矩阵

OpenGL使用4x4矩阵变换。注意,这16个元素存储在1D数组中,这些元素按列顺序排列。假如你想以行为顺序排列,你需要转置该矩阵。
OpenGL有4中不用的矩阵:GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE和GL_COLOR.你可以在
代码中使用glMatrixMode()函数改变当前的类型。例如,为了选择GL_MODELVIEW矩阵,可以这样:
glMatrixMode(GL_MODELVIEW);
---------------------------------------------------------------------------------------------------------------------------------------------
Model-View 矩阵(GL_MODELVIEW)
GL_MODELVIEW矩阵在一个矩阵中包含view矩阵和model 矩阵,为了变换view(camera),你需要将整个
场景施以逆变换。gluLookAt()用来设置viewing变换。
最右边的三个矩阵元素 (m12, m13, m14) 是用作位移变换的。m15元素是齐次坐标。(何为齐次坐标,参见:http://www.songho.ca/math/homogeneous/homogeneous.html),该元素是用来投影变换的。
3个元素集(m0, m1, m2),(m4, m5, m6)和(m8, m9, m10) 是用作欧拉变换和仿射变换,例如glRotate(),缩放glScalef().
注意这三个元素集实际上指得是3个正交坐标系:
(m0, m1, m2): +X 轴,向左的向量(left vector)(估计是相对屏幕自己来说),默认为(1,0,0)
(m4, m5, m6) : +Y轴,向上的向量(up vector),默认为(0,1,0)
(m8, m9, m10): +Z轴,向前的向量,默认为(0,0,1).
4 columns of GL_MODELVIEW matrix
我们能够不使用OpenGL变换函数,直接构造GL_MODELVIEW矩阵。下面有一些有用的代码构建
GL_MODELVIEW矩阵
1. Angles to Axes
2. Lookat to Axes
3. Matrix4 class
注意,OpenGL在多种变换同时施加到顶点上时以相反的顺序矩阵相乘。例如,假如一个顶点先以MA
进行变换。OpenGL首先在乘以顶点之前运用MB x MA 。故最后的变换出现在矩阵相乘之前,最先的变换在最后出现。


投影矩阵Projection Matrix(GL_PROJECTION)
GL_PROJECTION矩阵用来定义截锥体。该截锥体决定了那些对象或者对象的哪些部分将会被裁剪掉。同样,它也决定着3D场景怎样投影到屏幕中
(关于怎样构建投影矩阵,请查看
http://www.songho.ca/opengl/gl_projectionmatrix.html
OpenGL提供2个函数用来GL_PROJECTION变换。glFrustum()产生投影视角。glOrtho()产生正交(或者平行)投影。
两个函数都需要6个参数决定6个剪切面:left, right, bottom, top, near, 和far 平面。截锥体的8个顶点如下所示:
OpenGL Perspective Viewing Frustum
远端平面(后面)的顶点能够简单地通过相似三角形的比率计算出来。例如,远端平面的左侧可以如下计算:

对于正交投影,ratio为1,所以远端平面的left,right,bottom和top值都与近端平面的值相同。
同样,你也可以使用gluPerspective()和gluOrtho2D()函数,但是传递更少的参数。gluPerspective()只需要4个参数:视图的垂直区域(vertical field of view(FOV)),
width/height的ratio,还有近端平面和远端平面的距离。下面代码使用gluPerspective()和glFrustum()实现同样的功能:

OpenGL正交的截锥体
OpenGL Orthographic Frustum
然而,假如你想要一个非对称的视觉空间,你可以直接使用glFrustum()。例如,
假如你想要呈现一个大的场景到2个相邻的屏幕,你可以截断截锥体变成2个不对称的截锥体(左和右)。然后,
呈现每个截锥体场景。
(这句话太不好翻译了,原位如下:
For example, if you want to render a wide scene into 2 adjoining screens, you can break down the frustum into 2 asymmetric frustums (left and right). Then, render the scene with each frustum.
An example of an asymmetric frustum
纹理矩阵(GL_TEXTURE)
纹理坐标(s,t,r,q)在任何纹理映射之前乘以GL_TEXTURE矩阵所得,默认是恒等的。所以纹理映射到物体的位置将正好是你赋值给纹理坐标的位置。
通过改变GL_TEXTURE,你可以滑动,旋转,拉伸或者伸缩纹理。

颜色矩阵(GL_COLOR)
颜色部分是通过乘以GL_COLOR矩阵所得。该矩阵用于颜色空间和颜色组件的变换。(原位如下:It can be used for color space conversion and color component swaping)
颜色矩阵并不是通用的,需要GL_ARB_imaging扩展(什么是GL_ARB_imaging扩展?求解)
其他矩阵例子
glPushMatrix()——将当前的矩阵压入矩阵栈
glPopMatrix()——从当前的矩阵栈中弹出当前的矩阵
glLoadIdentity()——设置当前矩阵为等同矩阵
glLoadMatrix{fd}(m)——将当前矩阵替换成矩阵m
glLoadTransposeMatrix{fd}(m)——将当前矩阵换成其转置矩阵
glMultMatrix{fd}(m)——将当前矩阵乘以矩阵m,并且更新当前矩阵
glMultTransposeMatrix{fd}(m)——将当前矩阵乘以其转置矩阵,并且更新当前矩阵
glGetFloatv(GL_MODELVIEW_MATRIX, m) ——将GL_MODELVIEW矩阵的16个值加载到m中
例子1:ModelView Matrix

这个demo应用显示怎样使用glTranslatef()和glRotatef()操作GL_MODELVIEW
下载链接:
matrixModelView.zip:
http://www.songho.ca/opengl/files/matrixModelView.zip
(OS X 10.6+) matrixModelView_mac.zip: http://www.songho.ca/opengl/files/matrixModelView_mac.zip
注意所有的OpenGL函数在Mac和Windows下都在ModelGL.h和ModelGL.cpp中实现,在这些包中的这些文件是完全一样的。
该demo应用使用一个定制的4X4类(链接为:http://www.songho.ca/opengl/gl_matrix.html)作为默认的OpenGL矩阵例子,为了指定model和camera变换.
在ModelGL.cpp中有3中矩阵对象:matrixModel,matrixView和matrixModelView.每一种矩阵保存着预先计算好的变换。然后将这些矩阵元素传递给OpenGL的函数——glLoadMatrix().实际的画图程序应该向下面这个样子:

使用OpenGL默认的矩阵函数,相同的代码如下:

投影矩阵例子:

该 demo应用显示了如何使用glFrustum()和glOrtho()函数操作投影变换。
源码和二进制文件下载的链接:
matrixProjection.zip:
http://www.songho.ca/opengl/files/matrixProjection.zip
matrixProjection_mac.zip(OS X 10.6+):
http://www.songho.ca/opengl/files/matrixProjection_mac.zip
同样,ModelGL.h和ModelGL.cpp在两者的包中有同样的文件,且所有的OpenGL函数都置于这些文件中。
ModelGL类有一个定制的matrix对象:matrixProjection,两个成员函数:setFrustum()和setOrthoFrustum().
其功能与glFrustum()和glOrtho()函数相同

GL_PROJECTION矩阵构建的16个参数在这可以看到:
OpenGL几何变换---翻译http://www.songho.ca/opengl/gl_projectionmatrix.html的更多相关文章
- 实验3 OpenGL几何变换
转自:http://www.cnblogs.com/opengl/archive/2012/10/30/2747130.html 1.实验目的: 理解掌握一个OpenGL程序平移.旋转.缩放变换的方法 ...
- 4.4.2 OpenGL几何变换编程实例
程序运行结果如下图: #include <GL/glut.h> #include <stdlib.h> #include <math.h> /* 初始化显示窗口大小 ...
- OpenGL编程指南第版本学习笔记 --- OpenGL程序实现过程(win32 + OpenGL)
1. 先上代码 头文件glCommon.h #include <GL/glew.h> #include <GL/GL.h> #include <GL/GLU.h> ...
- 基于VC++ Win32+CUDA+OpenGL组合与VC++ MFC SDI+CUDA+OpenGL组合两种方案的遥感影像显示:获得的重要结论!
1.基于VC++ Win32+CUDA+OpenGL组合的遥感影像显示 在该组合方案下,初始化时将OpenGL设置为下面两种方式,效果一样 //设置方式1 glutInitDisplayMode (G ...
- OPENGL学习【一】VS2008开发OPENGL程序开发环境搭建
1.VS2008工具自行在网上下载安装,现只提供VS2008开发工具中配置OPENGL环境的详细步骤.开发包及编译工具会在下方一并放出链接. 2.打开CMake的工具,主要的配置信息如下,按照数字顺序 ...
- 【GISER && Painter】Chapter00:OpenGL原理学习笔记
说明:简单了解一下OpenGL的工作原理,初步认识计算机对于图形渲染的底层设计与实现,第一次接触,也没学过C艹,欢迎各位批评指正. 一 什么是OpenGL? OpenGL是一个开放标准(specif ...
- OpenGL的镶嵌
镶嵌(tessellation)是将凹边形分割或者是凸边形相交边组成的多边形.因为OpenGL只接受凸多边形的渲染,这些非凸多边形必须在绘制前进行镶嵌. 上图分别为凹四边形.中间有洞及自交的多边形. ...
- [OpenGL](翻译+补充)投影矩阵的推导
1.简介 基本是翻译和补充 http://www.songho.ca/opengl/gl_projectionmatrix.html 计算机显示器是一个2D的平面,一个3D的场景要被OpenGL渲染必 ...
- OpenGL 矩阵变换
Overview 几何数据--顶点位置,和标准向量(normal vectors),在OpenGL 管道raterization 处理过程之前可通过顶点操作(Vertex Operation)和基本组 ...
随机推荐
- Flume 开发人员指南V1.5.2
介绍 概述 Apache Flume是一个用来从非常多不同的源有效地收集.聚集和移动大量的日志数据到一个中心数据仓库的分布式的,可靠的和可用的系统. Apache Flume是Apache软件基金会的 ...
- Shell脚本值:运算符
算术运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用. expr 是一款表达式计算工具,使用它能完成表达式的求值操作. 例如:实现两个 ...
- oled屏幕
oled作为一种新型的有机显示屏,越来越现实出其重要性,它不但超薄可弯折并且可视视角较宽.处在不论什么角度看屏幕都不会造成图像的失真. 且它有三中原色:绿.红,蓝. 我近期在学安在智能车上的oled ...
- Spring学习十----------Bean的配置之Autowired注解实现
© 版权声明:本文为博主原创文章,转载请注明出处 @Required -@Required注解适用于bean属性的setter方法 -这个注解仅仅表示,受影响的bean属性必须在配置时被填充,通过在b ...
- MVC中的ViewData、ViewBag和TempData
一.ViewBag和ViewData的定义 public dynamic ViewBag { get; } public ViewDataDictionary ViewData { get; set; ...
- html用jquery获取屏幕宽度与滚动条的关系
当内容高度超过屏幕高度时,获取的屏幕宽度不包括滚动条.即使是浮动,也要显式设置高度,才会全屏. 未超过时,获取的宽度包括滚动条.
- eclipse-jee版配置tomcat
Eclipse作为一款优秀的java开发开源IDE,集成了许多优秀的开发控件.下来我就如何安装eclipse及插件进行说明: 一.JDK安装 JDK是作为整个java的核心,包括运行环境,编译工具 ...
- Office 365 开发入门
<Office 365 开发入门指南>公开邀请试读,欢迎反馈 终于等来了这一天,可以为我的这本新书画上一个句号.我记得是在今年的2月份从西雅图回来之后,就萌发了要为中国的Office 36 ...
- 安装Redis图形监控工具---RedisLive
RedisLive简介 RedisLive是一款用Python编写基于WEB的Redis图形监控工具,也是一款实时监控Redis数据的开源软件,以WEB的形式展现出redis中的key的情况,实例数据 ...
- Kindeditor 修改内容时如何不让 及 <> 被自动转义
$html = str_replace(' ', ' ', $html); $html = str_replace('>', '>', $html); $html ...