如何使LibGDX的GLSurfaceView透明,以便我们可以看到其后面的Android ImageView?

4
基本前提是我有两个Android视图......一个填充屏幕的背景视图(在这种情况下是ImageView),以及位于前景中并且是LibGDX应用程序的LibGDX GLSurfaceView。 我想在LibGDX GLSurfaceView中打一个洞,以便我可以看到后台ImageView透过显示。 也就是说,LibGDX部分的行为就像一个覆盖层。不幸的是,我根本无法让它起作用。 我已经剥离了所有代码,只保留了希望演示我正在尝试做什么的必要内容。
在完整的应用程序中,它是一个Android应用程序,其中背景View是视频,而由LibGdx渲染的前景则是一组需要叠加在视频上的视频控件。
public class MiniClientGDXTestActivity extends AndroidApplication implements ApplicationListener {
    @Bind(R.id.surface)
    FrameLayout uiFrameHolder;

    Stage stage;
    Batch batch;
    Camera camera;
    Viewport viewport;
    ShapeRenderer shapeRenderer;


    private View miniClientView;

    public MiniClientGDXTestActivity() {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        hideSystemUI(this);

        setContentView(R.layout.miniclientgltest_layout);
        ButterKnife.bind(this);

        AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
        //cfg.useGL20 = false;
        // we need to change the default pixel format - since it does not include an alpha channel
        // we need the alpha channel so the camera preview will be seen behind the GL scene
        cfg.r = 8;
        cfg.g = 8;
        cfg.b = 8;
        cfg.a = 8;

        miniClientView = initializeForView(this, cfg);

        if (graphics.getView() instanceof SurfaceView) {
            SurfaceView glView = (SurfaceView) graphics.getView();
            glView.setBackgroundColor(android.graphics.Color.TRANSPARENT);
            // force alpha channel - I'm not sure we need this as the GL surface is already using alpha channel
            glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
        }

        uiFrameHolder.addView(miniClientView);
    }

    @Override
    public void create() {
        camera = new OrthographicCamera();
        viewport = new StretchViewport(1920, 1080, camera);
        stage = new Stage(viewport);
        batch = stage.getBatch();
        shapeRenderer = new ShapeRenderer();

        Gdx.graphics.setContinuousRendering(false);
        Gdx.graphics.requestRendering();
    }

    @Override
    public void resize(int width, int height) {
        stage.getViewport().setWorldSize(1920, 1080);
        stage.getViewport().update(width, height, true);
        Gdx.graphics.requestRendering();
    }

    @Override
    public void render() {
        Gdx.gl20.glClearColor(0, 0, 0, 0);
        Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

        // draw whatever we have on the stage
        stage.draw();

        // draw red rectangle
        drawRect(10, 10, 1000, 1000);

        // draw a blue box
        fillRect(50, 50, 800, 800);

        // punch a hole in the surface (ie, clear an area) so that we can see the view that is
        // behind this view
        clearRect(200, 200, 1600, 600);
    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void dispose() {

    }

    public void drawRect(final int x, final int y, final int width, final int height) {
        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
        shapeRenderer.rect(x, y, width, height, Color.RED, Color.RED, Color.RED, Color.RED);
        shapeRenderer.end();
    }

    public void fillRect(final int x, final int y, final int width, final int height) {
        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.rect(x, y, width, height, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE);
        shapeRenderer.end();
    }

    public void clearRect(final int x, final int y, final int width, final int height) {
//                Gdx.gl.glEnable(GL20.GL_BLEND);
//                Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);


        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
        shapeRenderer.setColor(Color.CLEAR);
        shapeRenderer.rect(x, y, width, height);
        shapeRenderer.end();

//                Gdx.gl.glDisable(GL20.GL_BLEND);
    }

}

以下是XML布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:keepScreenOn="true">

    <FrameLayout
        android:visibility="visible"
        android:id="@+id/surface"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <!-- to see if we can see this -->
        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/background"/>

        <!-- gdx gets added here -->
    </FrameLayout>


</FrameLayout>

“View” 不是 LibGDX 框架的一部分。你没有在舞台上放置任何东西,但你正在绘制舞台。你到底想在这里做什么? - Madmenyo
无论如何,如果您想要在某些东西上“打洞”,我猜您唯一的选择就是使用图像和剪贴蒙版。https://github.com/mattdesl/lwjgl-basics/wiki/LibGDX-Masking - Madmenyo
我知道这个示例并没有做太多事情,因为我剥离了它所做的一切,只是为了说明问题。也就是说,我有两个Android View..一个ImageView作为背景,一个GLSurfaceView作为LibGDX。我想在GLSurfaceView中打一个洞,以便看到背景图像的一部分。我以这个libgdx教程为基础。https://github.com/libgdx/libgdx/wiki/Integrating-libgdx-and-the-device-camera 我不是试图遮盖2个LibGDX纹理/ pimaps。在很大程度上,这是一个android + GLSurfaceView问题(我认为)。 - stuckless
1个回答

4
似乎使用PixelFormat.RGBA_8888调用setZOrderOnTop可以解决问题。
    if (graphics.getView() instanceof SurfaceView) {
        GLSurfaceView glView = (GLSurfaceView) graphics.getView();
        glView.setZOrderOnTop(true);
        glView.getHolder().setFormat(PixelFormat.RGBA_8888);
    }

现在当调用clearRect方法时,它将在GLSurfaceView中打一个洞,以显示在其下方的Android视图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接