シザーテストとは
シザーテストとは描画範囲を狭める機能です。矩形を指定することができます。
シザーテスト自体は扱いは簡単なのでOpenGL直に触ることが容易なlibGDXを利用する限りは単純なものならそのまま使ってもかまわないです。
一応libGDXにも用意されています。そのままではなくほんの少しだけ高機能なもの、シザースタックです。
シザースタックとは
シザースタックはシザーテストの矩形をスタックのように積み上げる機能です。Andの論理演算のように複数の矩形が重なっている部分のみ描画されます。
サンプルとして256x256の画像を描画してみます。
画像を描画する
基礎2とほぼ同じコードです。
public class MainListener20 extends ApplicationAdapter{
SpriteBatch batch;
Texture texture;
@Override
public void create() {
batch = new SpriteBatch();
texture = new Texture("enemy.png");
}
@Override
public void resize(int w, int h) {
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
}
public static void main(String[] args) {
new LwjglApplication(new MainListener20(), "libGdxTest", 256, 256);
}
}
Y方向を半分切り取る
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
ScissorStack.pushScissors(new Rectangle(0, 0, 256, 128));
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
ScissorStack.popScissors();
}
X方向を半分切り取る
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
ScissorStack.pushScissors(new Rectangle(0, 0, 128, 256));
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
ScissorStack.popScissors();
}
両方スタックに乗せる
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
ScissorStack.pushScissors(new Rectangle(0, 0, 256, 128));
ScissorStack.pushScissors(new Rectangle(0, 0, 128, 256));
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
ScissorStack.popScissors();
ScissorStack.popScissors();
}
今回のような単純な描画ではあまりスタックの意味がないですが、階層構造を持つ画面などではスタックが活躍します。Scene2Dのような場合ですね。
Scene2Dでシザースタックを使う
Scene2Dではさらに上位のAPIとしてActor自体がメソッドを持っています。
メソッドはそれぞれclipBegin()とclipEnd()です。
シザーテストという名前ではなくクリッピングというより上位の概念名にしていますが、中身は同じです。シザースタックを利用しています。
引数なしのclipBegin()をよびだすとそのコンポーネントのサイズでクリッピングされます。座標系はそのActorのローカル座標になります。
シザースタックを直接使う場合は座標変換がめんどくさいのでScene2Dを使う場合はこちらを使うのが良いでしょう。また、こちらはオブジェクトプーリングされていますので上のようなサンプルコードと違い、Rectangleが使いまわされるためGC負荷が上がりません。できるだけこちらをつかいましょう。
また、Scene2Dに限りませんが、Scene2Dで特に発覚しやすいのが描画タイミングです。あくまでも描画をする時にシザーテストが行われます。batch.draw()等を呼び出しただけではまだ描画されていません。flushやendなどをシザーテストの開始前と描画後に入れるようにしましょう。