1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tests; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.Input; 21 import com.badlogic.gdx.InputAdapter; 22 import com.badlogic.gdx.InputMultiplexer; 23 import com.badlogic.gdx.InputProcessor; 24 import com.badlogic.gdx.graphics.GL20; 25 import com.badlogic.gdx.graphics.g2d.ParticleEffect; 26 import com.badlogic.gdx.graphics.g2d.ParticleEffectPool; 27 import com.badlogic.gdx.graphics.g2d.ParticleEffectPool.PooledEffect; 28 import com.badlogic.gdx.graphics.g2d.ParticleEmitter; 29 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 30 import com.badlogic.gdx.scenes.scene2d.Actor; 31 import com.badlogic.gdx.scenes.scene2d.Stage; 32 import com.badlogic.gdx.scenes.scene2d.ui.Button; 33 import com.badlogic.gdx.scenes.scene2d.ui.CheckBox; 34 import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle; 35 import com.badlogic.gdx.scenes.scene2d.ui.Label; 36 import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; 37 import com.badlogic.gdx.scenes.scene2d.ui.Skin; 38 import com.badlogic.gdx.scenes.scene2d.ui.Table; 39 import com.badlogic.gdx.scenes.scene2d.ui.TextButton; 40 import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; 41 import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; 42 import com.badlogic.gdx.tests.utils.GdxTest; 43 import com.badlogic.gdx.utils.Array; 44 import com.badlogic.gdx.utils.viewport.ExtendViewport; 45 46 public class ParticleEmittersTest extends GdxTest { 47 private SpriteBatch spriteBatch; 48 ParticleEffect effect; 49 ParticleEffectPool effectPool; 50 Array<PooledEffect> effects = new Array(); 51 PooledEffect latestEffect; 52 float fpsCounter; 53 Stage ui; 54 CheckBox skipCleanup; 55 Button clearEmitters; 56 Label logLabel; 57 58 @Override create()59 public void create () { 60 spriteBatch = new SpriteBatch(); 61 62 effect = new ParticleEffect(); 63 effect.load(Gdx.files.internal("data/singleTextureAllAdditive.p"), Gdx.files.internal("data")); 64 effect.setPosition(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2); 65 effectPool = new ParticleEffectPool(effect, 20, 20); 66 67 setupUI(); 68 69 InputProcessor inputProcessor = new InputAdapter() { 70 71 public boolean touchDragged (int x, int y, int pointer) { 72 if (latestEffect != null) latestEffect.setPosition(x, Gdx.graphics.getHeight() - y); 73 return false; 74 } 75 76 public boolean touchDown (int x, int y, int pointer, int newParam) { 77 latestEffect = effectPool.obtain(); 78 latestEffect.setEmittersCleanUpBlendFunction(!skipCleanup.isChecked()); 79 latestEffect.setPosition(x, Gdx.graphics.getHeight() - y); 80 effects.add(latestEffect); 81 82 return false; 83 } 84 85 }; 86 87 InputMultiplexer multiplexer = new InputMultiplexer(); 88 multiplexer.addProcessor(ui); 89 multiplexer.addProcessor(inputProcessor); 90 91 Gdx.input.setInputProcessor(multiplexer); 92 } 93 94 @Override dispose()95 public void dispose () { 96 spriteBatch.dispose(); 97 effect.dispose(); 98 } 99 100 @Override resize(int width, int height)101 public void resize (int width, int height) { 102 ui.getViewport().update(width, height); 103 } 104 render()105 public void render () { 106 ui.act(); 107 spriteBatch.getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 108 float delta = Gdx.graphics.getDeltaTime(); 109 Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 110 spriteBatch.begin(); 111 for (ParticleEffect e : effects) 112 e.draw(spriteBatch, delta); 113 spriteBatch.end(); 114 fpsCounter += delta; 115 if (fpsCounter > 3) { 116 fpsCounter = 0; 117 String log = effects.size + " particle effects, FPS: " + Gdx.graphics.getFramesPerSecond() + ", Render calls: " 118 + spriteBatch.renderCalls; 119 Gdx.app.log("libgdx", log); 120 logLabel.setText(log); 121 } 122 ui.draw(); 123 } 124 needsGL20()125 public boolean needsGL20 () { 126 return false; 127 } 128 setupUI()129 private void setupUI () { 130 ui = new Stage(new ExtendViewport(640, 480)); 131 Skin skin = new Skin(Gdx.files.internal("data/uiskin.json")); 132 skipCleanup = new CheckBox("Skip blend function clean-up", skin); 133 skipCleanup.setTransform(false); 134 skipCleanup.addListener(listener); 135 logLabel = new Label("", skin.get(LabelStyle.class)); 136 clearEmitters = new TextButton("Clear screen", skin); 137 clearEmitters.setTransform(false); 138 clearEmitters.addListener(listener); 139 Table table = new Table(); 140 table.setTransform(false); 141 table.setFillParent(true); 142 table.defaults().padTop(5).left(); 143 table.top().left().padLeft(5); 144 table.add(skipCleanup).row(); 145 table.add(clearEmitters).row(); 146 table.add(logLabel); 147 ui.addActor(table); 148 } 149 updateSkipCleanupState()150 void updateSkipCleanupState () { 151 for (ParticleEffect eff : effects) { 152 for (ParticleEmitter e : eff.getEmitters()) 153 e.setCleansUpBlendFunction(!skipCleanup.isChecked()); 154 } 155 } 156 157 ChangeListener listener = new ChangeListener() { 158 159 @Override 160 public void changed (ChangeEvent event, Actor actor) { 161 if (actor == skipCleanup) { 162 updateSkipCleanupState(); 163 } else if (actor == clearEmitters) { 164 for (PooledEffect e : effects) 165 e.free(); 166 effects.clear(); 167 } 168 } 169 }; 170 } 171