package loon.action.map.tmx.renderers;
import loon.LSystem;
import loon.LTexture;
import loon.LTextureBatch;
import loon.action.map.tmx.TMXImageLayer;
import loon.action.map.tmx.TMXMap;
import loon.action.map.tmx.TMXTileLayer;
import loon.action.map.tmx.TMXTileSet;
import loon.action.map.tmx.tiles.TMXMapTile;
import loon.action.map.tmx.tiles.TMXTile;
import loon.opengl.BlendState;
import loon.opengl.GLEx;
import loon.utils.MathUtils;
public class TMXOrthogonalMapRenderer extends TMXMapRenderer {
public TMXOrthogonalMapRenderer(TMXMap map) {
super(map);
}
protected void renderImageLayer(GLEx g, TMXImageLayer imageLayer) {
if (!imageLayer.isVisible()) {
return;
}
float opacity = imageLayer.getOpacity();
if (opacity <= 0f) {
return;
}
if (opacity > 1f) {
opacity = 1f;
}
float tmpAlpha = baseColor.a;
baseColor.a *= opacity;
LTexture originalTexture = textureMap.get(imageLayer.getImage()
.getSource());
g.draw(originalTexture, imageLayer.getX(), imageLayer.getY(),
imageLayer.getWidth() * map.getTileWidth(),
imageLayer.getHeight() * map.getTileHeight(), baseColor);
baseColor.a = tmpAlpha;
}
protected void renderTileLayer(GLEx g, TMXTileLayer tileLayer) {
synchronized (this) {
if (!tileLayer.isVisible()) {
return;
}
float opacity = tileLayer.getOpacity();
if (opacity <= 0f) {
return;
}
if (opacity > 1f) {
opacity = 1f;
}
int tx = _location.x() / map.getTileWidth();
int ty = _location.y() / map.getTileHeight();
int windowWidth = (int) (LSystem.viewSize.getWidth()
/ map.getTileWidth() / scaleX);
int windowHeight = (int) (LSystem.viewSize.getHeight()
/ map.getTileHeight() / scaleY);
boolean onlyTexture = textureMap.size == 1;
LTexture current = textureMap.get(map.getTileset(0).getImage()
.getSource());
LTextureBatch batch = current.getTextureBatch();
float tmpAlpha = baseColor.a;
boolean cache = false;
baseColor.a *= opacity;
try {
if (onlyTexture) {
int hashCode = 1;
hashCode = LSystem.unite(hashCode, tx);
hashCode = LSystem.unite(hashCode, ty);
hashCode = LSystem.unite(hashCode, windowWidth);
hashCode = LSystem.unite(hashCode, windowHeight);
hashCode = LSystem.unite(hashCode, scaleX);
hashCode = LSystem.unite(hashCode, scaleY);
hashCode = LSystem.unite(hashCode, _rotation);
if (hashCode != lastHashCode) {
lastHashCode = hashCode;
batch.disposeLastCache();
batch.begin();
} else {
if (batch.existCache()) {
batch.setBlendState(BlendState.AlphaBlend);
batch.postCache(baseColor, 0);
cache = true;
return;
} else {
batch.begin();
}
}
} else {
batch.begin();
}
batch.setBlendState(BlendState.AlphaBlend);
batch.setColor(baseColor);
for (int x = 0; x < tileLayer.getWidth(); x++) {
for (int y = 0; y < tileLayer.getHeight(); y++) {
if ((tx + x < 0) || (ty + y < 0)) {
continue;
}
if ((tx + x >= tileLayer.getWidth())
|| (ty + y >= tileLayer.getHeight())) {
continue;
}
if ((x >= windowWidth) || (y >= windowHeight)) {
continue;
}
TMXMapTile mapTile = tileLayer.getTile(x, y);
if (mapTile.getTileSetID() == -1) {
continue;
}
TMXTileSet tileSet = map.getTileset(mapTile
.getTileSetID());
TMXTile tile = tileSet.getTile(mapTile.getGID()
- tileSet.getFirstGID());
LTexture texture = textureMap.get(tileSet.getImage()
.getSource());
if (texture.getID() != current.getID()) {
batch.end();
current = texture;
batch = current.getTextureBatch();
batch.begin();
batch.setBlendState(BlendState.AlphaBlend);
batch.checkTexture(current);
}
int tileID = mapTile.getGID() - tileSet.getFirstGID();
if (tile != null && tile.isAnimated()) {
tileID = tileAnimators.get(tile).getCurrentFrame()
.getTileID();
}
int numColsPerRow = tileSet.getImage().getWidth()
/ tileSet.getTileWidth();
int tileSetCol = tileID % numColsPerRow;
int tileSetRow = tileID / numColsPerRow;
float tileWidth = map.getTileWidth();
float tileHeight = map.getTileHeight();
float posX = (x * tileWidth + _location.x) * scaleX;
float posY = (y * tileHeight + _location.y) * scaleY;
float srcX = (tileSet.getMargin() + (tileSet
.getTileWidth() + tileSet.getSpacing())
* tileSetCol);
float srcY = (tileSet.getMargin() + (tileSet
.getTileHeight() + tileSet.getSpacing())
* tileSetRow);
float srcWidth = srcX + tileWidth;
float srcHeight = srcY + tileHeight;
float xOff = srcX * batch.getInvTexWidth()
+ texture.xOff;
float widthRatio = srcWidth * batch.getInvTexWidth();
float yOff = srcY * batch.getInvTexHeight()
+ texture.yOff;
float heightRatio = srcHeight * batch.getInvTexHeight();
boolean flipX = mapTile.isFlippedHorizontally();
boolean flipY = mapTile.isFlippedVertically();
boolean flipZ = mapTile.isFlippedDiagonally();
if (flipZ) {
flipX = !flipX;
flipY = !flipY;
}
if (flipX) {
float temp = xOff;
xOff = widthRatio;
widthRatio = temp;
}
if (flipY) {
float temp = yOff;
yOff = heightRatio;
heightRatio = temp;
}
float uvCorrectionX = (0.2f / tileSet.getImage()
.getWidth());
float uvCorrectionY = (0.2f / tileSet.getImage()
.getHeight());
if (_rotation != 0f || scaleX != 1f || scaleY != 1f) {
float originX = tileWidth / 2;
float originY = tileHeight / 2;
final float worldOriginX = posX + tileWidth / 2;
final float worldOriginY = posY + tileHeight / 2;
float fx = -originX;
float fy = -originY;
float fx2 = tileWidth - originX;
float fy2 = tileHeight - originY;
if (scaleX != 1 || scaleY != 1) {
fx *= scaleX;
fy *= scaleY;
fx2 *= scaleX;
fy2 *= scaleY;
}
final float p1x = fx;
final float p1y = fy;
final float p2x = fx;
final float p2y = fy2;
final float p3x = fx2;
final float p3y = fy2;
final float p4x = fx2;
final float p4y = fy;
float x1;
float y1;
float x2;
float y2;
float x3;
float y3;
float x4;
float y4;
if (_rotation != 0) {
final float cos = MathUtils.cosDeg(_rotation);
final float sin = MathUtils.sinDeg(_rotation);
x1 = cos * p1x - sin * p1y;
y1 = sin * p1x + cos * p1y;
x2 = cos * p2x - sin * p2y;
y2 = sin * p2x + cos * p2y;
x3 = cos * p3x - sin * p3y;
y3 = sin * p3x + cos * p3y;
x4 = x1 + (x3 - x2);
y4 = y3 - (y2 - y1);
} else {
x1 = p1x;
y1 = p1y;
x2 = p2x;
y2 = p2y;
x3 = p3x;
y3 = p3y;
x4 = p4x;
y4 = p4y;
}
x1 += worldOriginX;
y1 += worldOriginY;
x2 += worldOriginX;
y2 += worldOriginY;
x3 += worldOriginX;
y3 += worldOriginY;
x4 += worldOriginX;
y4 += worldOriginY;
if (flipZ) {
x2 += tileWidth;
y2 += tileHeight;
x4 += tileWidth;
y4 += tileHeight;
}
batch.glVertex2f(x1, y1);
batch.glColor4f();
batch.glTexCoord2f(xOff + uvCorrectionX, yOff
+ uvCorrectionY);
batch.glVertex2f(x2, y2);
batch.glColor4f();
batch.glTexCoord2f(xOff + uvCorrectionX,
heightRatio - uvCorrectionY);
batch.glVertex2f(x3, y3);
batch.glColor4f();
batch.glTexCoord2f(widthRatio - uvCorrectionX,
heightRatio - uvCorrectionY);
batch.glVertex2f(x4, y4);
batch.glColor4f();
batch.glTexCoord2f(widthRatio - uvCorrectionX, yOff
+ uvCorrectionY);
} else {
batch.glVertex2f(posX, posY);
batch.glColor4f();
batch.glTexCoord2f(xOff + uvCorrectionX, yOff
+ uvCorrectionY);
batch.glVertex2f(flipZ ? posX + tileWidth : posX,
flipZ ? posY : posY + tileHeight);
batch.glColor4f();
batch.glTexCoord2f(xOff + uvCorrectionX,
heightRatio - uvCorrectionY);
batch.glVertex2f(posX + tileWidth, posY
+ tileHeight);
batch.glColor4f();
batch.glTexCoord2f(widthRatio - uvCorrectionX,
heightRatio - uvCorrectionY);
batch.glVertex2f(flipZ ? posX : posX + tileWidth,
flipZ ? posY + tileHeight : posY);
batch.glColor4f();
batch.glTexCoord2f(widthRatio - uvCorrectionX, yOff
+ uvCorrectionY);
}
}
}
} finally {
if (!cache) {
batch.end();
if (onlyTexture) {
batch.newCache();
}
}
baseColor.a = tmpAlpha;
}
}
}
}