Прозрачный шейдер заполняет прозрачные фрагменты чистым цветом

1

Я пытаюсь сделать прозрачный объект в OpenGL ES 2.0. Это живые обои, я использую GLWallpaperService в качестве базового класса для этого. Я настраиваю OpenGL таким образом:

    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glDepthFunc(GLES20.GL_GEQUAL);
    GLES20.glClearDepthf(0.0f);
    GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);

В инициализации стола я устанавливаю режим рендеринга:

        setRenderMode(RENDERMODE_CONTINUOUSLY);

Шейдеры, которые я использую, берутся из примера PowerVR OGLES2AlphaTest для альфа-тестирования, который отлично работает на устройстве HTC Desire.
Вот код для шейдеров:

private final String mVertexShader = "uniform highp mat4 uMVPMatrix;\n" +
        "attribute highp vec4 aPosition;\n" +
        "attribute highp vec2 aTextureCoord;\n" +
        "varying mediump vec2 vTextureCoord;\n" +
        "void main() {\n" +
        "  gl_Position = uMVPMatrix * aPosition;\n" +
        "  vTextureCoord = aTextureCoord;\n" +
        "}\n";

private final String mFragmentShader = "precision mediump float;\n" +
        "varying mediump vec2 vTextureCoord;\n" +
        "uniform sampler2D sTexture;\n" +
        "void main() {\n" +
        "  vec4 base = texture2D(sTexture, vTextureCoord);\n" +
        "  if(base.a < 0.5){ discard; }\n" +
        "  gl_FragColor = base;\n" +
        "}\n";

Код для кадра рендеринга:

public void onDrawFrame(GL10 glUnused) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    GLES20.glUseProgram(mProgram);
    checkGlError("glUseProgram");

    GLES20.glDisable(GLES20.GL_BLEND);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maPosition");
    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
    GLES20.glEnableVertexAttribArray(maPositionHandle);
    checkGlError("glEnableVertexAttribArray maPositionHandle");
    GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maTextureHandle");
    GLES20.glEnableVertexAttribArray(maTextureHandle);
    checkGlError("glEnableVertexAttribArray maTextureHandle");

    long time = SystemClock.uptimeMillis() % 4000L;
    float angle = 0.090f * ((int) time);
    time = SystemClock.uptimeMillis();// % 4000L;
    angle = 0.030f * ((int) time);
    Matrix.setRotateM(mMMatrix, 0, angle, 0, 1.0f, 0);
    Matrix.scaleM(mMMatrix, 0, 0.075f, 0.075f, 0.075f);
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, numPolys);
    checkGlError("glDrawArrays");
}

Результирующее изображение рендеринга: http://imgur.com/hNqm0. Но если я использую

        setRenderMode(RENDERMODE_WHEN_DIRTY);

для инициализации обоев, я могу получить правильный рендеринг, но только 1 неподвижный кадр после переключения на другую активность и обратно на обои. Если я периодически пытаюсь позвонить requestRender(), я все равно получаю неправильную прозрачность.

  • 0
    Я сузил проблему до шейдера, пожалуйста, обратитесь к этому вопросу: stackoverflow.com/questions/6086551/…
Теги:
opengl-es
opengl-es-2.0

1 ответ

0
Лучший ответ

ОК, я решил. Это было вызвано записью в буфер глубины.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню