在我的GLSurfaceView.Renderer中,我将我的场景分为两部分。第一组是偏移和旋转,而第二组是与“相机”对齐,所以我应用glRotate和glTranslate,然后应用完全相反的glTranslate和glRotate。在某些设备上,这样可以正常工作,但在其他设备上,整个场景会慢慢地从“中心”旋转。
这是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.
有什么明显的东西我不见了吗?有没有更好的方法来处理旋转,然后旋转回来?
到目前为止,我已经注意到了这个问题:
这些设备没有显示问题:
答案 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();
}