Android-эмулятор OpenGL на дальние расстояния - PullRequest
2 голосов
/ 21 декабря 2011

Я пытаюсь сделать простой квадрат в OpenGl на Android. Тот же код работает правильно на реальных устройствах, но на эмуляторе квадрат деформируется. Это происходит только тогда, когда я использую высокое значение zFar (в данном примере это zNear = 80000, zFar = 80100) и не зависит от расстояния между zNear и zFar. Проверка глубины отключена, поэтому я не думаю, что она имеет какое-либо отношение к буферу глубины.

Вот как это выглядит на реальном устройстве:

http://imgur.com/9246P

А вот так это выглядит на эмуляторе.

http://i.imgur.com/L0IKv.png

Когда квадрат вращается, деформации становятся более заметными, и в какой-то момент квадрат исчезает, а затем снова появляется.

Я знаю, что эмулятор использует другую реализацию OpenGl, может быть, это ошибка? Кто-нибудь знает, почему он так себя ведет?

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 ++;
        }
    }
}

Заранее спасибо.

1 Ответ

2 голосов
/ 22 декабря 2011

Я воспроизвел эффект из вашего кода, и проблема исчезнет, ​​если вы разделите все эти числа 80000-ти на 10. Я подозреваю, что реализация OpenGL эмулятора использует внутреннюю арифметику с фиксированной запятой, что заставит ее боротьсяс такими большими числами.Если он использует формат glFixed (S15.16), он не сможет обрабатывать числа, превышающие 32768.

...