使用glRotatef旋转.obj模型

时间:2016-05-04 08:52:14

标签: android-studio opengl-es rotateanimation

我尝试使用 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 screen 轴旋转。不是它自己的 x 。有人知道为什么吗?

说明

  • 我注意到 onDrawFrame 一直在运行。但是, y 上的 1.2f 不会持续翻译模型。只有当 z != 0.(我不知道为什么).. ..
  • 我读过我们可以使用三角法来获得正确的 x 向量。但这对我没有任何意义。如果应用程序能够在内存中保留模型的位置以使 yrot 正确,为什么不能为 xrot 执行相同的操作?

2 个答案:

答案 0 :(得分:1)

操作顺序很重要。矩阵乘法链中的变换(每个OpenGL变换调用实际上只是一个矩阵乘法)在反向"中行动,即,首先应用乘以变换矩阵的最后一个变换。每次转型都会影响到当地的#34;原点。

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

  

现在当我要求' xrot'它围绕x屏轴旋转。不是它自己的x。有人知道为什么吗?

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

  

我注意到onDrawFrame一直在运行。然而,该模型并未在y上持续翻译1.2f。

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

  

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

在每次迭代时,z的值可能会集成到代码中其他位置的其他变量中。

答案 1 :(得分: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);
    }

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

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

因此,在模型的任何位置,我们都可以转动其本地 x y 轴。

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