/******************************************************************************* * Copyright 2011 See AUTHORS file. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.badlogic.gdx.tests; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.InputAdapter; import com.badlogic.gdx.InputMultiplexer; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.g2d.ParticleEffect; import com.badlogic.gdx.graphics.g2d.ParticleEffectPool; import com.badlogic.gdx.graphics.g2d.ParticleEffectPool.PooledEffect; import com.badlogic.gdx.graphics.g2d.ParticleEmitter; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Button; import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.badlogic.gdx.tests.utils.GdxTest; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.viewport.ExtendViewport; public class ParticleEmittersTest extends GdxTest { private SpriteBatch spriteBatch; ParticleEffect effect; ParticleEffectPool effectPool; Array<PooledEffect> effects = new Array(); PooledEffect latestEffect; float fpsCounter; Stage ui; CheckBox skipCleanup; Button clearEmitters; Label logLabel; @Override public void create () { spriteBatch = new SpriteBatch(); effect = new ParticleEffect(); effect.load(Gdx.files.internal("data/singleTextureAllAdditive.p"), Gdx.files.internal("data")); effect.setPosition(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2); effectPool = new ParticleEffectPool(effect, 20, 20); setupUI(); InputProcessor inputProcessor = new InputAdapter() { public boolean touchDragged (int x, int y, int pointer) { if (latestEffect != null) latestEffect.setPosition(x, Gdx.graphics.getHeight() - y); return false; } public boolean touchDown (int x, int y, int pointer, int newParam) { latestEffect = effectPool.obtain(); latestEffect.setEmittersCleanUpBlendFunction(!skipCleanup.isChecked()); latestEffect.setPosition(x, Gdx.graphics.getHeight() - y); effects.add(latestEffect); return false; } }; InputMultiplexer multiplexer = new InputMultiplexer(); multiplexer.addProcessor(ui); multiplexer.addProcessor(inputProcessor); Gdx.input.setInputProcessor(multiplexer); } @Override public void dispose () { spriteBatch.dispose(); effect.dispose(); } @Override public void resize (int width, int height) { ui.getViewport().update(width, height); } public void render () { ui.act(); spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); float delta = Gdx.graphics.getDeltaTime(); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); spriteBatch.begin(); for (ParticleEffect e : effects) e.draw(spriteBatch, delta); spriteBatch.end(); fpsCounter += delta; if (fpsCounter > 3) { fpsCounter = 0; String log = effects.size + " particle effects, FPS: " + Gdx.graphics.getFramesPerSecond() + ", Render calls: " + spriteBatch.renderCalls; Gdx.app.log("libgdx", log); logLabel.setText(log); } ui.draw(); } public boolean needsGL20 () { return false; } private void setupUI () { ui = new Stage(new ExtendViewport(640, 480)); Skin skin = new Skin(Gdx.files.internal("data/uiskin.json")); skipCleanup = new CheckBox("Skip blend function clean-up", skin); skipCleanup.setTransform(false); skipCleanup.addListener(listener); logLabel = new Label("", skin.get(LabelStyle.class)); clearEmitters = new TextButton("Clear screen", skin); clearEmitters.setTransform(false); clearEmitters.addListener(listener); Table table = new Table(); table.setTransform(false); table.setFillParent(true); table.defaults().padTop(5).left(); table.top().left().padLeft(5); table.add(skipCleanup).row(); table.add(clearEmitters).row(); table.add(logLabel); ui.addActor(table); } void updateSkipCleanupState () { for (ParticleEffect eff : effects) { for (ParticleEmitter e : eff.getEmitters()) e.setCleansUpBlendFunction(!skipCleanup.isChecked()); } } ChangeListener listener = new ChangeListener() { @Override public void changed (ChangeEvent event, Actor actor) { if (actor == skipCleanup) { updateSkipCleanupState(); } else if (actor == clearEmitters) { for (PooledEffect e : effects) e.free(); effects.clear(); } } }; }