0

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

图片:开始时大约 5 分钟后

这是 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 上找到,这里。

我有什么明显的遗漏吗?有没有更好的方法来处理旋转,然后旋转回来?

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

  • 连结 4
  • HTC 感觉
  • 另一部我不记得名字的 LG 手机

这些设备没有显示问题:

  • 银河连结
  • 连结 7
  • Xoom
4

2 回答 2

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();

希望有帮助。

于 2012-12-28T09:54:36.960 回答
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();
}
于 2012-12-28T05:47:44.020 回答