I’m trying to render a simple square in OpenGl on Android. The same code behaves correctly on real devices, but on the emulator the square is deformed. This only happens when I use high zFar value (in this example it’s zNear = 80000, zFar = 80100) and does not depend on distance between zNear and zFar. Depth test is disabled, so I don’t think it has anything to do with the depth buffer.
This is how it looks on a real device:

And this is how it looks on an emulator.

When the square is rotating the deformations become more visible, and at some point the square disappears and then reappears again.
I know that the emulator uses a different implementation of OpenGl, maybe it’s a bug?
Does anybody know why it’s behaving like this?
public class SquareTestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLSurfaceView glView = new GLSurfaceView(this);
glView.setRenderer(new SquareRenderer());
setContentView(glView);
}
public class SquareRenderer implements Renderer {
private final float[] verts = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f };
private final int nrOfVerts = verts.length / 3;
private FloatBuffer vertBuf;
private float rotation;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_DEPTH_TEST);
gl.glColor4f(1, 0, 0, 1);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verts.length * Float.SIZE / 8);
byteBuffer.order(ByteOrder.nativeOrder());
vertBuf = byteBuffer.asFloatBuffer();
vertBuf.put(verts);
vertBuf.position(0);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
GLU.gluPerspective(gl, 90, (float) width / height, 80000, 80100);
gl.glMatrixMode(GL10.GL_MODELVIEW);
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, 80050, 0, 0, 0, 0, 1, 0);
gl.glRotatef(rotation, 0, 0, 1);
gl.glScalef(80000, 80000, 1);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuf);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, nrOfVerts);
rotation ++;
}
}
}
Thanks in advance.
I reproduced the effect from your code, and the problem goes away if you divide all of those 80000-ish numbers by 10. I suspect that the emulator’s OpenGL implementation is using fixed-point arithmetic internally, which would cause it to struggle with numbers that big. If it uses the glFixed format (S15.16), it will not be able to handle numbers greater than 32768.