如何在LibGDX中进行混合

2022-09-02 03:59:39

我基本上想在LibGDX中玩混合模式,但不知道该怎么做。我在互联网上找到了这张图片。我想在LibGDX上做同样的事情。有人可以教我如何。

enter image description here

我一直在使用Scene2D。这是我的非工作代码段。

private class MyGroup extends Group {

    Image red, blue;

    public MyGroup() {
        Texture texture = new Texture(Gdx.files.internal("images/red.png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        red = new Image(texture);

        texture = new Texture(Gdx.files.internal("images/blue.png"));
        texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
        blue = new Image(texture);

        red.setX(-25);
        blue.setX(25);
    }
    @Override
    public void draw(Batch batch, float parentAlpha) {
        batch.end();
        batch.begin();
        batch.enableBlending();

        red.draw(batch, parentAlpha);

        Gdx.gl.glEnable(Gdx.gl20.GL_BLEND);
        Gdx.gl.glBlendFuncSeparate(
                Gdx.gl20.GL_DST_COLOR, 
                Gdx.gl20.GL_SRC_COLOR,
                Gdx.gl20.GL_ONE,
                Gdx.gl20.GL_ONE);

        blue.draw(batch, parentAlpha);
    }
}

答案 1

我意识到这不是一个新问题,但我想我会为其他任何在OpenGL中进行渲染的人分享一些信息(了解这些术语有很大帮助,所以你不仅仅是猜测混合和匹配)请注意,这个网站是我自己学习的大部分内容的方式, 所以可以在那里找到更完整的信息。

目标颜色:缓冲区中的颜色,除非对其进行修改或用新值覆盖,否则将(最终)绘制该颜色。

源颜色:来自其他渲染命令的颜色,这些命令可能与目标颜色交互,也可能不与目标颜色交互(取决于我们的设置)

默认混合公式:Final Color = (SourceColor*SourceBlendingFactor)+(DestinationColor*DestinationBlendingFactor) 此默认公式可以更改,但我建议阅读顶部的源链接以获取更多信息

两个混合因子是我们可以搞砸的。我们可以将它们设置为:

GL_ZERO: RGB(0,0,0) A(0)
GL_ONE: RGB(1,1,1) A(1)
GL_SRC_COLOR: RGB(sourceR, sourceG, sourceB) A(sourceA)
GL_ONE_MINUS_SRC_COLOR: RGB(1-sourceR, 1-sourceG, 1-sourceB) A(1-sourceA)
GL_DST_COLOR: RGB(destinationR, destinationG, destinationB) A(destinationA)
GL_ONE_MINUS_DST_COLOR: RGB(1-destinationR, 1-destinationG, 1-destinationB) A(1-destinationA)
GL_SRC_ALPHA: RGB(源 A, 源 A, 源 A) A(源 A)
GL_ONE_MINUS_SRC_ALPHA: RGB(1-源 A, 1-源 A, 1-源 A) A(1-源A)
GL_DST_ALPHA: RGB(目的 A, 目的 A, 目标 A) A(目的A)
GL_ONE_MINUS_DST_ALPHA: RGB(1-目标 A, 1-目标 A, 1-目标A) A(1-目标A)
GL_SRC_ALPHA_SATURATE: RGB(min(sourceA, 1-destinationA), min(sourceA, 1-destinationA), min(sourceA, 1-destinationA)) A(1)

以下也使用一些预定义的常量颜色,默认情况下它是黑色
GL_CONSTANT_COLOR: RGB(constantR, constantG, constantB) A(constantA)
GL_ONE_MINUS_CONSTANT_COLOR: RGB(1-constantR, 1-constantG, 1-constantB) A(1-constantA)
GL_CONSTANT_ALPHA: RGB(常数A, 常数A, 常数A) A(常数A)
GL_ONE_MINUS_CONSTANT_ALPHA: RGB(1-常数A, 1-常数A, 1-常数A) A(1-常数A)

因此,所有这些都只是预定义的浮点值,这些浮点值与我们的源或目标相乘,然后添加到另一个。

从图像中最容易观察到的是GL_ZERO和GL_ONE。我们最终得到的是任何具有ONE的图像。


了解GL_DST_COLOR GL_ZERO

当GL_ZERO在目标上时,我们将忽略缓冲区中当前的任何颜色信息(因为将所有内容乘以零)。但是,由于源图像上也GL_DST_COLOR,我们最终会将源和目标的r,g,b,a值相乘。

由于示例图像的性质,这在图像中看起来不错。一个充当纯色图像,而另一个灰度图像看起来和作用几乎像一束光,以“揭示”我们GL_ZERO设置中的颜色。

希望这有助于解释我们在上面看到的图像,并帮助每个人了解这些图像实际上是如何混合在一起的。


答案 2

好吧,为了部分回答我的问题,这是我使用的技巧。如果我做错了什么,请告诉我。注意:这不适用于其他功能。就像我将GL_DST_COLOR和GL_ZERO结合起来时,它不会输出我想要的东西。但其他人会。所以只是玩它。我仍然在这里寻找其他答案。

代码如下:

private class MyGroup extends Group {

    Texture dst, src;

    public MyGroup() {
        dst = new Texture(Gdx.files.internal("images/dst.png"));
        dst.setFilter(TextureFilter.Linear, TextureFilter.Linear);

        src = new Texture(Gdx.files.internal("images/src.png"));
        src.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        // We need to cast to use blending function
        SpriteBatch sb = (SpriteBatch)batch;

        // draw our destination image
        sb.draw(dst, 0, 0);
        sb.end();

        // remember SpriteBatch's current functions
        int srcFunc = sb.getBlendSrcFunc();
        int dstFunc = sb.getBlendDstFunc();

        // Let's enable blending
        sb.enableBlending();
        sb.begin();

        // blend them
        b.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
        sb.draw(src, 0, 0);

        // Reset
        sb.end();
        sb.begin();
        sb.setBlendFunction(srcFunc, dstFunc);

    }
}

推荐