月亮绕着地球转,地球绕着太阳转。多层旋转关系在opengl里是个啥玩意?让我们来看一看。
在opengl中,我们的各种操作会最终产生一个矩阵,矩阵与代表顶点的向量相乘得到最终的顶点信息。不过有趣的是,如果我们依次写下操作1,2,对应矩阵A,B,如果顶点的列向量是V,则变换的结果V'=ABV。可以看到的是,后定义的B操作先应用在了V上。这是因为opengl内的矩阵是右乘的(具体问度娘)。
我不是很喜欢这种反着看的方法。所以我推荐把这些操作看成对坐标系的操作,那就正常了。对于上面的例子,就可以认为是先把坐标系做A操作再做B操作(因为原点和绘制物体的顶点是对立的关系,很有意思)。有点抽象,我们上具体例子。
要绘制一个简单的日地月模型。我们有了一个基本的思路,先在原点画太阳,再把坐标系旋转一定角度,再沿着某个方向平移,画个地球,再旋转坐标系,然后平移,绘制月亮。代码如下:
glutSolidSphere(50, 100, 100);//太阳
glRotatef(clock()/10, 0, 0, 1);
glTranslated(300, 0, 0);
glutSolidSphere(30, 100, 100);//地球
glRotated(clock()/10, 0, 0, 1);
glTranslated(-100, 0, 0);
glutSolidSphere(10, 30, 30);//月亮
我们如果按照对顶点的操作来看,由上到下,平移操作产生的矩阵定义为T1,T2,旋转的为R1,R2。我们来看看月亮经历了什么。
R1T1R2T2:沿X移动-100,旋转,沿着X移动300,旋转。还是能够理解的,但是和平常的习惯不一样,所以还是推荐看成对坐标系的操作。
但是这样弄出来的不过是三个圆在转,所以我们在太阳处添加额外光照,但是要设置太阳变成发光物体的话,我们需要对太阳的材质的GL_EMISSION属性做出修改
glMaterialfv(GL_FRONT, GL_EMISSION, sun);
sun是一个数组,代表发光物体的RBGA。
这样太阳就看起来像是发光了,但是实际上我们设置在太阳的点光源对太阳发光没任何贡献。也不会出现太阳会过滤点光源的光