Прозрачный шейдер заполняет прозрачные фрагменты чистым цветом - PullRequest
1 голос
/ 19 мая 2011

Я пытаюсь сделать прозрачный объект в 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(), я все равно получаю неправильную прозрачность.

1 Ответ

0 голосов
/ 03 сентября 2012

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

...