package com.indignado.logicbricks.systems;
import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Engine;
import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.Family;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.indignado.logicbricks.components.ViewsComponent;
import com.indignado.logicbricks.config.Settings;
import com.indignado.logicbricks.core.data.ParticleEffectView;
import com.indignado.logicbricks.core.data.TextureView;
import com.indignado.logicbricks.core.data.View;
import com.indignado.logicbricks.utils.Log;
import java.util.Comparator;
/**
* @author Rubentxu
*/
public class RenderingSystem extends LogicBrickSystem {
private World physics;
protected Viewport viewport;
protected OrthographicCamera uiCamera;
private Batch batch;
private Camera camera;
private Array<View> renderQueue;
private Comparator<View> comparator;
private ComponentMapper<ViewsComponent> vm;
private TiledMap map;
private OrthogonalTiledMapRenderer mapRenderer;
// Debug
private ShapeRenderer debugShapeRenderer;
private Box2DDebugRenderer debugRenderer;
private BitmapFont debugFont;
public RenderingSystem() {
super(Family.all(ViewsComponent.class).get(), 5);
vm = ComponentMapper.getFor(ViewsComponent.class);
setProcessing(false);
renderQueue = new Array<View>();
comparator = new Comparator<View>() {
@Override
public int compare(View viewA, View viewB) {
return (int) Math.signum(viewA.layer - viewB.layer);
}
};
if (Settings.DRAW_GRID) {
this.debugShapeRenderer = new ShapeRenderer();
}
if (Settings.DEBUG && !Settings.TESTING) {
this.debugRenderer = new Box2DDebugRenderer(Settings.DRAW_BOX2D_BODIES, Settings.DRAW_BOX2D_JOINTS, Settings.DRAW_BOX2D_ABBs,
Settings.DRAW_BOX2D_INACTIVE_BODIES, Settings.DRAW_BOX2D_VELOCITIES, Settings.DRAW_BOX2D_CONTACTS);
debugRenderer.setDrawAABBs(Settings.DRAW_BOX2D_ABBs);
debugRenderer.setDrawBodies(Settings.DRAW_BOX2D_BODIES);
debugRenderer.setDrawContacts(Settings.DRAW_BOX2D_CONTACTS);
debugRenderer.setDrawInactiveBodies(Settings.DRAW_BOX2D_INACTIVE_BODIES);
debugRenderer.setDrawJoints(Settings.DRAW_BOX2D_JOINTS);
debugRenderer.setDrawVelocities(Settings.DRAW_BOX2D_VELOCITIES);
debugFont = new BitmapFont();
debugFont.setUseIntegerPositions(false);
debugFont.getData().setScale(0.1f);
uiCamera = new OrthographicCamera();
}
}
@Override
public void addedToEngine(Engine engine) {
super.addedToEngine(engine);
batch = context.get(Batch.class);
camera = context.get(Camera.class);
camera.position.set(Settings.WIDTH / 2, Settings.HEIGHT / 2, 0);
physics = context.get(World.class);
}
@Override
public void update(float deltaTime) {
super.update(deltaTime);
renderQueue.sort(comparator);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
for (View view : renderQueue) {
if (view.tint != null) {
batch.setColor(view.tint);
} else {
batch.setColor(Color.WHITE);
}
batch.getColor().a = view.opacity;
if (view instanceof ParticleEffectView) {
ParticleEffect effect = ((ParticleEffectView) view).effect;
effect.setPosition(view.position.x, view.position.y);
effect.update(deltaTime);
if (((ParticleEffectView) view).autoStart) {
effect.start();
((ParticleEffectView) view).autoStart = false;
}
effect.draw(batch);
} else if (TextureView.class.isAssignableFrom(view.getClass())) {
TextureView textureView = (TextureView) view;
if(textureView.textureRegion != null) {
processTextureFlip(textureView);
float originX = textureView.width * 0.5f;
float originY = textureView.height * 0.5f;
batch.draw(textureView.textureRegion, textureView.position.x - originX, textureView.position.y - originY,
originX, originY, textureView.width, textureView.height, 1, 1, textureView.rotation);
}
// Gdx.app.log("RederingSystem", "texture width " + textureView.width + " height " + textureView.height
// + " texture position " + textureView.position);
}
}
debugDrawUI();
batch.end();
renderQueue.clear();
debugDrawWorld();
}
protected void debugDrawWorld() {
if (Settings.DEBUG && !Settings.TESTING) {
if (Settings.DRAW_GRID) {
// Debug shapes
debugShapeRenderer.setProjectionMatrix(camera.combined);
debugShapeRenderer.setColor(1.0f, 0.0f, 0.0f, 1.0f);
debugShapeRenderer.begin(ShapeRenderer.ShapeType.Line);
debugShapeRenderer.line(-Settings.WIDTH * 0.5f, 0.0f, Settings.WIDTH * 0.5f, 0.0f);
debugShapeRenderer.line(0.0f, -Settings.HEIGHT * 0.5f, 0.0f, Settings.HEIGHT * 0.5f);
debugShapeRenderer.setColor(0.0f, 1.0f, 0.0f, 1.0f);
for (int i = -100; i <= 100; ++i) {
if (i == 0)
continue;
debugShapeRenderer.line(-Settings.WIDTH * 0.5f, i, Settings.WIDTH * 0.5f, i);
}
for (int i = -100; i <= 100; ++i) {
if (i == 0)
continue;
debugShapeRenderer.line(i, -Settings.HEIGHT * 0.5f, i, Settings.HEIGHT * 0.5f);
}
debugShapeRenderer.end();
}
debugRenderer.render(physics, camera.combined);
}
}
protected void debugDrawUI() {
if (Settings.DEBUG && !Settings.TESTING) {
if (Settings.DRAW_FPS) {
String fpsText = String.format("%d FPS", Gdx.graphics.getFramesPerSecond());
debugFont.setColor(1.0f, 1.0f, 1.0f, 1.0f);
debugFont.draw(batch, fpsText, Settings.drawFPSPosX, Settings.drawFPSPosY);
}
}
}
private void processTextureFlip(TextureView view) {
if ((view.flipX && !view.textureRegion.isFlipX()) || (!view.flipX && view.textureRegion.isFlipX())) {
float temp = view.textureRegion.getU();
view.textureRegion.setU(view.textureRegion.getU2());
view.textureRegion.setU2(temp);
}
if ((view.flipY && !view.textureRegion.isFlipY()) || (!view.flipY && view.textureRegion.isFlipY())) {
float temp = view.textureRegion.getV();
view.textureRegion.setV(view.textureRegion.getV2());
view.textureRegion.setV2(temp);
}
}
@Override
public void processEntity(Entity entity, float deltaTime) {
if (Settings.DEBUG_ENTITY != null) tag = Log.tagEntity(this.getClass().getSimpleName(), entity);
for (Object view : entity.getComponent(ViewsComponent.class).views) {
renderQueue.add((View) view);
}
}
public Camera getCamera() {
return camera;
}
}