Проблема глубинного буфера OpenGL на Android - PullRequest
0 голосов
/ 26 мая 2011

Я занимаюсь разработкой движка 3D-рендеринга для Android.У меня возникли некоторые проблемы с буфером глубины.Я рисую несколько кубиков, один большой и два маленьких, которые упадут поверх большего.Во время рендеринга я видел, что с буфером глубины явно что-то не так, как видно на снимке экрана:

Depth Buffer Problem on Device

Этот снимок экрана был сделан на HTC Hero (под управлением Android 2.3.4) с OpenGL ES 1.1 Все приложение (все еще) нацелено на OpenGL ES 1.1.На эмуляторе он выглядит одинаково.

Это вызовы в моем методе onSurfaceCreated в рендере:

public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    Log.d(TAG, "onsurfacecreated method called");

    int[] depthbits = new int[1];
    gl.glGetIntegerv(GL_DEPTH_BITS, depthbits, 0);
    Log.d(TAG, "Depth Bits: " + depthbits[0]);

    gl.glDisable(GL_DITHER);

    gl.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

    gl.glClearColor(1, 1, 1, 1);
    gl.glClearDepthf(1f);
    gl.glEnable(GL_CULL_FACE);
    gl.glShadeModel(GL_SMOOTH);
    gl.glEnable(GL_DEPTH_TEST);

    gl.glMatrixMode(GL_PROJECTION);
    gl.glLoadMatrixf(
            GLUtil.matrix4fToFloat16(mFrustum.getProjectionMatrix()), 0);

    setLights(gl);
}

Вызов GL для битов глубины возвращает 16 на устройстве и 0на эмуляторе.Это имело бы смысл, если бы он не работал только на эмуляторе, поскольку, очевидно, отсутствует буфер глубины.(Я попытался установить для EGLConfigChooser значение true, поэтому он создал бы Config с максимально возможным буфером глубины 16 бит, но это не сработало на эмуляторе. Это не было необходимо на устройстве.)

В моем методе onDrawFrame я выполняю следующие вызовы OpenGL:

    gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    gl.glClearDepthf(1);

И затем для каждого из кубов:

    gl.glEnableClientState(GL_VERTEX_ARRAY);
    gl.glFrontFace(GL_CW);
    gl.glVertexPointer(3, GL_FIXED, 0, mVertexBuffer);
    // gl.glColorPointer(4, GL_FIXED, 0, mColorBuffer);
    gl.glEnableClientState(GL_NORMAL_ARRAY);
    gl.glNormalPointer(GL_FIXED, 0, mNormalBuffer);
    // gl.glEnable(GL_TEXTURE_2D);
    // gl.glTexCoordPointer(2, GL_FLOAT, 0, mTexCoordsBuffer);
    gl.glDrawElements(GL_TRIANGLES, mIndexBuffer.capacity(),
            GL_UNSIGNED_SHORT, mIndexBuffer);
    gl.glDisableClientState(GL_NORMAL_ARRAY);
    gl.glDisableClientState(GL_VERTEX_ARRAY);

Чего мне не хватает?Если вам нужно больше кода, просто спросите.

Спасибо за любой совет!

Ответы [ 2 ]

1 голос
/ 30 мая 2011

Теперь я правильно его заработал. Проблема была не в OpenGL. Это была (как упоминал Бантар) проблема с матрицей проекции. Я сам управляю матрицей проекций, и вычисление окончательной матрицы было как-то искажено (или, по крайней мере, не так, как ожидает OpenGL). Я не могу вспомнить, где я получил алгоритм для моих расчетов, но как только я изменил его на способ, которым OpenGL вычисляет матрицу проекции (или напрямую вызывает glFrustumf (...)), он работал нормально.

0 голосов
/ 26 мая 2011

попробуйте включить:

-glDepthFunc(GL_LEQUAL)
-glDepthMask( true );
...