OpenGL的常见矩阵和变化
2020-07-10 本文已影响0人
iOSer_jia
前言
OpenGL的坐标转换中需要对顶点坐标进行计算,这种对多个顶点的计算我们需要借助到矩阵,OpenGL所有的变换都是通过矩阵相乘实现的,本文将通过各种变化来了解矩阵的作用。
坐标系变换
一个物体从初始的3维坐标到屏幕上的2维坐标需要经历物体坐标->世界坐标->观察者坐标->裁剪坐标->规范化设备坐标->屏幕坐标这个过程。
![](https://img.haomeiwen.com/i1818006/ca7995a119672ed8.png)
模型矩阵
用于将物体从物体坐标转化为世界坐标,事实上,物体本身的变化也可以用模型矩阵,比如旋转、平移等。具体可以用下面代码获取模型矩阵。
GLFrame objectFrame;
// 旋转(绕世界坐标系x轴旋转)
objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);
// 模型矩阵
M3DMatrix44f mObjectFrame;
objectFrame.GetMatrix(mObjectFrame);
视图矩阵
用于将物体从世界坐标转化为观察者坐标,涉及到观察位置变化的需要用到试图矩阵。
可以用下面代码获取试图矩阵
GLFrame cameraFrame;
cameraFrame.MoveForward(-30.0f);
// 视图矩阵
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
投影矩阵
用于物体从观察者坐标转化为裁剪坐标,和投影方式有关,在确定投影方式后我们就可以得到投影矩阵。
GLFrustum viewFrustum;
// 设置透视投影
viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 500.0f);
M3DMatrix44f projectionMatrix = viewFrustum.GetProjectionMatrix();
矩阵堆栈
在绘制场景是,我们往往需要使用很多矩阵进行换算,而我们常常需要保存这些换的中间状态,以便变化后的快速恢复,比如场景绘制是我需要让矩阵从A到B,再由A到C,如果没有矩阵堆栈,我们要A到B的矩阵,再由B->A,之后才能有A到C,而有矩阵栈,我们只要让A入栈,再让B入帐,执行完A->B后,再将栈顶的B出栈,执行A->C,显然比单个矩阵效率高很多。
GLMatrixStack modelViewMatrix;
//调用顶部载入单元矩阵
modelViewMatrix.LoadIdentity();
// 压栈,如果括号内为空则将栈顶的矩阵复制一份放到栈顶
modelViewMatrix.PushMatrix();
//矩阵乘以矩阵堆栈的顶部矩阵,相乘的结果随后简存储在堆栈的顶部
modelViewMatrix.MultMatrix(mCamera);
//矩阵乘以矩阵堆栈的顶部矩阵,相乘的结果随后简存储在堆栈的顶部
modelViewMatrix.MultMatrix(mObjectFrame);
//几何变换的管道(用于合成模型试图投影矩阵(mvp矩阵))
GLGeometryTransform transformPipeline;
//设置变换管线以使用两个矩阵堆栈
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
// 调用平面着色器
shaderManager.UseStockShader(GLT_SHADER_FLAT,transformPipeline.GetModelViewProjectionMatrix(), vBlack);
// 绘制
...
//还原到以前的模型视图矩阵(单位矩阵)
modelViewMatrix.PopMatrix();