【问题标题】:GLSurfaceView on top of other viewsGLSurfaceView 在其他视图之上
【发布时间】:2020-06-21 14:33:15
【问题描述】:

我想在我的活动当前内容之上显示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)
    }

我可以看到它是半透明的,但透明度绝对不是 alpha 值的 10%。它要高得多。即使将清除颜色设置为 (1, 0, 0, 0),我也可以在主要内容之上看到非常饱和的红色叠加层。

任何想法如何在我的主要内容之上呈现 GLSurfaceView 并支持透明度?

【问题讨论】:

    标签: android opengl-es glsurfaceview


    【解决方案1】:

    作为一个变体。您可以在单独的视图元素中显示 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>
    

    结果:

    【讨论】:

    • 我希望 GLSurfaceView 位于其他内容之上,反之亦然
    【解决方案2】:

    我不熟悉 API 的这个角落,但根据您的描述,我认为您期待普通的 alpha 混合:

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

    但 API 实际上提供了预乘混合:

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

    要获得您想要的结果,您需要自己将输出 RGB 乘以输出 Alpha。例如对于你的例子,如果你想要一个非常轻微的红色覆盖,你应该使用:

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

    本文档是关于预乘 alpha 及其有用性的一个很好的入门:https://developer.nvidia.com/content/alpha-blending-pre-or-not-pre

    【讨论】:

    • 这与我的问题无关
    • 你说过,在使用GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.1f) 时,“我可以看到它是半透明的,但绝对透明度不是 alpha 值的 10%”。我是说您需要将 RGB 预乘以 alpha 值,即使用 GLES20.glClearColor(0.1f, 0.0f, 0.0f, 0.1f)。你试过这个吗?它是否会产生预期的 10% 透明度?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2016-12-27
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多