Ножницы 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 для идей.)