Как сделать смешение в LibGDX

В основном я хочу играть с режимами смешивания в 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 (знание этих терминов очень помогает, поэтому вы не просто угадывая смешение и сопоставление). Обратите внимание, что этот сайт - это то, как я сам это узнал сам, поэтому там можно найти более полную информацию.

Цвет назначения: цвет в буфере, который будет (в конечном итоге) рисован, если он не будет изменен или не перезаписан новыми значениями.

Цвет источника: цвет, поступающий из дополнительных команд рендеринга, которые могут или не могут взаимодействовать с цветом назначения (в зависимости от наших настроек)

Стандартное уравнение смешивания: Конечный цвет = (SourceColor * SourceBlendingFactor) + (DestinationColor * DestinationBlendingFactor) (Это уравнение по умолчанию можно изменить, но я рекомендую прочитать ссылку на источник вверху для получения дополнительной информации)

Два BlendingFactors - это то, с чем мы можем общаться. Мы можем установить их так:

GL_ZERO: RGB (0,0,0) A (0)
GL_ONE: RGB (1,1,1) A (1)
GL_SOURCE_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 (sourceA, sourceA, sourceA) A (sourceA)
GL_ONE_MINUS_SRC_ALPHA: RGB (1-sourceA, 1-sourceA, 1-sourceA) A (1-sourceA)
GL_DST_ALPHA: RGB (destinationA, destinationA, destinationA) A (destinationA)
GL_ONE_MINUS_DST_ALPHA: RGB (1-destinationA, 1-destinationA, 1-destinationA) A (1-destinationA)
GL_SRC_ALPHA_SATURATE: RGB (мин (источникA, 1-destinationA), min (источникA, 1-destinationA), min (источникA, 1-destinationA)) A (1)

Следующее также использует некоторый предопределенный постоянный цвет, по умолчанию это черный цвет GL_CONSTANT_COLOR: RGB (константаR, константа G, константа B) A (константа A)
GL_ONE_MINUS_CONSTANT_COLOR: RGB (1-константаR, 1-константа G, 1-константа B) A (1-constantA)
GL_CONSTANT_ALPHA: RGB (константа A, постоянная A, постоянная A) A (константа A)
GL_ONE_MINUS_CONSTANT_ALPHA: RGB (1-constantA, 1-constantA, 1-constantA) A (1-constantA)

Таким образом, все это только предопределенные значения float, которые умножаются либо на наш источник, либо на пункт назначения, а затем добавляются к другому.

Проще всего наблюдать изображение - GL_ZERO и GL_ONE. В итоге получилось, что у любого изображения есть ОДИН.


Общие сведения о GL_ZERO с GL_DST_COLOR

Когда GL_ZERO находится в пункте назначения, мы игнорируем любую информацию о цвете, которая в настоящее время находится в буфере (потому что умножение всего на ноль). Однако, с GL_DST_COLOR также на исходном изображении, мы заканчиваем умножением значений r, g, b, значений источника и адресата.

Это хорошо выглядит на изображении из-за природы образцовых изображений. Один действует как сплошное цветное изображение, в то время как другое изображение в оттенках серого выглядит и действует почти как луч света, чтобы "раскрыть" цвет из нашей установки 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 current functions
        int srcFunc = sb.getBlendSrcFunc();
        int dstFunc = sb.getBlendDstFunc();

        // Let 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);

    }
}