一步步学OpenGL《复合变换》讲述.doc

  1. 1、本文档共9页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
一步步学OpenGL《复合变换》 背景 在前面的几个教程中我们建立了几种基本图形变换是我们能灵活的将物体移动到3d世界的任意地方。我们还有很多要学(相机控制和透视投影等等),但你可能也已经想到,复合的图形变换也是必的。多数情况下,你会想缩放物体来和3d世界相适应,旋转物体到合适的方向,移动物体到某个地方等等。到现在我们已经实践了每一次的单一图形变换。为了实现上面一系列的变换,我们需要对顶点位置左乘第一个变换矩阵,然后得到的结果再左乘下一个变换矩阵等等,将所有变换矩阵都左乘顶点位置之后实现多个变换。一种笨办法就是在shader中应用每一个变换矩阵实现所有的变换,但这样很低效,因为对于所有顶点这些矩阵都是一样的,只有顶点的位置发生变化,这样要不断重复对每个顶点位置进行这一系列的矩阵相乘操作。幸运的是线性代数中有一些规则可以说让我们的生活更加简易,他告我们对于给定的一组矩阵M0…Mn和一个向量V有下面的等式换算: Mn * Mn-1 * ... * M0 * V = (Mn* Mn-1 * ... * M0) * V 所以如果你令: N = Mn * Mn-1 * ... * M0 那么: Mn * Mn-1 * ... * M0 * V = (Mn * Mn-1 * ... * M0) * V = N * V 这意味着我们可以一次性计算N,然后把它作为一致变量传给shader和每一个顶点位置相乘完成所有的变换,这个只需要GPU对每个顶点进行一次矩阵/向量相乘操作。 当计算N的时候怎样安排每个变换矩阵的先后顺序呢?你首先要记住向量最开始先是被最右边的矩阵左乘的(上面的例子就是M0)。然后向量被从右边到左边所有的变换矩阵所变换。在3d图形中你通常希望先缩放物体,然后旋转它,然后平移,之后再进行camera转换最后投影到2d屏幕。让我们先看先旋转后平移会怎样: 可以看出,如果先平移物体的话会很难来设置物体的最终位置,因为当你将物体远离坐标原点后,再旋转物体会同时造成物体的平移效果(是绕原点旋转,而不是绕自身旋转了),这是我们希望能避免的。通过先旋转后移动可以避免这两个操作的相互依赖性,这也是尽量围绕原点对称建模的原因,那样当你缩放或者旋转物体不会产生副作用,缩放和旋转后物体依然保持和之前一样对称。 源代码详解 (1) #define ToRadian(x) ((x) * M_PI / 180.0f) #define ToDegree(x) ((x) * 180.0f / M_PI) 在这个教程中我们开始要使用具体的角度值了。标准C语言库中三角函数使用弧度值作为参数。上面的宏定义可以实现角度和弧度之间的转换。 (2) inline Matrix4f operator*(const Matrix4f Right) const { Matrix4f Ret; for (unsigned int i = 0 ; i 4 ; i++) { for (unsigned int j = 0 ; j 4 ; j++) { Ret.m[i][j] = m[i][0] * Right.m[0][j] + m[i][1] * Right.m[1][j] + m[i][2] * Right.m[2][j] + m[i][3] * Right.m[3][j]; } } return Ret; } 这里是定义了矩阵相乘的操作符。可以看到结果矩阵的值依次是左边矩阵每一行和右边矩阵对应每一列的点乘。这个矩阵相乘的操作对实现管线类十分重要。 (3) class Pipeline { public: Pipeline() { ... } void Scale(float ScaleX, float ScaleY, float ScaleZ) { ... } void WorldPos(float x, float y, float z) { ... } void Rotate(float RotateX, float RotateY, float RotateZ) { ... } const Matrix4f* GetTrans(); private: Vector3f m_scale; Vector3f m_worldPos; Ve

文档评论(0)

shuwkb + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档