场景慢慢旋转

时间:2012-12-28 05:36:05

标签: android opengl-es

在我的GLSurfaceView.Renderer中,我将我的场景分为两部分。第一组是偏移和旋转,而第二组是与“相机”对齐,所以我应用glRotate和glTranslate,然后应用完全相反的glTranslate和glRotate。在某些设备上,这样可以正常工作,但在其他设备上,整个场景会慢慢地从“中心”旋转。

图片:At startAfter ~5 mins

这是onDraw()函数:

@Override
public void onDrawFrame(GL10 gl) {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    // rotate card table
    gl.glRotatef(-20f, 1f, 0f, 0f);
    gl.glRotatef(  5f, 0f, 1f, 0f);
    gl.glRotatef(-10f, 0f, 0f, 1f);
    gl.glTranslatef( 1f, 3f, 0f);

    mDeck.draw(gl);

    // undo rotate for buttons/overlays
    gl.glTranslatef(-1f, -3f, 0f);
    gl.glRotatef( 10f, 0f, 0f, 1f);
    gl.glRotatef( -5f, 0f, 1f, 0f);
    gl.glRotatef( 20f, 1f, 0f, 0f);

    mOverlayBtns.draw(gl);
    mPass.draw(gl);
}

可以在GitHub上找到完整的源代码,here.

有什么明显的东西我不见了吗?有没有更好的方法来处理旋转,然后旋转回来?

到目前为止,我已经注意到了这个问题:

  • Nexus 4
  • HTC Sensation
  • 另一部LG名字我不记得的手机

这些设备没有显示问题:

  • Galaxy Nexus
  • Nexus 7
  • Xoom的

2 个答案:

答案 0 :(得分:1)

你的代码每帧都应用了一组仿射变换,问题是每次变换都是累积的,所以你一遍又一遍地应用变换。您需要使用glLoadIdentity(http://www.khronos.org/opengles/sdk/1.1/docs/man/glLoadIdentity.xml)重置当前加载的MODELVIEW矩阵,或者按当前矩阵,加载新矩阵,绘制然后弹回矩阵(就像您在修复响应中所做的那样)。

我会在每个帧绘制的开头放置一个glLoadIdentity。另外,通过您的修复,我也会这样做:

gl.glPushMatrix();

gl.glLoadIdentity(); // Be sure we start clean

// rotate card table
gl.glRotatef(-20f, 1f, 0f, 0f);
gl.glRotatef(  5f, 0f, 1f, 0f);
gl.glRotatef(-10f, 0f, 0f, 1f);
gl.glTranslatef( 1f, 3f, 0f);

mDeck.draw(gl);

gl.glPopMatrix();

希望有所帮助。

答案 1 :(得分:0)

我找到了解决问题的方法,但我仍然希望有人能够解释我上面遇到的问题。

不是旋转场景,而是旋转回来,我可以使用glPushMatrix和glPopMatrix来隔离两组。这样,glTranslate和glRotate组就可以将场景移回去了。

@Override
public void onDrawFrame(GL10 gl) {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);


    gl.glPushMatrix();

    // rotate card table
    gl.glRotatef(-20f, 1f, 0f, 0f);
    gl.glRotatef(  5f, 0f, 1f, 0f);
    gl.glRotatef(-10f, 0f, 0f, 1f);
    gl.glTranslatef( 1f, 3f, 0f);

    mDeck.draw(gl);

    gl.glPopMatrix();


    gl.glPushMatrix();
    // undo rotate for buttons/overlays
    // gl.glTranslatef(-1f, -3f, 0f);
    // gl.glRotatef( 10f, 0f, 0f, 1f);
    // gl.glRotatef( -5f, 0f, 1f, 0f);
    // gl.glRotatef( 20f, 1f, 0f, 0f);

    mOverlayBtns.draw(gl);
    mPass.draw(gl);

    gl.glPopMatrix();
}