Optimized map renderer to no longer lag out on crappy phones

This commit is contained in:
Anuken
2018-03-20 22:15:44 -04:00
parent 1984921883
commit e330b28e49
3 changed files with 48 additions and 15 deletions

View File

@@ -2,6 +2,7 @@ package io.anuke.mindustry.editor;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.IntSet;
import com.badlogic.gdx.utils.IntSet.IntSetIterator;
import io.anuke.mindustry.io.MapTileData.TileDataWriter;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.blocks.Blocks;
@@ -9,15 +10,14 @@ import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Graphics;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.MeshBatch;
import io.anuke.ucore.graphics.IndexedRenderer;
import io.anuke.ucore.util.Log;
import static io.anuke.mindustry.Vars.tilesize;
public class MapRenderer {
private static final int chunksize = 32;
private MeshBatch mesh = new MeshBatch(0);
private int[][] chunks;
private static final int chunksize = 64;
private IndexedRenderer[][] chunks;
private IntSet updates = new IntSet();
private MapEditor editor;
private int width, height;
@@ -27,7 +27,22 @@ public class MapRenderer {
}
public void resize(int width, int height){
mesh.resize(width * height * 3);
//TODO just freezes on tablets
if(chunks != null){
for(int x = 0; x < chunks.length; x ++){
for(int y = 0; y < chunks[0].length; y ++){
chunks[x][y].dispose();
}
}
}
chunks = new IndexedRenderer[width/chunksize][height/chunksize];
for(int x = 0; x < width/chunksize; x ++){
for(int y = 0; y < height/chunksize; y ++){
chunks[x][y] = new IndexedRenderer(chunksize*chunksize*2);
}
}
this.width = width;
this.height = height;
updateAll();
@@ -39,11 +54,26 @@ public class MapRenderer {
Graphics.end();
mesh.getTransformMatrix().setToTranslation(tx, ty, 0).scl(tw / (width * tilesize),
th / (height * tilesize), 1f);
mesh.setProjectionMatrix(Core.batch.getProjectionMatrix());
IntSetIterator it = updates.iterator();
while(it.hasNext){
int i = it.next();
int x = i % width;
int y = i / height;
render(x, y);
}
updates.clear();
mesh.render(Core.atlas.getTextures().first());
for(int x = 0; x < width/chunksize; x ++){
for(int y = 0; y < height/chunksize; y ++){
IndexedRenderer mesh = chunks[x][y];
mesh.getTransformMatrix().setToTranslation(tx, ty, 0).scl(tw / (width * tilesize),
th / (height * tilesize), 1f);
mesh.setProjectionMatrix(Core.batch.getProjectionMatrix());
mesh.render(Core.atlas.getTextures().first());
}
}
Graphics.begin();
@@ -53,7 +83,8 @@ public class MapRenderer {
}
public void updatePoint(int x, int y){
render(x, y);
//TODO spread out over multiple frames?
updates.add(x + y*width);
}
public void updateAll(){
@@ -65,6 +96,8 @@ public class MapRenderer {
}
private void render(int wx, int wy){
int x = wx/chunksize, y = wy/chunksize;
IndexedRenderer mesh = chunks[x][y];
TileDataWriter data = editor.getMap().readAt(wx, wy);
Block floor = Block.getByID(data.floor);
Block wall = Block.getByID(data.wall);
@@ -73,14 +106,14 @@ public class MapRenderer {
if (floor != Blocks.air && Draw.hasRegion(fregion)) {
TextureRegion region = Draw.region(fregion);
mesh.draw(wx + wy*width, region, wx * tilesize, wy * tilesize, 8, 8);
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, 8, 8);
}
String wregion = Draw.hasRegion(wall.name) ? wall.name : wall.name + "1";
if (wall != Blocks.air && Draw.hasRegion(wregion)) {
TextureRegion region = Draw.region(wregion);
mesh.draw(wx + wy*width + (width*height), region, wx * tilesize, wy * tilesize, 8, 8);
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region, wx * tilesize, wy * tilesize, 8, 8);
}
}
}