1

我尝试使用glRotatef围绕自己的轴旋转 .obj 3d 模型。但它没有按我的意愿工作。

代码

public void onDrawFrame(GL10 gl) {

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glEnable(GL10.GL_LIGHTING);
        gl.glLoadIdentity();

        gl.glTranslatef(0f, -1.2f, -z);
        gl.glRotatef(xrot, 1f, 0f, 0f);
        gl.glRotatef(yrot, 0f, 1f, 0f);

        model.draw(gl);
    }

问题

第一次旋转yrot效果很好:无论模型的位置如何,它总是围绕自己的z旋转(好吧,我要求围绕y旋转,所以它并不完美。但至少它使用自己的轴!)

现在,当我询问“xrot”时,它会围绕x 屏幕轴旋转。不是它自己的x。有人知道为什么吗?

评论

  • 我注意到onDrawFrame一直在运行。但是,该模型不会在y上不断平移1.2f。只有当z != 0 时。(我不知道为什么)..
  • 我读到我们可以使用三角函数来获得正确的x向量。但这对我来说没有意义。如果应用程序能够在内存中保存模型的位置以使yrot正确,为什么它不能为xrot做同样的事情?
4

2 回答 2

1

操作顺序很重要。矩阵乘法链中的变换(每个 OpenGL 变换调用实际上只是一个矩阵乘法)“反向”作用,即首先应用乘以变换矩阵的最后一个变换。并且每个转换都作用于“本地”原点。

您的第一个变换是绕 y 轴旋转。然后应用 x 轴旋转,但这发生在新的局部坐标系中。

现在,当我询问“xrot”时,它会围绕 x 屏幕轴旋转。不是它自己的 x。有人知道为什么吗?

在您的特定转换链中,x 轴旋转恰好与屏幕的 x 轴对齐。

我注意到 onDrawFrame 一直在运行。然而,模型不会在 y 上不断平移 1.2f。

OpenGL 不是场景图。它甚至不“知道”什么是模型。它只绘制单个点、线和三角形,一次一个,仅此而已。如果场景发生变化,则必须重新绘制所有内容。函数glRotateglTranslate不作用于模型。他们所做的只是操纵当前活动的变换矩阵中的值。当你最终绘制一些东西时,它只是这个矩阵用于转换传入的顶点向量(不仅仅是位置,固定函数中还有其他属性的矩阵,当使用着色器时,一切皆有可能)。无论如何,在开始绘制新框架时,您希望将矩阵重置为已知状态。就是glLoadIdentity这样。所以每一帧你都重新开始。

只有当 z != 0 时。(我不知道为什么)。

可能z在每次迭代时,值会被集成到代码中其他地方的某个其他变量中。

于 2016-05-04T09:15:08.720 回答
0

这是一个解决方案:

public void onDrawFrame(GL10 gl) {

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        gl.glEnable(GL10.GL_LIGHTING);

        if(flag==0) {
            gl.glLoadIdentity();
            gl.glTranslatef(0f, -1f, -z);
            flag=1; xrotold=0; yrotold=0;
        }
        else{
            float dxrot=xrot-xrotold;
            float dyrot=yrot-yrotold;

            gl.glRotatef(dxrot, 1f, 0f, 0f);
            gl.glRotatef(dyrot, 0f, 1f, 0f);

            yrotold=yrot;
            xrotold=xrot;
        }

        model.draw(gl);
    }

使用此解决方案,我们不会每个周期都加载标识。我们保持相同的矩阵。

然后我们计算无穷小旋转并将它们应用于全局矩阵。

因此,在模型的任何位置,我们都可以绕其局部xy轴转动。

感谢 datenwolf 向我展示了正确的方向。

于 2016-05-04T15:54:36.350 回答