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.geom.Vector2f; import loon.opengl.BlendState; import loon.opengl.GLEx; public class TMXIsometricMapRenderer extends TMXMapRenderer { private Vector2f tempVector = new Vector2f(); public TMXIsometricMapRenderer(TMXMap map) { super(map); } private Vector2f orthoToIso(float x, float y) { tempVector.x = (x - y) * map.getTileWidth() / 2 + _location.x; tempVector.y = (x + y) * map.getTileHeight() / 2 + _location.y; return tempVector.addSelf(map.getWidth() * map.getTileWidth() / 2, 0); } @Override 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 current = textureMap.get(imageLayer.getImage().getSource()); float tileWidth = map.getTileWidth(); float tileHeight = map.getTileHeight(); float posX = (imageLayer.getY() * tileWidth / 2) + (imageLayer.getX() * tileWidth / 2) + _location.x; float posY = (imageLayer.getX() * tileHeight / 2) - (imageLayer.getY() * tileHeight / 2) + _location.y; g.draw(current, posX, posY, imageLayer.getWidth() * map.getTileWidth(), imageLayer.getHeight() * map.getTileHeight(), baseColor); baseColor.a = tmpAlpha; } @Override 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(); float windowWidth = LSystem.viewSize.getWidth() / map.getTileWidth() * 2f; float windowHeight = LSystem.viewSize.getHeight() / map.getTileHeight() * 2f; float doubleWidth = tileLayer.getWidth() * 2f; float doubleHeight = tileLayer.getHeight() * 2f; 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 >= doubleWidth) || (ty + y >= doubleHeight)) { continue; } if ((tx + x >= windowWidth) || (ty + 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 = tileSet.getTileWidth(); float tileHeight = tileSet.getTileHeight(); 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.5f / tileSet.getImage() .getWidth()); float uvCorrectionY = (0.5f / tileSet.getImage() .getHeight()); if (_rotation != 0f || scaleX != 1f || scaleY != 1f) { if (_rotation != 0f) { batch.glVertex2f(orthoToIso(x, y).addSelf( -tileWidth / 2, 0).newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, yOff + uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(flipZ ? tileWidth : 0, flipZ ? 0 : tileHeight) .newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(tileWidth, tileHeight) .newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(flipZ ? 0 : tileWidth, flipZ ? tileHeight : 0) .newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, yOff + uvCorrectionY); } else if (scaleX != 1f || srcY != 1f) { batch.glVertex2f(orthoToIso(x, y).addSelf( -tileWidth / 2, 0).mul(scaleX, scaleY)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, yOff + uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(flipZ ? tileWidth : 0, flipZ ? 0 : tileHeight) .mul(scaleX, scaleY)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(tileWidth, tileHeight) .mul(scaleX, scaleY)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(flipZ ? 0 : tileWidth, flipZ ? tileHeight : 0) .mul(scaleX, scaleY)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, yOff + uvCorrectionY); } else { batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .mul(scaleX, scaleY) .newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, yOff + uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(flipZ ? tileWidth : 0, flipZ ? 0 : tileHeight) .mul(scaleX, scaleY) .newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(tileWidth, tileHeight) .mul(scaleX, scaleY) .newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y) .addSelf(-tileWidth / 2, 0) .addSelf(flipZ ? 0 : tileWidth, flipZ ? tileHeight : 0) .mul(scaleX, scaleY) .newRotate(_rotation)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, yOff + uvCorrectionY); } } else { batch.glVertex2f(orthoToIso(x, y).addSelf( -tileWidth / 2, 0)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, yOff + uvCorrectionY); batch.glVertex2f(orthoToIso(x, y).addSelf( -tileWidth / 2, 0).addSelf( flipZ ? tileWidth : 0, flipZ ? 0 : tileHeight)); batch.glColor4f(); batch.glTexCoord2f(xOff + uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y).addSelf( -tileWidth / 2, 0).addSelf(tileWidth, tileHeight)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, heightRatio - uvCorrectionY); batch.glVertex2f(orthoToIso(x, y).addSelf( -tileWidth / 2, 0).addSelf( flipZ ? 0 : tileWidth, flipZ ? tileHeight : 0)); batch.glColor4f(); batch.glTexCoord2f(widthRatio - uvCorrectionX, yOff + uvCorrectionY); } } } } finally { if (!cache) { batch.end(); if (onlyTexture) { batch.newCache(); } } baseColor.a = tmpAlpha; } } } }