diff --git a/core/assets/sprites/sprites.atlas b/core/assets/sprites/sprites.atlas index 04956cf196..64e91aa95f 100644 --- a/core/assets/sprites/sprites.atlas +++ b/core/assets/sprites/sprites.atlas @@ -6,7 +6,7 @@ filter: Nearest,Nearest repeat: none force-projector-top rotate: false - xy: 691, 1145 + xy: 593, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -321,7 +321,7 @@ junction index: -1 mass-driver-turret rotate: false - xy: 907, 920 + xy: 1103, 1018 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -347,6 +347,13 @@ phase-conveyor-end orig: 32, 32 offset: 0, 0 index: -1 +warp-gate + rotate: false + xy: 1295, 1559 + size: 96, 96 + orig: 96, 96 + offset: 0, 0 + index: -1 warp-gate-top rotate: false xy: 1393, 1657 @@ -426,28 +433,28 @@ mechanical-drill-top index: -1 oil-extractor rotate: false - xy: 1005, 920 + xy: 907, 920 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 oil-extractor-liquid rotate: false - xy: 1103, 920 + xy: 1005, 920 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 oil-extractor-rotator rotate: false - xy: 1197, 1755 + xy: 1103, 920 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 oil-extractor-top rotate: false - xy: 1197, 1657 + xy: 1197, 1755 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -1140,7 +1147,7 @@ cross-2 index: -1 cross-3 rotate: false - xy: 495, 1145 + xy: 397, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -1203,14 +1210,14 @@ rubble-2-1 index: -1 rubble-3-0 rotate: false - xy: 1295, 1657 + xy: 1197, 1559 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 rubble-3-1 rotate: false - xy: 1295, 1657 + xy: 1197, 1559 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -1462,21 +1469,21 @@ liquid-router-top index: -1 liquid-tank-bottom rotate: false - xy: 907, 1018 + xy: 809, 978 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 liquid-tank-liquid rotate: false - xy: 1005, 1018 + xy: 907, 1018 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 liquid-tank-top rotate: false - xy: 1103, 1018 + xy: 1005, 1018 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -1693,14 +1700,14 @@ rtg-generator-top index: -1 thorium-reactor-center rotate: false - xy: 1393, 1755 + xy: 1295, 1657 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 thorium-reactor-lights rotate: false - xy: 1197, 1461 + xy: 1393, 1755 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -1938,14 +1945,14 @@ separator-liquid index: -1 core-open rotate: false - xy: 1923, 1853 + xy: 1825, 1853 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 core-top rotate: false - xy: 397, 1145 + xy: 1923, 1853 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -2029,7 +2036,7 @@ arc-heat index: -1 cyclone rotate: false - xy: 593, 1145 + xy: 495, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -2043,7 +2050,7 @@ duo index: -1 fuse rotate: false - xy: 809, 1076 + xy: 711, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -2092,14 +2099,14 @@ meltdown-heat index: -1 ripple rotate: false - xy: 1295, 1755 + xy: 1197, 1657 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ripple-heat rotate: false - xy: 1197, 1559 + xy: 1295, 1755 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -2197,56 +2204,56 @@ dagger-factory-top-open index: -1 fortress-factory rotate: false - xy: 515, 1047 + xy: 691, 1145 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fortress-factory-top rotate: false - xy: 613, 1047 + xy: 515, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory-top rotate: false - xy: 613, 1047 + xy: 515, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 titan-factory-top rotate: false - xy: 613, 1047 + xy: 515, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 fortress-factory-top-open rotate: false - xy: 711, 1047 + xy: 613, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory-top-open rotate: false - xy: 711, 1047 + xy: 613, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 titan-factory-top-open rotate: false - xy: 711, 1047 + xy: 613, 1047 size: 96, 96 orig: 96, 96 offset: 0, 0 index: -1 ghoul-factory rotate: false - xy: 809, 978 + xy: 809, 1076 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -2316,7 +2323,7 @@ spirit-factory-top-open index: -1 titan-factory rotate: false - xy: 1295, 1559 + xy: 1197, 1461 size: 96, 96 orig: 96, 96 offset: 0, 0 @@ -4015,20 +4022,6 @@ vault orig: 96, 96 offset: 0, 0 index: -1 -block-icon-warp-gate - rotate: false - xy: 1825, 1853 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 -warp-gate - rotate: false - xy: 1825, 1853 - size: 96, 96 - orig: 96, 96 - offset: 0, 0 - index: -1 block-icon-water rotate: false xy: 613, 939 diff --git a/core/assets/sprites/sprites.png b/core/assets/sprites/sprites.png index f5eb799e32..40ce7615ca 100644 Binary files a/core/assets/sprites/sprites.png and b/core/assets/sprites/sprites.png differ diff --git a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java index 5d05ebf119..2d52696f33 100644 --- a/core/src/io/anuke/mindustry/graphics/FloorRenderer.java +++ b/core/src/io/anuke/mindustry/graphics/FloorRenderer.java @@ -2,39 +2,46 @@ package io.anuke.mindustry.graphics; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; -import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.OrthographicCamera; -import com.badlogic.gdx.graphics.VertexAttribute; -import com.badlogic.gdx.graphics.VertexAttributes.Usage; -import com.badlogic.gdx.graphics.g2d.TextureRegion; -import com.badlogic.gdx.graphics.glutils.ShaderProgram; +import com.badlogic.gdx.utils.IntArray; +import com.badlogic.gdx.utils.IntSet; +import com.badlogic.gdx.utils.IntSet.IntSetIterator; +import com.badlogic.gdx.utils.ObjectSet; import io.anuke.mindustry.game.EventType.WorldLoadGraphicsEvent; import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.Floor; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Events; +import io.anuke.ucore.core.Graphics; import io.anuke.ucore.core.Timers; +import io.anuke.ucore.graphics.CacheBatch; +import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Log; import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Structs; -import static io.anuke.mindustry.Vars.tilesize; -import static io.anuke.mindustry.Vars.world; +import java.util.Arrays; +import static io.anuke.mindustry.Vars.*; + +//TODO point shader mesh public class FloorRenderer{ - private final static int chunksize = 32; - private final static int vertexSize = 6; - private float[] vertices = new float[vertexSize]; - private Chunk[][] chunks; - private ShaderProgram shader = createDefaultShader(); - private Mesh mesh; + private final static int chunksize = 64; + + private Chunk[][] cache; + private CacheBatch cbatch; + private IntSet drawnLayerSet = new IntSet(); + private IntArray drawnLayers = new IntArray(); public FloorRenderer(){ Events.on(WorldLoadGraphicsEvent.class, event -> clearTiles()); } - /**Draws all the floor tiles in the camera range.*/ public void drawFloor(){ + if(cache == null){ + return; + } + OrthographicCamera camera = Core.camera; int crangex = (int) (camera.viewportWidth * camera.zoom / (chunksize * tilesize)) + 1; @@ -43,121 +50,175 @@ public class FloorRenderer{ int camx = Mathf.scl(camera.position.x, chunksize * tilesize); int camy = Mathf.scl(camera.position.y, chunksize * tilesize); - Gdx.gl.glEnable(GL20.GL_VERTEX_PROGRAM_POINT_SIZE); - Gdx.gl.glEnable( 0x8861); - Core.atlas.getTextures().first().bind(0); - shader.begin(); - shader.setUniformMatrix("u_projectionViewMatrix", Core.camera.combined); - shader.setUniformi("u_texture", 0); + int layers = CacheLayer.values().length; + drawnLayers.clear(); + drawnLayerSet.clear(); + + //preliminary layer check for(int x = -crangex; x <= crangex; x++){ for(int y = -crangey; y <= crangey; y++){ int worldx = camx + x; int worldy = camy + y; - if(!Structs.inBounds(worldx, worldy, chunks)) + if(!Structs.inBounds(worldx, worldy, cache)) continue; - Chunk chunk = chunks[worldx][worldy]; - mesh.render(shader, GL20.GL_POINTS, chunk.start / vertexSize, chunk.end / vertexSize); + Chunk chunk = cache[worldx][worldy]; + + //loop through all layers, and add layer index if it exists + for(int i = 0; i < layers; i++){ + if(chunk.caches[i] != -1){ + drawnLayerSet.add(i); + } + } } } - shader.end(); - } - - /**Clears the mesh and renders the entire world to it.*/ - public void clearTiles(){ - if(mesh != null){ - mesh.dispose(); + IntSetIterator it = drawnLayerSet.iterator(); + while(it.hasNext){ + drawnLayers.add(it.next()); } - int size = world.width() * world.height() * vertexSize; + drawnLayers.sort(); - mesh = new Mesh(true, size, 0, - new VertexAttribute(Usage.Position, 2, ShaderProgram.POSITION_ATTRIBUTE), - new VertexAttribute(Usage.TextureCoordinates, 4, ShaderProgram.TEXCOORD_ATTRIBUTE + "0")); + //Graphics.end(); + beginDraw(); - mesh.getVerticesBuffer().position(0); - mesh.getVerticesBuffer().limit(mesh.getMaxVertices()); - cache(); + for(int i = 0; i < drawnLayers.size; i++){ + CacheLayer layer = CacheLayer.values()[drawnLayers.get(i)]; + + drawLayer(layer); + } + + endDraw(); } - private void addSprite(TextureRegion region, float x, float y){ - vertices[0] = x; - vertices[1] = y; - vertices[2] = region.getU(); - vertices[3] = region.getV(); - vertices[4] = region.getU2(); - vertices[5] = region.getV2(); + public void beginDraw(){ + if(cache == null){ + return; + } - mesh.getVerticesBuffer().put(vertices); + cbatch.setProjectionMatrix(Core.camera.combined); + cbatch.beginDraw(); + + Gdx.gl.glEnable(GL20.GL_BLEND); } - private void cache(){ - Timers.mark(); + public void endDraw(){ + if(cache == null){ + return; + } + + cbatch.endDraw(); + } + + public void drawLayer(CacheLayer layer){ + if(cache == null){ + return; + } + + OrthographicCamera camera = Core.camera; + + int crangex = (int) (camera.viewportWidth * camera.zoom / (chunksize * tilesize)) + 1; + int crangey = (int) (camera.viewportHeight * camera.zoom / (chunksize * tilesize)) + 1; + + layer.begin(); + + for(int x = -crangex; x <= crangex; x++){ + for(int y = -crangey; y <= crangey; y++){ + int worldx = Mathf.scl(camera.position.x, chunksize * tilesize) + x; + int worldy = Mathf.scl(camera.position.y, chunksize * tilesize) + y; + + if(!Structs.inBounds(worldx, worldy, cache)){ + continue; + } + + Chunk chunk = cache[worldx][worldy]; + if(chunk.caches[layer.ordinal()] == -1) continue; + cbatch.drawCache(chunk.caches[layer.ordinal()]); + } + } + + layer.end(); + } + + private void cacheChunk(int cx, int cy){ + Chunk chunk = cache[cx][cy]; + + ObjectSet used = new ObjectSet<>(); + + for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ + for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ + Tile tile = world.tile(tilex, tiley); + + if(tile != null){ + used.add(tile.floor().cacheLayer); + } + } + } + + for(CacheLayer layer : used){ + cacheChunkLayer(cx, cy, chunk, layer); + } + } + + private void cacheChunkLayer(int cx, int cy, Chunk chunk, CacheLayer layer){ + + Graphics.useBatch(cbatch); + cbatch.begin(); + + for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){ + for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize; tiley++){ + Tile tile = world.tile(tilex , tiley); + Floor floor; + + if(tile == null){ + continue; + }else{ + floor = tile.floor(); + } + + if(floor.cacheLayer == layer){ + floor.draw(tile); + }else if(floor.cacheLayer.ordinal() < layer.ordinal()){ + floor.drawNonLayer(tile); + } + } + } + + cbatch.end(); + Graphics.popBatch(); + chunk.caches[layer.ordinal()] = cbatch.getLastCache(); + } + + public void clearTiles(){ + if(cbatch != null) cbatch.dispose(); int chunksx = Mathf.ceil((float) (world.width()) / chunksize), - chunksy = Mathf.ceil((float) (world.height()) / chunksize); - chunks = new Chunk[chunksx][chunksy]; + chunksy = Mathf.ceil((float) (world.height()) / chunksize) ; + cache = new Chunk[chunksx][chunksy]; + cbatch = new CacheBatch(world.width() * world.height() * 4 * 4); + + Timers.mark(); + + Draw.scale(scaling); for(int x = 0; x < chunksx; x++){ for(int y = 0; y < chunksy; y++){ - int offset = mesh.getVerticesBuffer().position(); - - for(int cx = x*chunksize; cx < (x + 1) * chunksize && cx < world.width(); cx++){ - for(int cy = y*chunksize; cy < (y + 1) * chunksize && cy < world.height(); cy++){ - Tile tile = world.tile(cx, cy); - - Floor floor = tile.floor(); - TextureRegion region = floor.getEditorIcon(); - addSprite(region, tile.worldx(), tile.worldy()); - } - } - - chunks[x][y] = new Chunk(offset, mesh.getVerticesBuffer().position() - offset); + cache[x][y] = new Chunk(); + Arrays.fill(cache[x][y].caches, -1); + cacheChunk(x, y); } } - Log.info("Cache: " + Timers.elapsed()); + + Draw.scale(1f); + + Log.info("Time to cache: {0}", Timers.elapsed()); } - static ShaderProgram createDefaultShader () { - String vertexShader = - "#version 120\n" - + "attribute vec4 " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" // - + "attribute vec4 " + ShaderProgram.COLOR_ATTRIBUTE + ";\n" // - + "attribute vec4 " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" // - //+ "attribute float a_size;\n" - + "uniform mat4 u_projectionViewMatrix;\n" // - + "varying vec4 v_texCoords;\n" // - + "\n" // - + "void main(){\n" // - + " v_texCoords = " + ShaderProgram.TEXCOORD_ATTRIBUTE + "0;\n" // - + " gl_Position = u_projectionViewMatrix * " + ShaderProgram.POSITION_ATTRIBUTE + ";\n" // - + " gl_PointSize = 33.0;\n" - + "}\n"; - String fragmentShader = - "#version 120\n" - + "#ifdef GL_ES\n" // - + "precision mediump float;\n" // - + "#endif\n" // - + "varying vec4 v_texCoords;\n" // - + "uniform sampler2D u_texture;\n" // - + "void main(){\n"// - + " gl_FragColor = texture2D(u_texture, gl_PointCoord * (v_texCoords.zw - v_texCoords.xy) + v_texCoords.xy);\n" // - + "}"; - ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader); - if (shader.isCompiled() == false) throw new IllegalArgumentException("Error compiling shader: " + shader.getLog()); - return shader; + private class Chunk{ + int[] caches = new int[CacheLayer.values().length]; } - - class Chunk{ - final int start, end; - - public Chunk(int start, int end){ - this.start = start; - this.end = end; - } - } -} +} \ No newline at end of file diff --git a/core/src/io/anuke/mindustry/world/blocks/Floor.java b/core/src/io/anuke/mindustry/world/blocks/Floor.java index a72219ada9..4fc1771189 100644 --- a/core/src/io/anuke/mindustry/world/blocks/Floor.java +++ b/core/src/io/anuke/mindustry/world/blocks/Floor.java @@ -91,7 +91,7 @@ public class Floor extends Block{ int texSize = (int)(tilesize/scaling); int totSize = padSize + texSize; - int sx = -dx * texSize + padSize/2, sy = -dy * texSize + padSize; + int sx = -dx * texSize + padSize/2, sy = -dy * texSize + padSize/2; int x = Mathf.clamp(sx, 0, totSize); int y = Mathf.clamp(sy, 0, totSize); int w = Mathf.clamp(sx + texSize, 0, totSize) - x, h = Mathf.clamp(sy + texSize, 0, totSize) - y; @@ -187,9 +187,12 @@ public class Floor extends Block{ if(other == null) continue; Floor floor = other.floor(); + Floor cur = this; + if(floor instanceof OreBlock) floor = ((OreBlock) floor).base; + if(cur instanceof OreBlock) cur = ((OreBlock) cur).base; - if((floor.id <= this.id && !(tile.getElevation() != -1 && other.getElevation() > tile.getElevation())) || (!blends.test(floor) && !tileBlends.test(tile, other)) || (floor.cacheLayer.ordinal() > this.cacheLayer.ordinal() && !sameLayer) || - (sameLayer && floor.cacheLayer == this.cacheLayer)) continue; + if((floor.id <= cur.id && !(tile.getElevation() != -1 && other.getElevation() > tile.getElevation())) || (!cur.blends.test(floor) && !cur.tileBlends.test(tile, other)) || (floor.cacheLayer.ordinal() > cur.cacheLayer.ordinal() && !sameLayer) || + (sameLayer && floor.cacheLayer == cur.cacheLayer)) continue; TextureRegion region = floor.edgeRegions[i]; //Draw.color(Hue.random()); @@ -199,7 +202,7 @@ public class Floor extends Block{ tile.worldy() + floor.offsets[i].y * scaling, region.getRegionWidth() * scaling, region.getRegionHeight() * scaling); - //Draw.color(); + // Draw.color(); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java index 7333c7dcd2..0c0e727d93 100644 --- a/core/src/io/anuke/mindustry/world/blocks/OreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/OreBlock.java @@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.MathUtils; import io.anuke.mindustry.type.Item; import io.anuke.mindustry.type.ItemStack; -import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.util.Mathf; @@ -19,8 +18,6 @@ public class OreBlock extends Floor{ this.base = base; this.variants = 3; this.minimapColor = ore.color; - this.blends = block -> (block instanceof OreBlock && ((OreBlock) block).base != base) || (!(block instanceof OreBlock) && block != base); - this.tileBlends = (tile, other) -> tile.getElevation() < other.getElevation(); this.edge = base.name; } @@ -46,8 +43,4 @@ public class OreBlock extends Floor{ base.drawEdges(tile, true); } - @Override - public boolean blendOverride(Block block){ - return block == base; - } } diff --git a/tools/src/io/anuke/mindustry/Generators.java b/tools/src/io/anuke/mindustry/Generators.java index e38bac28cd..8f13d89404 100644 --- a/tools/src/io/anuke/mindustry/Generators.java +++ b/tools/src/io/anuke/mindustry/Generators.java @@ -160,8 +160,8 @@ public class Generators { Image shadow = ImageContext.get(item.name + (i+1)); for (int x = 0; x < image.width(); x++) { - for (int y = 1; y < image.height(); y++) { - Color color = shadow.getColor(x, y - 1); + for (int y = 2; y < image.height(); y++) { + Color color = shadow.getColor(x, y - 2); //draw semi transparent background if(color.a > 0.001f){