(x,y,z):组合起来表示两个重要的值,一个是方向,一个是向量
多边形面积公式:
float s = 0.0;
for(i=0; i<n; i++)
{
s += (point[i].x*point[(i+1)%n].y+point[(i+1)%n].x*point[i].y)/2;
}
逆时针给予点 A是正面的面积 A>0
顺时针给予点 A是背面的面积 A<0
AB + BC = AC
AB - AC = CB 共同起点指向被减
已知两个非零向量A,B 作 OA=A OB=B 则角AOB称为向量A和向量B的夹角
记作 <A,B> 并规定 0<= <A,B> <= 180(大于等于0度,小于等于180)
A*B = |A|*|B|*COS<A,B>
两个向量的数量积:
A*B = B*A
(A+B)+C = A+(B+C)
|A*B| 小于等于 |A|*|B| (三角形)
(A*B)*C 不等于 A*(B*C)
(A*B)平方 不等于 A的平方* B的平方
由 A*B = A*C (A不为0) 推不出 B=C
(B和C共线的时候不成立)
两个向量的向量积:
A X B 若 A和B 不共线 |A X B| = |A|*|B|*sin<A,B>
A X B 的方向是垂直于 A 和 B 右手系
openGL 变换术语:
视图 : 指定观察者或者照相机的位置
模型 : 在场景中移动的物体
模型视图:描述视图和模型变换的二元性
投影:改变视景体的大小或重新设置它的形状
视口:这是一种伪变换,只是对框口上的最终输出进行缩放。
视图变换:
视图变换是应用到场景中的第一变换它用来确定场景中的有利位置
在正投影中观察者被认为在Z轴正方向无穷远的位置,能够看到视景体
中任何东西
视图变换允许我们把观察点放在所希望的任何位置,并允许在任何方向
上观察场景
确定视图变换就像在场景中放置照相机并让它指向某个方向
从大局上考虑在应用任何其他模型变换之前,必须先应用视图变换这样做是
因为对视觉座标而言,视图变换移动了当前的工作座标,所有后续变换随后
都会基于新调整的座标系进行。然后在实际开始考虑如何进行变换时,就会
更容易地看到这些变换是如何实现的了
模型变换:
模型变换用于操纵模型和其中的特定对象,这些变换将对象移动到需要的位置
然后再对他们进行旋转和缩放。
模型视图二元性:
实际上视图和模型变换按照它们内部效果和对场景的最终外观来说是一样的
将这两个区分开来纯粹是为了程序员方便
将对象向后移和将参考座标向前一移在视觉上没有区别
视图变换和模型变换一样都应用在整个场景中,在场景中对象常常先进行
视图变换后单独进行模型变换
模型视图:是指这两种变换在变换管线中进行组合,成为一个单独的矩阵
即模型视图矩阵
投影变换:
这种投影实际上定义了视景体并创建了剪切平面
剪切平面是3D空间中的平面方程式,OPenGL用它来确定几何图形对于观察者
来说是否可见
投影变换指定一个完成的场景(所有模型变换都已完成)是如何投影到屏幕上的
最终图像
视口变换:
投影变换完成后,就得到一个场景的二维投影,它将被映射到屏幕上某处的
窗口上,这种到物理窗口的映射是我们最后要做的变换称为视口变换
幸运的是我们不必为这是操心,图形硬件会为我们做好这些
模型视图矩阵:
模型视图矩阵是一个4X4矩阵
顶点数据实际上是4个元素其中包含一个附加值 W 它表示缩放因子
默认情况下这个值被设置为1.0
在数学中行优先矩阵和列优先矩阵互为转置矩阵
X1 Y1 Z1 T1
X2 Y2 Z2 T2
X3 Y3 Z3 T3
0 0 0 0
前三列的前3个元素只是方向向量 他们表示空间中
X轴(X1、X2、X3)、Y轴(Y1、Y2、Y3)、Z轴(Z1、Z2、Z3)上的方向
第四列向量包含变换后的座标系原点的X,Y, Z的值
最奇妙的是如果有一个包含了一个不同座标系的位置和方向的4X4矩阵
然后用一个表示原来座标系的向量,乘以这个矩阵得到的结果是一个转
到新座标系下的新向量
这就意味着空间中任何位置和任何想要的方向都可以由一个4X4矩阵唯一
确定并且如果使对象的所有向量乘以这个矩阵那么我们就将整个对象变换
到空间中的给定位置和方向
旋转、平移将这两个变化加在一起造作很简单,只需要两个矩阵相称
相乘时运算的顺序是有影响的
eg、一个旋转矩阵乘以一个平移矩阵,与一个平移矩阵乘以一个旋转矩阵是不同的
投影矩阵:
模型视图矩阵实际上是在视觉座标中移动几何图形到目前为止,我们已经在屏幕上
使用了范围为-1到+1(实际上沿Z轴方向范围也是-1到+1)的默认座标系。事实上
这个小小的座标范围确实是硬件唯一能够接受的
那么使用不同座标系的技巧就是将我们想要的座标系变换到这个单位立方体中
我们使用新的矩阵来完成这项工作,就是投影投影矩阵
变换管线 :
初始顶点数据 变换的视觉座标 剪裁座标
X 模型 X1 投影 X2
Y ==》 视图 ==》 Y1 ==》 ==》 Y2
Z 矩阵 Z1 矩阵 Z2
W W1 W2
规范化的设备座标 窗口座标
透视 X2/W2 视口
==》 ==》 Y2/W2 ==》 ==》 屏幕上显示图形
除法 Z2/W2 变换
裁剪座标值位于我们前面提到的+/-1.0单位座标系内,将有效地将所有位于
这个裁剪空间之外的数据消除掉
裁剪座标随后再除以W座标生成规范化的设备座标,其中W值可能会被投影矩阵
或者模型矩阵修改这取决于发生的变换
座标三元组将通过视口变换被映射到2D平面上这项操作也是由一个矩阵来表示
但是不能直接指定或者修改这个矩阵。
openGL将在内部根据指定的glviewport的值来设置这个矩阵。
像素包装:
图像数据在内存中很少以紧密包装的形式存在
在许多硬件平台上出于性能上的考虑一幅图像的每一行都应从一种
特定的字节对齐地址开始
在默认情况下opengl采用4个字节的对齐方式,这种方式适合于很多
目前正在使用的系统
如果不采用4个字节对其,可能会在后面的工作中导致某些很难发现
的与内存相关的奇怪bug,这可能会让我们焦头烂额。虽然这个看起来
可能像是一种存储空间的浪费,但是这种排列能够让大多数cpu更高效
的获取数据块
改变或恢复像素存储方式:glpixelstoref(...)
顶点着色器:
执行大量的计算得到顶点在屏幕上的位置
一个复杂的应用程序可能包含许多个顶点着色器,但是同一时刻
只能由一个顶点着色器起作用
细分着色器:
顶点着色器处理每个顶点的关联数据后,如果同时激活了细分着色器
那么它将进一步处理这些数据
细分着色器会使用patch来描述一个物体的形状,并使用相对简单的
patch几何体来完成细分的工作,其结果是几何图元的数量增加,并且
模型的外观变得更加平滑。
几何着色器:
允许在光栅化之前对图元做进一步处理,eg、创建新图元
图元装配:
顶点、细分、几何着色器所处理的都是顶点数据,此外这些顶点之间
如何构成几何图元的所有信息也会被传递到openGL中
图元装配阶段将这些顶点与相关的几何图元之间组织起来
剪切:
顶点可能会落在视口之外,也就是我们可以进行绘制的框口区域,
此时与顶点相关的图元会做出改动,以保证相关的像素不会在视
口外绘制
光栅化: 将更新后的图元传递给光栅化单元生成对应的片元我们
可以将一个片元视为一个候选像素
片元着色器:
最后一个可以通过编程控制屏幕上显示颜色的阶段
我们使用着色器计算片元的最终颜色
顶点着色器(包括细分和几何)决定图元应该位于屏幕的什么位置
片元着色器使用这些信息决定某个片原的颜色是什么
逐片元操作:
片元操作的下一步就是最后的独立片元处理过程
在这个阶段里会使用深度测试和模板测试的方式来决定一个片元是否是可见的