为什么要理解这些基础变化
根据我的观察,大家在学习OpenGL的时候有一个误区,就是认为如果不能精通那些3D图形数学知识,就会让我们寸步难行。其实不然,就像我们不需要懂得任何关于汽车结构和内燃机方面的知识也能开车。但是,我们最好能对汽车有足够的了解,以便我们意识到什么时候需要更换机油、定期加油、汽车常规保养工作。同样要成为一名可靠和有能力的OpenGL程序员,至少需要理解这些基础知识,才知道能做什么?以及哪些工具适合我们要做的工作。初学者,经过一段时间的实践,就会渐渐理解矩阵和向量。并且培养出一种更为直观的能力,能够在实践中充分利用所学的内容。
基础变化的介绍
大家现在还明不明⽩向量、矩阵是什么?有没有能力在脑海中默算出2个矩阵的乘法?以及这些矩阵对 OpenGL意味着什么?
GLTools 库中有一个组件叫Math3d,其中包含了大量好用的OpenGL 一致的3D数学和数据类型。虽然我们不必亲自进行所有的矩阵和向量的操作,但要知道它们是什么?以及如何运用它们。
-
向量
3个值(x、y、z)组合起来表示2个重要的值,⽅向和数量
math3d库,有2个数据类型,能够表示一个三维或者四维向量。M3DVector3f
可以表示一个三维向量(x,y,z),而M3DVector4f
则可以表示一个四维向量(x,y,z,w).在典型情况下,w坐标设为1.0。x,y,z值通过除以w,来进⾏行缩放。⽽除以1.0则本质上不改变x,y,z值。
typedef float M3DVector3f[3];
typedef float M3DVector4f[4];
M3DVector3f vVector;//声明一个三分量向量操作
M3DVector4f vVectro= {0.0f,0.0f,1.0f,1.0f} ;//声明一个四分量的操作:
//声明一个三分量顶点数组,例如生成一个三角形
M3DVector3f vVerts[] = {
};
-0.5f,0.0f,0.0f,
0.5f,0.0f,0.0f,
0.0f,0.5f,0.0f
};
(1)向量点乘
//实现点乘方法:
//⽅法1:返回的是-1,1之间的值。它代表这2个向量的余弦值。
float m3dDotProduct3(const M3DVector3f u,const
M3DVector3f v);
//⽅法2:返回2个向量之间的弧度值。
float m3dGetAngleBetweenVector3(const M3DVector3f
u,const M3DVector3f v);
(2)向量叉乘
//实现叉乘方法:
//result 为法向量
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f
u ,const M3DVector3f v);
-
矩阵
在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合
typedef float M3DMatrix33f[9];
typedef float M3DMatrix44f[16];
M3DMatrix44f mCamera;//定义4*4矩阵
-
OpenGL中的基础变化
(1)OpenGL变换术语概况,如下图所示:
(2)顶点变换管线,如下图:
从顶点变换管线图可以看到,顶点数据是通过不同的矩阵变换最后显示到窗口上的,那么这个过程中我们需要用到哪些矩阵相关的工具呢,下面我们就来了解矩阵相关的工具。
-
矩阵堆栈(GLMatrixStack)
//类型
GLMatrixStack::GLMatrixStack(int iStackDepth = 64);
//在堆栈顶部载入一个单元矩阵
void GLMatrixStack::LoadIdentity(void);
//在堆栈顶部载入任何4*4矩阵
void GLMatrixStack::LoadMatrix(const M3DMatrix44f m);
//矩阵乘以矩阵堆栈顶部矩阵,相乘结果存储到堆栈的顶部
void GLMatrixStack::MultMatrix(const M3DMatrix44f);
//获取矩阵堆栈顶部的值 GetMatrix 函数
void GLMatrixStack::GetMatrix(M3DMatrix44f mMatrix);
//将当前矩阵压入堆栈(栈顶矩阵copy 一份到栈顶)
void GLMatrixStack::PushMatrix(void);
//将M3DMatrix44f 矩阵对象压入当前矩阵堆栈
void PushMatrix(const M3DMatrix44f mMatrix);
//将GLFame 对象压入矩阵对象
void PushMatrix(GLFame &frame);
//出栈(出栈指的是移除顶部的矩阵对象)
void GLMatrixStack::PopMatrix(void);
//Rotate 函数angle参数是传递的度数,而不是弧度
void GLMatrixStack::Rotate(GLfloat angle,GLfloat x,GLfloat y,GLfloat z); //生成旋转矩阵
void GLMatrixStack::Translate(GLfloat x,GLfloat y,GLfloat z);//生成平移矩阵
void GLMatrixStack::Scale(GLfloat x,GLfloat y,GLfloat z);//生成缩放矩阵 -
使用照相机(摄像机) 和⻆色帧进行移动(GLFrame)
class GLFrame
{
protected:
M3DVector3f vOrigin; // Where am I?
M3DVector3f vForward; // Where am I going?
M3DVector3f vUp; // Which way is up?
}
//将堆栈的顶部压入任何矩阵
void GLMatrixStack::LoadMatrix(GLFrame &frame);
//矩阵乘以矩阵堆栈顶部的矩阵,相乘结果存储在堆栈的顶部
void GLMatrixStack::MultMatrix(GLFrame &frame);
//将当前的矩阵压栈
void GLMatrixStack::PushMatrix(GLFrame &frame);
以上有不正确的地方欢迎留言指出,有问题随时联系,有需要补充的也可以提出,谢谢。