我正在尝试实现一些简单的事情:在X轴上设置平移,并将对象围绕它的中心旋转一个固定的角度。
为了达到这个目的,就我目前的知识而言,有必要将物体移动到中心,旋转并移回原始位置。好的。我得到的问题是,它看起来像是旋转它的局部轴并沿着这些轴进行最后一次平移,所以它以错误的位置结束。
这是我的代码:
public void draw(GL10 gl) {
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);
gl.glTranslatef(x, 0, 0);
gl.glTranslatef(-x, 0, 0);
gl.glRotatef(-80, 0, 1, 0);
gl.glTranslatef(x, 0, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES10.GL_UNSIGNED_SHORT, indicesBuffer);
}
在旋转之前,对象应该是0,0,0。它正确旋转。但它接近屏幕,好像x轴指向我(80°)。
注意:我只让“opengl”作为标记,因为这是一个普通的OpenGL问题,答案不应该与Android有关。
答案 0 :(得分:4)
这是不赞成这样做的方式,但我想这不是没有回答这个问题的借口。
如果将多个变换应用于顶点,则OpenGL以相反的顺序执行矩阵乘法。例如,如果首先通过MA转换顶点,然后按MB转换顶点,则OpenGL在乘以顶点之前首先执行MB x MA。因此,最后一个变换首先出现,第一个变换出现在代码的最后一个。
gl.glPushMatrix();
gl.glTranslatef(globalX, 0, 0);
gl.glTranslatef(localX, 0 ,0);
gl.glRotatef(-80, 0, 1, 0);
gl.glTranslatef(-globalX, 0, 0);
gl.glPopMatrix();
首先从您在变换层次结构中的位置移动到原点。 然后围绕该原点旋转。 沿任何轴应用一些局部运动。 将对象移回其全局定位。
使用glPushMatrix()和glPopMatrix()来撤消相同位置的元素的更改,它具有相对定位的相同父元素。 推送保留了OpenGL在上面的本地代码中的操作之后应用的先前(父)对象的转换,因为它是公共堆栈(LIFO)的顺序,在这种情况下是矩阵堆栈。