/******************************************************************************* * Copyright 2013 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.maps.tiled.renderers; import static com.badlogic.gdx.graphics.g2d.Batch.C1; import static com.badlogic.gdx.graphics.g2d.Batch.C2; import static com.badlogic.gdx.graphics.g2d.Batch.C3; import static com.badlogic.gdx.graphics.g2d.Batch.C4; import static com.badlogic.gdx.graphics.g2d.Batch.U1; import static com.badlogic.gdx.graphics.g2d.Batch.U2; import static com.badlogic.gdx.graphics.g2d.Batch.U3; import static com.badlogic.gdx.graphics.g2d.Batch.U4; import static com.badlogic.gdx.graphics.g2d.Batch.V1; import static com.badlogic.gdx.graphics.g2d.Batch.V2; import static com.badlogic.gdx.graphics.g2d.Batch.V3; import static com.badlogic.gdx.graphics.g2d.Batch.V4; import static com.badlogic.gdx.graphics.g2d.Batch.X1; import static com.badlogic.gdx.graphics.g2d.Batch.X2; import static com.badlogic.gdx.graphics.g2d.Batch.X3; import static com.badlogic.gdx.graphics.g2d.Batch.X4; import static com.badlogic.gdx.graphics.g2d.Batch.Y1; import static com.badlogic.gdx.graphics.g2d.Batch.Y2; import static com.badlogic.gdx.graphics.g2d.Batch.Y3; import static com.badlogic.gdx.graphics.g2d.Batch.Y4; import com.badlogic.gdx.Gdx; 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.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.maps.MapLayer; import com.badlogic.gdx.maps.MapObject; import com.badlogic.gdx.maps.tiled.TiledMap; import com.badlogic.gdx.maps.tiled.TiledMapImageLayer; import com.badlogic.gdx.maps.tiled.TiledMapRenderer; import com.badlogic.gdx.maps.tiled.TiledMapTileLayer; import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell; import com.badlogic.gdx.maps.tiled.tiles.AnimatedTiledMapTile; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.utils.Disposable; public abstract class BatchTiledMapRenderer implements TiledMapRenderer, Disposable { static protected final int NUM_VERTICES = 20; protected TiledMap map; protected float unitScale; protected Batch batch; protected Rectangle viewBounds; protected Rectangle imageBounds = new Rectangle(); protected boolean ownsBatch; protected float vertices[] = new float[NUM_VERTICES]; public TiledMap getMap () { return map; } public void setMap (TiledMap map) { this.map = map; } public float getUnitScale () { return unitScale; } public Batch getBatch () { return batch; } public Rectangle getViewBounds () { return viewBounds; } public BatchTiledMapRenderer (TiledMap map) { this(map, 1.0f); } public BatchTiledMapRenderer (TiledMap map, float unitScale) { this.map = map; this.unitScale = unitScale; this.viewBounds = new Rectangle(); this.batch = new SpriteBatch(); this.ownsBatch = true; } public BatchTiledMapRenderer (TiledMap map, Batch batch) { this(map, 1.0f, batch); } public BatchTiledMapRenderer (TiledMap map, float unitScale, Batch batch) { this.map = map; this.unitScale = unitScale; this.viewBounds = new Rectangle(); this.batch = batch; this.ownsBatch = false; } @Override public void setView (OrthographicCamera camera) { batch.setProjectionMatrix(camera.combined); float width = camera.viewportWidth * camera.zoom; float height = camera.viewportHeight * camera.zoom; float w = width * Math.abs(camera.up.y) + height * Math.abs(camera.up.x); float h = height * Math.abs(camera.up.y) + width * Math.abs(camera.up.x); viewBounds.set(camera.position.x - w / 2, camera.position.y - h / 2, w, h); } @Override public void setView (Matrix4 projection, float x, float y, float width, float height) { batch.setProjectionMatrix(projection); viewBounds.set(x, y, width, height); } @Override public void render () { beginRender(); for (MapLayer layer : map.getLayers()) { if (layer.isVisible()) { if (layer instanceof TiledMapTileLayer) { renderTileLayer((TiledMapTileLayer)layer); } else if (layer instanceof TiledMapImageLayer) { renderImageLayer((TiledMapImageLayer)layer); } else { renderObjects(layer); } } } endRender(); } @Override public void render (int[] layers) { beginRender(); for (int layerIdx : layers) { MapLayer layer = map.getLayers().get(layerIdx); if (layer.isVisible()) { if (layer instanceof TiledMapTileLayer) { renderTileLayer((TiledMapTileLayer)layer); } else if (layer instanceof TiledMapImageLayer) { renderImageLayer((TiledMapImageLayer)layer); } else { renderObjects(layer); } } } endRender(); } @Override public void renderObjects(MapLayer layer) { for (MapObject object : layer.getObjects()) { renderObject(object); } } @Override public void renderObject(MapObject object) { } @Override public void renderImageLayer(TiledMapImageLayer layer) { final Color batchColor = batch.getColor(); final float color = Color.toFloatBits(batchColor.r, batchColor.g, batchColor.b, batchColor.a * layer.getOpacity()); final float[] vertices = this.vertices; TextureRegion region = layer.getTextureRegion(); if (region == null) { return; } final float x = layer.getX(); final float y = layer.getY(); final float x1 = x * unitScale; final float y1 = y * unitScale; final float x2 = x1 + region.getRegionWidth() * unitScale; final float y2 = y1 + region.getRegionHeight() * unitScale; imageBounds.set(x1, y1, x2 - x1, y2 - y1); if (viewBounds.contains(imageBounds) || viewBounds.overlaps(imageBounds)) { final float u1 = region.getU(); final float v1 = region.getV2(); final float u2 = region.getU2(); final float v2 = region.getV(); vertices[X1] = x1; vertices[Y1] = y1; vertices[C1] = color; vertices[U1] = u1; vertices[V1] = v1; vertices[X2] = x1; vertices[Y2] = y2; vertices[C2] = color; vertices[U2] = u1; vertices[V2] = v2; vertices[X3] = x2; vertices[Y3] = y2; vertices[C3] = color; vertices[U3] = u2; vertices[V3] = v2; vertices[X4] = x2; vertices[Y4] = y1; vertices[C4] = color; vertices[U4] = u2; vertices[V4] = v1; batch.draw(region.getTexture(), vertices, 0, NUM_VERTICES); } } /** Called before the rendering of all layers starts. */ protected void beginRender () { AnimatedTiledMapTile.updateAnimationBaseTime(); batch.begin(); } /** Called after the rendering of all layers ended. */ protected void endRender () { batch.end(); } @Override public void dispose () { if (ownsBatch) { batch.dispose(); } } }