初学OpenGL,对它的矩阵变换不甚了解,尤其是glTranslatef和glRotatef联合使用,立即迷得不知道东西南北。在代码中改变数据多次,终于得到了相关变换概念。
代码语言:javascript复制 glLoadIdentity(); // 重置当前的模型观察矩阵
glTranslatef(2.5f,0.0f,-20.0f);
glRotatef(rtri,1.0f,0.0f,0.0f);
glTranslatef(0.0f,1.0f,0.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f,1.0f,0.0f); // 绘制三角形
glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点
glColor3f(1.0f,0.0f,1.0f);
glVertex3f(-1.0f,-1.0f, 0.0f); // 左下
glColor3f(1.0f,0.5f,0.5f);
glVertex3f( 1.0f,-1.0f, 0.0f); // 右下
glEnd();
代码语言:javascript复制
知识准备:
OpenGL中的矩阵采用列优先存储,矩阵表示如下
假设有点(3,3,3),如果把该点沿x轴移动2单位,沿y轴移动3单位,沿z轴移动4单位,那么该点会是(3 2, 3 3, 4 4) = (5,6,7). 用矩阵表示是:
,左边的矩阵称为平移变换矩阵,若把2、3、4换成x、y、z,则用它乘以一个齐次坐标表示的向量,就可以将该向量平移(x,y,z). 旋转变换和缩放变换都像平移变换一样可用一个矩阵来表示。这里可以不用理会这些矩阵长什么样,只需清楚它们乘以一个齐次坐标表示的向量,就可以使该向量发生需要的变换。
把平移变换矩阵记为T(x,y,z),旋转变换矩阵记为R(s,x,y,z),表示绕向量(x,y,z)旋转s角度;把向量记为X。现在要把一个点X,如(3,3,3,1),移动(2,2,2)单位,再绕y轴旋转30度角,用矩阵表示即R(0,1,0,30)*T(2,2,2)*X,可以理解为离X最近的矩阵最先作用。理解这个顺序很重要,这样,所有变换都可以用一串矩阵的相乘来表示。
代码解释:
代码中glBegin到glEnd是绘制三角形。首先对三角形起作用的是旋转,然后是移动。明确了作用顺序后,还有一个让人困惑的就是坐标轴是否改变。因为glTranslatef的变换是以当前位置来变换的,也就是说用的是相对坐标而不是绝对坐标。
glLoadIdentity();
glTranslatef(-1.5f,0.0f,-6.0f);
glTranslatef(-1.5f,0.0f,-6.0f);
当glLoadIdentity之后,坐标轴回到OpenGL窗口的中心,通过两次glTranslatef(-1.5f,0.0f,-6.0f),坐标轴到了(-3.0f,0.0f,-12.0f);
所以三角形首先按向量(0.0f,1.0f,0.0f)移动,然后绕X轴旋转,然后再按向量(-2.5f,0.0f,-10.0f)移动,最终得到的就是把一个如下描述的图形:
这个图形在旋转,可以看出是绕X轴旋转的三角形,而所在的位置有两次glTranslatef确定。