GLSurfaceView поверх других представлений - PullRequest
0 голосов
/ 21 июня 2020

Я хочу показать GLSurfaceView поверх текущего содержимого моей активности в виде наложения. Однако содержимое ниже должно быть видимым.

Вот мои настройки GLSurfaceView:

setEGLConfigChooser(8, 8, 8, 8, 16, 0)
setZOrderOnTop(true)
holder.setFormat(PixelFormat.TRANSLUCENT)
setRenderer(renderer)

И в рендерере у меня есть:

    override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
        // Set the background frame color
        GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.1f)
    }

    override fun onDrawFrame(unused: GL10) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
    }

    override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
    }

Я вижу, что он полупрозрачный, но определенно прозрачность не 10%, как значение альфа. Это намного выше. Даже если установить чистый цвет на (1, 0, 0, 0), я могу увидеть очень насыщенный красный оверлей поверх основного содержимого.

Любые идеи, как визуализировать GLSurfaceView поверх основного содержимого и поддержка прозрачности?

Ответы [ 2 ]

0 голосов
/ 22 июня 2020

Я не знаком с этим углом API, но из того, что вы описываете, я думаю, вы ожидаете обычного альфа-смешивания:

DestinationColor.rgb = (SourceColor.rgb * SourceColor.a) + (DestinationColor.rgb * (1 - SourceColor.a));

Но API фактически предлагая предварительно умноженное смешивание:

DestinationColor.rgb = (SourceColor.rgb * One) + (DestinationColor.rgb * (1 - SourceColor.a));

Чтобы получить желаемый результат, вам нужно самостоятельно умножить выходной RGB на выходной альфа-канал. Например, для вашего примера, если вам нужно очень небольшое красное наложение, вы должны использовать:

GLES20.glClearColor(0.1f, 0.0f, 0.0f, 0.1f)

Этот документ является хорошим учебником по предварительно умноженному альфа и почему это полезно: https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre

0 голосов
/ 22 июня 2020

Как вариант. Вы можете отобразить OpenGLES-рендеринг в отдельном элементе представления и установить прозрачность для остальной части содержимого активности, например:

<com.app.CustomSurfaceView
    android:id="@+id/oglView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:alpha="0.5"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <Button
        android:id="@+id/button"
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:text="Button"
        android:textSize="38sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Результат:

введите описание изображения здесь

...