Ножницы OpenGL/Libgdx

Я пытаюсь в libgdx остановить рендеринг актеров за пределами группы, а также некоторые прямоугольники внутри группы, пример ниже

----------------------
----------------------
--******************--
--******************--
--*****--------*****--
--******************--
--******************--
----------------------
----------------------

Группа определяется как * где я хотел бы, чтобы актеры рисовались, - это где я хотел бы, чтобы актеры обрезались.

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

    Rectangle scissors = new Rectangle();
    Rectangle clipBounds = new Rectangle(getX(), getY(), getWidth(), getHeight());
    ScissorStack.calculateScissors(screen.getCamera(), screen.getBatch().getTransformMatrix(), clipBounds, scissors);
    ScissorStack.pushScissors(scissors);
    super.draw(batch, parentAlpha);
    batch.flush();
    ScissorStack.popScissors();

Как я могу также обрезать актеров внутри группы (я пытался добавить другие границы клипа, но он отображает только спрайты, которые находятся внутри обеих границ клипа).

Спасибо,

2 ответа

Реализация собственной ScissorGroup


ножничная группа:

      class ScissorGroup : Group() {

    private lateinit var localToScreenCoordinates: Vector2
    private lateinit var localToScreenSize       : Vector2

    private var X: Int = 0
    private var Y: Int = 0
    private var W: Int = 0
    private var H: Int = 0


    override fun draw(batch: Batch?, parentAlpha: Float) {
        if (stage != null) drawScissor(batch, parentAlpha)
    }



    private fun drawScissor(batch: Batch?, parentAlpha: Float) {
        batch?.endbegin {}

        localToScreenCoordinates = localToScreenCoordinates(Vector2())
        localToScreenSize        = stage.viewport.project(Vector2(width, height))

         X = localToScreenCoordinates.x.toInt()
         Y = Gdx.graphics.height - localToScreenCoordinates.y.toInt()
         W = localToScreenSize.x.toInt()
         H = localToScreenSize.y.toInt()

        Gdx.gl.glEnable(GL20.GL_SCISSOR_TEST)
        Gdx.gl.glScissor(
            X, Y,
            W - stage.viewport.zeroScreenVector.x.toInt(),
            H - stage.viewport.zeroScreenVector.y.toInt(),
        )

        super.draw(batch, parentAlpha)
        batch?.flush()
        Gdx.gl.glDisable(GL20.GL_SCISSOR_TEST)
    }

}

fun Batch.beginend(block: Batch.() -> Unit = { } ) {
    begin()
    block()
    end()
}

fun Batch.endbegin(block: Batch.() -> Unit = {  }) {
    end()
    block()
    begin()
}

 val Viewport.zeroScreenVector: Vector2 get() = project(Vector2(0f, 0f))

Как использовать:

      val scissor = ScissorGroup()
stage.addActor(scissor)
scissor.debug()
scissor.setBounds(50f, 0f, 50f, 50f)
scissor.addActor(a)

Я не думаю, что вы можете вложить внутреннюю область "против ножниц" в область ножниц. Так что, насколько я знаю, вы не можете использовать базовые примитивы Libgdx/OpenGL для достижения этой цели.

Вы можете сделать нечто подобное, перерисовав самую внутреннюю область "------" после рисования ваших актеров (материал "***").

В качестве альтернативы вы можете использовать буфер трафарета, буфер глубины или пользовательский фрагментный шейдер. (См. https://github.com/mattdesl/lwjgl-basics/wiki/LibGDX-Masking для идей.)

Другие вопросы по тегам