6.基础变换
向量
在math3d库中,M3DVector3f表示一个三维向量(x,y,z),M3DVector4f表示一个四维向量(x,y,z,w),w表示缩放因子,默认为1.0,x,y,z值通过除以w来进行缩放
空间中的每一个点即是一个顶点,也是一个向量
向量点乘 运算返回2个向量之间的夹角
float m3dDotProduct3(const M3DVector3f u, const M3DVector3f v)返回夹角的余弦值
float m3dGetAngleBetweenVector3(const M3DVector3f u,const M3DVector3f v);返回夹角的弧度值
向量叉乘 运算返回一个新的向量。这个新向量与原来2个向量垂直
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u ,const M3DVector3f v);
OpneGL变换术语
| 术语 | 意义 |
|---|---|
| 视图 | 指定观察者或摄像机的位置 |
| 模型 | 在场景中移动物体 |
| 模型视图 | 描述视图和模型变换的二元性 |
| 投影 | 改变视景体的大小和重新设置它的形状 |
| 视口 | 这是一种伪变化,只是对窗口上的最终输出进行缩放 |
顶点变换
初始顶点数据-模型视图矩阵->变换后的视觉坐标-投影矩阵->裁剪坐标-透视除法->规范化设备坐标-视口变换->绘制顶点数据
平移&旋转
要改变摄像机与物体之间的距离,有2种方式:
1.摄像机移动
2.物体移动
例如要摄像机和物体远离15
1.将观察者坐标位置Z移动往屏幕里移动15个单位位置.
表示离屏幕之间的距离 负数,是往屏幕后面移动;正数,往屏幕前面移动
cameraFrame.MoveForward(-15.0f);
2.将物体向屏幕外移动15.
objectFrame.MoveForward(15.0f);
Dome
操作: 点击向右一次
结果及分析:
objectMove = 1;objectRotate = 1,即移动物体,旋转物体。物体在原地进行了旋转
objectMove = 1;objectRotate = 0,即移动物体,旋转摄像机。物体没有变化,因为在压栈里没有用到摄像机的坐标矩阵,所以旋转无效objectMove = 0;objectRotate = 1,即移动摄像机,旋转物体。物体在原地进行了旋转objectMove = 0;objectRotate = 0,即移动摄像机,旋转摄像机。物体没有旋转,而是向右移动了。因为旋转的摄像机,所以是射线机围绕原点向右旋转了,而我们绘制的是摄像机的视野,所以看起来物体就向右移动了
旋转的球
模型视图矩阵 = 平移矩阵 * 旋转矩阵
变换矩阵 = 投影矩阵 * 模型视图矩阵
图形绘制函数
- 球
gltMakeSphere(GLTriangleBatch& sphereBatch, GLfloat fRadius, GLint iSlices, GLint iStacks);
参数1:sphereBatch,三角形批次类对象
参数2:fRadius,球体半径
参数3:iSlices,从球体底部堆叠到顶部的三角形带的数量;其实球体是一圈一圈三角形带组成
参数4:iStacks,围绕球体一圈排列的三角形对数
建议:一个对称性较好的球体的片段数量是堆叠数量的2倍,就是iStacks = 2 * iSlices; 绘制球体都是围绕Z轴,这样+z就是球体的顶点,-z就是球体的底部。 - 甜甜圈
gltMakeTorus(GLTriangleBatch& torusBatch, GLfloat majorRadius, GLfloat minorRadius, GLint numMajor, GLint numMinor);
参数1:torusBatch,三角形批次类对象
参数2:majorRadius,甜甜圈中心到外边缘的半径
参数3:minorRadius,甜甜圈中心到内边缘的半径
参数4:numMajor,沿着主半径的三角形数量
参数5:numMinor,沿着内部较小半径的三角形数量 - 圆柱/圆锥
void gltMakeCylinder(GLTriangleBatch& cylinderBatch, GLfloat baseRadius, GLfloat topRadius, GLfloat fLength, GLint numSlices, GLint numStacks);参数1:cylinderBatch,三角形批次类对象
参数2:baseRadius,底部半径
参数3:topRadius,头部半径
参数4:fLength,圆形长度
参数5:numSlices,围绕Z轴的三角形对的数量
参数6:numStacks,圆柱底部堆叠到顶部圆环的三角形数量
圆柱体,从0开始向Z轴正方向延伸。圆锥体,是一端的半径为0,另一端半径可指定。 - 光盘
void gltMakeDisk(GLTriangleBatch& diskBatch, GLfloat innerRadius, GLfloat outerRadius, GLint nSlices, GLint nStacks);
参数1:diskBatch,三角形批次类对象
参数2:innerRadius,内圆半径
参数3:outerRadius,外圆半径
参数4:nSlices,圆盘围绕Z轴的三角形对的数量
参数5:nStacks,圆盘外网到内围的三角形数量
矩阵堆栈
类型GLMatrixStack::GLMatrixStack(int iStackDepth = 64);
在堆栈顶部载入一个单元矩阵void GLMatrixStack::LoadIdentity(void);
在堆栈顶部载⼊矩阵(参数:4*4矩阵)void GLMatrixStack::LoadMatrix(const M3DMatrix44f m);
矩阵乘以矩阵堆栈顶部矩阵,相乘结果存储到堆栈的顶部void GLMatrixStack::MultMatrix(const M3DMatrix44f);
获取矩阵堆栈顶部的值GetMatrix函数.为了适应GLShaderMananger的使⽤,或者获取顶部矩阵的副本
const M3DMatrix44f & GLMatrixStack::GetMatrix(void); 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);
旋转函数angle参数是传递的度数,⽽而不不是弧度void MatrixStack::Rotate(GLfloat angle,GLfloat x,GLfloat y,GLfloat z);
移动函数void MatrixStack::Translate(GLfloat x,GLfloat y,GLfloat z);
缩放函数void MatrixStack::Scale(GLfloat x,GLfloat y,GLfloat z);
将堆栈的顶部压入任何矩阵void GLMatrixStack::LoadMatrix(GLFrame &frame);
矩阵乘以矩阵堆栈顶部的矩阵。相乘结果存储在堆栈的顶部void GLMatrixStack::MultMatrix(GLFrame &frame);
将当前的矩阵压栈void GLMatrixStack::PushMatrix(GLFrame &frame);
GLFrame函数,这个函数⽤用来检索条件适合的照相矩阵void GetCameraMatrix(M3DMatrix44f m,bool bRotationOnly = flase);
抗锯齿
对点进行抗锯齿处理 glEnable(GL_POINT_SMOOTH);
对线进行抗锯⻮处理 glEnable(GL_LINE_SMOOTH);
对多边形进⾏抗锯⻮处理 glEnable(GL_POLYGON_SMOOTH);
代码资料见:Github