WIP unification and cleanup of rendering in editor

This commit is contained in:
Anuken
2025-07-19 15:06:00 -04:00
parent c32f7473e8
commit 72e9db57a4
19 changed files with 173 additions and 176 deletions

View File

@@ -64,48 +64,7 @@ public class BlockRenderer{
});
Events.on(WorldLoadEvent.class, event -> {
blockTree = new BlockQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
blockLightTree = new BlockLightQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
floorTree = new FloorQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
shadowEvents.clear();
updateFloors.clear();
lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated
hadMapLimit = state.rules.limitMapArea;
shadows.getTexture().setFilter(TextureFilter.linear, TextureFilter.linear);
shadows.resize(world.width(), world.height());
shadows.begin();
Core.graphics.clear(Color.white);
Draw.proj().setOrtho(0, 0, shadows.getWidth(), shadows.getHeight());
Draw.color(blendShadowColor);
for(Tile tile : world.tiles){
recordIndex(tile);
if(tile.floor().updateRender(tile)){
updateFloors.add(new UpdateRenderState(tile, tile.floor()));
}
if(tile.overlay().updateRender(tile)){
updateFloors.add(new UpdateRenderState(tile, tile.overlay()));
}
if(tile.build != null && (tile.team() == player.team() || !state.rules.fog || (tile.build.visibleFlags & (1L << player.team().id)) != 0)){
tile.build.wasVisible = true;
}
if(tile.block().displayShadow(tile) && (tile.build == null || tile.build.wasVisible)){
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
}
}
Draw.flush();
Draw.color();
shadows.end();
updateDarkness();
reload();
});
//sometimes darkness gets disabled.
@@ -150,6 +109,51 @@ public class BlockRenderer{
});
}
public void reload(){
blockTree = new BlockQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
blockLightTree = new BlockLightQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
floorTree = new FloorQuadtree(new Rect(0, 0, world.unitWidth(), world.unitHeight()));
shadowEvents.clear();
updateFloors.clear();
lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated
hadMapLimit = state.rules.limitMapArea;
shadows.getTexture().setFilter(TextureFilter.linear, TextureFilter.linear);
shadows.resize(world.width(), world.height());
shadows.begin();
Core.graphics.clear(Color.white);
Draw.proj().setOrtho(0, 0, shadows.getWidth(), shadows.getHeight());
Draw.color(blendShadowColor);
for(Tile tile : world.tiles){
recordIndex(tile);
if(tile.floor().updateRender(tile)){
updateFloors.add(new UpdateRenderState(tile, tile.floor()));
}
if(tile.overlay().updateRender(tile)){
updateFloors.add(new UpdateRenderState(tile, tile.overlay()));
}
if(tile.build != null && (tile.team() == player.team() || !state.rules.fog || (tile.build.visibleFlags & (1L << player.team().id)) != 0)){
tile.build.wasVisible = true;
}
if(tile.block().displayShadow(tile) && (tile.build == null || tile.build.wasVisible)){
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
}
}
Draw.flush();
Draw.color();
shadows.end();
updateDarkness();
}
public void updateDarkness(){
darkEvents.clear();
dark.getTexture().setFilter(TextureFilter.linear);
@@ -197,6 +201,10 @@ public class BlockRenderer{
}
}
public FrameBuffer getShadowBuffer(){
return shadows;
}
public void removeFloorIndex(Tile tile){
if(indexFloor(tile)) floorTree.remove(tile);
}
@@ -294,7 +302,7 @@ public class BlockRenderer{
}
}
public void drawShadows(){
public void processShadows(){
if(!shadowEvents.isEmpty()){
Draw.flush();
@@ -315,6 +323,10 @@ public class BlockRenderer{
Draw.proj(camera);
}
}
public void drawShadows(){
processShadows();
float ww = world.width() * tilesize, wh = world.height() * tilesize;
float x = camera.position.x + tilesize / 2f, y = camera.position.y + tilesize / 2f;
@@ -511,6 +523,10 @@ public class BlockRenderer{
}
}
public void updateShadowTile(Tile tile){
shadowEvents.add(tile);
}
static class BlockQuadtree extends QuadTree<Tile>{
public BlockQuadtree(Rect bounds){

View File

@@ -97,7 +97,7 @@ public class CacheLayer{
@Override
public void begin(){
if(!Core.settings.getBool("animatedwater")) return;
if(!renderer.animateWater) return;
renderer.effectBuffer.begin();
Core.graphics.clear(Color.clear);
@@ -106,7 +106,7 @@ public class CacheLayer{
@Override
public void end(){
if(!Core.settings.getBool("animatedwater")) return;
if(!renderer.animateWater) return;
renderer.effectBuffer.end();
renderer.effectBuffer.blit(shader);

View File

@@ -111,10 +111,17 @@ public class FloorRenderer{
Events.on(WorldLoadEvent.class, event -> clearTiles());
}
public IndexData getIndexData(){
return indexData;
}
/** Queues up a cache change for a tile. Only runs in render loop. */
public void recacheTile(Tile tile){
//recaching all layers may not be necessary
recacheSet.add(Point2.pack(tile.x / chunksize, tile.y / chunksize));
recacheTile(tile.x, tile.y);
}
public void recacheTile(int x, int y){
recacheSet.add(Point2.pack(x / chunksize, y / chunksize));
}
public void drawFloor(){
@@ -127,10 +134,10 @@ public class FloorRenderer{
float pad = tilesize/2f;
int
minx = (int)((camera.position.x - camera.width/2f - pad) / chunkunits),
miny = (int)((camera.position.y - camera.height/2f - pad) / chunkunits),
maxx = Mathf.ceil((camera.position.x + camera.width/2f + pad) / chunkunits),
maxy = Mathf.ceil((camera.position.y + camera.height/2f + pad) / chunkunits);
minx = Math.max((int)((camera.position.x - camera.width/2f - pad) / chunkunits), 0),
miny = Math.max((int)((camera.position.y - camera.height/2f - pad) / chunkunits), 0),
maxx = Math.min(Mathf.ceil((camera.position.x + camera.width/2f + pad) / chunkunits), cache.length),
maxy = Math.min(Mathf.ceil((camera.position.y + camera.height/2f + pad) / chunkunits), cache[0].length);
int layers = CacheLayer.all.length;
@@ -221,10 +228,10 @@ public class FloorRenderer{
Camera camera = Core.camera;
int
minx = (int)((camera.position.x - camera.width/2f - pad) / chunkunits),
miny = (int)((camera.position.y - camera.height/2f - pad) / chunkunits),
maxx = Mathf.ceil((camera.position.x + camera.width/2f + pad) / chunkunits),
maxy = Mathf.ceil((camera.position.y + camera.height/2f + pad) / chunkunits);
minx = Math.max((int)((camera.position.x - camera.width/2f - pad) / chunkunits), 0),
miny = Math.max((int)((camera.position.y - camera.height/2f - pad) / chunkunits), 0),
maxx = Math.min(Mathf.ceil((camera.position.x + camera.width/2f + pad) / chunkunits), cache.length),
maxy = Math.min(Mathf.ceil((camera.position.y + camera.height/2f + pad) / chunkunits), cache[0].length);
layer.begin();

View File

@@ -5,6 +5,9 @@ import arc.graphics.g2d.*;
import arc.graphics.gl.*;
import arc.math.*;
import arc.util.*;
import mindustry.*;
import java.nio.*;
public class IndexedRenderer implements Disposable{
private static final int vsize = 5;
@@ -34,9 +37,10 @@ public class IndexedRenderer implements Disposable{
}
"""
);
private static final float[] tmpVerts = new float[vsize * 6];
private static final float[] tmpVerts = new float[vsize * 4];
private Mesh mesh;
private FloatBuffer buffer;
private Mat projMatrix = new Mat();
private Mat transMatrix = new Mat();
@@ -57,7 +61,7 @@ public class IndexedRenderer implements Disposable{
program.setUniformMatrix4("u_projTrans", combined);
mesh.render(program, Gl.triangles, 0, mesh.getMaxVertices());
mesh.render(program, Gl.triangles, 0, mesh.getMaxVertices() * 6 / 4);
}
public void setColor(Color color){
@@ -94,26 +98,19 @@ public class IndexedRenderer implements Disposable{
vertices[idx++] = u2;
vertices[idx++] = v2;
//tri2
vertices[idx++] = fx2;
vertices[idx++] = fy2;
vertices[idx++] = color;
vertices[idx++] = u2;
vertices[idx++] = v2;
vertices[idx++] = fx2;
vertices[idx++] = y;
vertices[idx++] = color;
vertices[idx++] = u2;
vertices[idx++] = v;
vertices[idx++] = x;
vertices[idx++] = y;
vertices[idx++] = color;
vertices[idx++] = u;
vertices[idx++] = v;
int dest = index * vsize * 4;
mesh.updateVertices(index * vsize * 6, vertices);
buffer.position(dest);
buffer.put(vertices);
//mark dirty
mesh.getVerticesBuffer();
}
public void draw(int index, TextureRegion region, float x, float y, float w, float h, float rotation){
@@ -166,26 +163,19 @@ public class IndexedRenderer implements Disposable{
vertices[idx++] = u2;
vertices[idx++] = v2;
//tri2
vertices[idx++] = x3;
vertices[idx++] = y3;
vertices[idx++] = color;
vertices[idx++] = u2;
vertices[idx++] = v2;
vertices[idx++] = x4;
vertices[idx++] = y4;
vertices[idx++] = color;
vertices[idx++] = u2;
vertices[idx++] = v;
vertices[idx++] = x1;
vertices[idx++] = y1;
vertices[idx++] = color;
vertices[idx++] = u;
vertices[idx++] = v;
int dest = index * vsize * 4;
mesh.updateVertices(index * vsize * 6, vertices);
buffer.position(dest);
buffer.put(vertices);
//mark dirty
mesh.getVerticesBuffer();
}
public Mat getTransformMatrix(){
@@ -199,13 +189,15 @@ public class IndexedRenderer implements Disposable{
public void resize(int sprites){
if(mesh != null) mesh.dispose();
mesh = new Mesh(true, 6 * sprites, 0,
mesh = new Mesh(true, 4 * sprites, 0,
VertexAttribute.position,
VertexAttribute.color,
VertexAttribute.texCoords);
//TODO why is this the only way to get it working properly? it should not need an array
mesh.setVertices(new float[6 * sprites * vsize]);
buffer = mesh.getVerticesBuffer();
buffer.limit(buffer.capacity());
mesh.indices = Vars.renderer.blocks.floor.getIndexData();
}
private void updateMatrix(){

View File

@@ -118,8 +118,7 @@ public class MultiPacker implements Disposable{
environment(4096),
ui(4096),
rubble(4096, 2048),
editor(4096, 2048);
rubble(4096, 2048);
public static final PageType[] all = values();