1

我正在尝试实现一些简单的事情:在 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 相关。

4

1 回答 1

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) 的顺序,在这种情况下是矩阵堆栈。

于 2013-01-17T09:13:39.630 回答