Partially implemented new building rendering
This commit is contained in:
@@ -70,7 +70,7 @@ public class DrawOperation{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case opBlock -> {
|
case opBlock -> {
|
||||||
tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y));
|
tile.getLinkedTiles(t -> editor.renderer.updateStatic(t.x, t.y));
|
||||||
|
|
||||||
Block block = content.block(to);
|
Block block = content.block(to);
|
||||||
tile.setBlock(block, tile.team(), tile.build == null ? 0 : tile.build.rotation);
|
tile.setBlock(block, tile.team(), tile.build == null ? 0 : tile.build.rotation);
|
||||||
@@ -78,7 +78,7 @@ public class DrawOperation{
|
|||||||
tile.build.enabled = true;
|
tile.build.enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y));
|
tile.getLinkedTiles(t -> editor.renderer.updateStatic(t.x, t.y));
|
||||||
}
|
}
|
||||||
case opRotation -> {
|
case opRotation -> {
|
||||||
if(tile.build != null) tile.build.rotation = to;
|
if(tile.build != null) tile.build.rotation = to;
|
||||||
@@ -86,7 +86,7 @@ public class DrawOperation{
|
|||||||
case opTeam -> tile.setTeam(Team.get(to));
|
case opTeam -> tile.setTeam(Team.get(to));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
editor.renderer.updatePoint(tile.x, tile.y);
|
editor.renderer.updateStatic(tile.x, tile.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Struct
|
@Struct
|
||||||
|
|||||||
171
core/src/mindustry/editor/EditorSpriteCache.java
Normal file
171
core/src/mindustry/editor/EditorSpriteCache.java
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
package mindustry.editor;
|
||||||
|
|
||||||
|
import arc.graphics.*;
|
||||||
|
import arc.graphics.g2d.*;
|
||||||
|
import arc.graphics.gl.*;
|
||||||
|
import arc.math.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
|
|
||||||
|
public class EditorSpriteCache implements Disposable{
|
||||||
|
//xy + color + uv
|
||||||
|
static final int vertexSize = 2 + 1 + 2;
|
||||||
|
|
||||||
|
private @Nullable Mesh mesh;
|
||||||
|
private final Seq<Texture> textures = new Seq<>(8);
|
||||||
|
private final IntSeq counts = new IntSeq(8);
|
||||||
|
|
||||||
|
private float[] tmpVertices;
|
||||||
|
|
||||||
|
/** Index in tmpVertices of current vertex data. */
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
/** @param tmpVertices Temporary buffer to hold vertices while building up sprites. Should be large enough to hold all sprite data this cache will contain. */
|
||||||
|
public EditorSpriteCache(float[] tmpVertices){
|
||||||
|
this.tmpVertices = tmpVertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return whether anything was added to the cache. */
|
||||||
|
public boolean isEmpty(){
|
||||||
|
return index == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds this cache into a mesh that can be used for rendering. Use after calling {@link #draw(TextureRegion, float, float, float, float, float, float, float, float)}.
|
||||||
|
* Until this method is called, no mesh is created.
|
||||||
|
*
|
||||||
|
* @param indices The shared index data in standard quad format, as seen in SpriteBatch.
|
||||||
|
* Since this data is static, it should be the same across all caches, and be large enough to accommodate all sprites.
|
||||||
|
* */
|
||||||
|
public void build(IndexData indices){
|
||||||
|
if(mesh != null) mesh.dispose();
|
||||||
|
|
||||||
|
mesh = new Mesh(true, index / vertexSize, 0,
|
||||||
|
VertexAttribute.position,
|
||||||
|
VertexAttribute.color,
|
||||||
|
VertexAttribute.texCoords
|
||||||
|
);
|
||||||
|
mesh.indices = indices;
|
||||||
|
mesh.setVertices(tmpVertices, 0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds the specified region to the cache. */
|
||||||
|
public void draw(TextureRegion region, float x, float y, float originX, float originY, float width, float height, float rotation, float colorPacked){
|
||||||
|
if(mesh != null) throw new IllegalStateException("This cache is already built. Call #clear() before drawing new sprites.");
|
||||||
|
|
||||||
|
// bottom left and top right corner points relative to origin
|
||||||
|
final float worldOriginX = x + originX;
|
||||||
|
final float worldOriginY = y + originY;
|
||||||
|
float fx = -originX;
|
||||||
|
float fy = -originY;
|
||||||
|
float fx2 = width - originX;
|
||||||
|
float fy2 = height - originY;
|
||||||
|
|
||||||
|
float x1, y1, x2, y2, x3, y3, x4, y4;
|
||||||
|
|
||||||
|
// rotate
|
||||||
|
if(rotation != 0){
|
||||||
|
final float cos = Mathf.cosDeg(rotation);
|
||||||
|
final float sin = Mathf.sinDeg(rotation);
|
||||||
|
|
||||||
|
x1 = cos * fx - sin * fy;
|
||||||
|
y1 = sin * fx + cos * fy;
|
||||||
|
|
||||||
|
x2 = cos * fx - sin * fy2;
|
||||||
|
y2 = sin * fx + cos * fy2;
|
||||||
|
|
||||||
|
x3 = cos * fx2 - sin * fy2;
|
||||||
|
y3 = sin * fx2 + cos * fy2;
|
||||||
|
|
||||||
|
x4 = x1 + (x3 - x2);
|
||||||
|
y4 = y3 - (y2 - y1);
|
||||||
|
}else{
|
||||||
|
x1 = fx;
|
||||||
|
y1 = fy;
|
||||||
|
|
||||||
|
x2 = fx;
|
||||||
|
y2 = fy2;
|
||||||
|
|
||||||
|
x3 = fx2;
|
||||||
|
y3 = fy2;
|
||||||
|
|
||||||
|
x4 = fx2;
|
||||||
|
y4 = fy;
|
||||||
|
}
|
||||||
|
|
||||||
|
x1 += worldOriginX;
|
||||||
|
y1 += worldOriginY;
|
||||||
|
x2 += worldOriginX;
|
||||||
|
y2 += worldOriginY;
|
||||||
|
x3 += worldOriginX;
|
||||||
|
y3 += worldOriginY;
|
||||||
|
x4 += worldOriginX;
|
||||||
|
y4 += worldOriginY;
|
||||||
|
|
||||||
|
final float u = region.u;
|
||||||
|
final float v = region.v2;
|
||||||
|
final float u2 = region.u2;
|
||||||
|
final float v2 = region.v;
|
||||||
|
|
||||||
|
int idx = index;
|
||||||
|
float[] verts = tmpVertices;
|
||||||
|
Texture texture = region.texture;
|
||||||
|
|
||||||
|
verts[idx + 0] = x1;
|
||||||
|
verts[idx + 1] = y1;
|
||||||
|
verts[idx + 2] = colorPacked;
|
||||||
|
verts[idx + 3] = u;
|
||||||
|
verts[idx + 4] = v;
|
||||||
|
|
||||||
|
verts[idx + 5] = x2;
|
||||||
|
verts[idx + 6] = y2;
|
||||||
|
verts[idx + 7] = colorPacked;
|
||||||
|
verts[idx + 8] = u;
|
||||||
|
verts[idx + 9] = v2;
|
||||||
|
|
||||||
|
verts[idx + 10] = x3;
|
||||||
|
verts[idx + 11] = y3;
|
||||||
|
verts[idx + 12] = colorPacked;
|
||||||
|
verts[idx + 13] = u2;
|
||||||
|
verts[idx + 14] = v2;
|
||||||
|
|
||||||
|
verts[idx + 15] = x4;
|
||||||
|
verts[idx + 16] = y4;
|
||||||
|
verts[idx + 17] = colorPacked;
|
||||||
|
verts[idx + 18] = u2;
|
||||||
|
verts[idx + 19] = v;
|
||||||
|
|
||||||
|
int lastIndex = textures.size - 1;
|
||||||
|
if(lastIndex < 0 || textures.get(lastIndex) != texture){
|
||||||
|
textures.add(texture);
|
||||||
|
counts.add(6);
|
||||||
|
}else{
|
||||||
|
counts.incr(lastIndex, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
index += vertexSize * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Renders the cached mesh. The shader must already have the correct view matrix (usually u_projectionViewMatrix) set as a uniform. */
|
||||||
|
public void render(Shader shader){
|
||||||
|
if(mesh == null) throw new IllegalStateException("Cache is empty, call build() first.");
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < textures.size; i++){
|
||||||
|
int count = counts.items[i];
|
||||||
|
textures.get(i).bind();
|
||||||
|
|
||||||
|
mesh.render(shader, Gl.triangles, offset, count);
|
||||||
|
offset += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose(){
|
||||||
|
if(mesh != null){
|
||||||
|
mesh.dispose();
|
||||||
|
mesh = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import arc.func.*;
|
|||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
import mindustry.world.blocks.environment.*;
|
||||||
import mindustry.world.modules.*;
|
import mindustry.world.modules.*;
|
||||||
@@ -46,13 +47,16 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBlock(Block type, Team team, int rotation, Prov<Building> entityprov){
|
public void setBlock(Block type, Team team, int rotation, Prov<Building> entityprov){
|
||||||
|
Block prev = this.block;
|
||||||
|
Tile prevCenter = (build == null ? this : build.tile);
|
||||||
|
|
||||||
if(skip()){
|
if(skip()){
|
||||||
super.setBlock(type, team, rotation, entityprov);
|
super.setBlock(type, team, rotation, entityprov);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.block == type && (build == null || build.rotation == rotation)){
|
if(this.block == type && (build == null || build.rotation == rotation)){
|
||||||
update();
|
updateStatic();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +65,7 @@ public class EditorTile extends Tile{
|
|||||||
cen.op(DrawOperation.opRotation, (byte)build.rotation);
|
cen.op(DrawOperation.opRotation, (byte)build.rotation);
|
||||||
cen.op(DrawOperation.opTeam, (byte)build.team.id);
|
cen.op(DrawOperation.opTeam, (byte)build.team.id);
|
||||||
cen.op(DrawOperation.opBlock, block.id);
|
cen.op(DrawOperation.opBlock, block.id);
|
||||||
update();
|
updateStatic();
|
||||||
}else{
|
}else{
|
||||||
if(build != null) op(DrawOperation.opRotation, (byte)build.rotation);
|
if(build != null) op(DrawOperation.opRotation, (byte)build.rotation);
|
||||||
if(build != null) op(DrawOperation.opTeam, (byte)build.team.id);
|
if(build != null) op(DrawOperation.opTeam, (byte)build.team.id);
|
||||||
@@ -70,7 +74,20 @@ public class EditorTile extends Tile{
|
|||||||
|
|
||||||
super.setBlock(type, team, rotation, entityprov);
|
super.setBlock(type, team, rotation, entityprov);
|
||||||
|
|
||||||
renderer.blocks.updateShadowTile(this);
|
if(requiresBlockUpdate(type) || requiresBlockUpdate(prev)){
|
||||||
|
if(prev.size > 1){
|
||||||
|
prevCenter.getLinkedTilesAs(prev, tile -> {
|
||||||
|
editor.renderer.updateBlock(tile.x, tile.y);
|
||||||
|
renderer.blocks.updateShadowTile(tile);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getLinkedTiles(tile -> {
|
||||||
|
editor.renderer.updateBlock(tile.x, tile.y);
|
||||||
|
renderer.blocks.updateShadowTile(tile);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
renderer.blocks.updateShadowTile(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,7 +101,7 @@ public class EditorTile extends Tile{
|
|||||||
op(DrawOperation.opTeam, (byte)getTeamID());
|
op(DrawOperation.opTeam, (byte)getTeamID());
|
||||||
super.setTeam(team);
|
super.setTeam(team);
|
||||||
|
|
||||||
getLinkedTiles(t -> editor.renderer.updatePoint(t.x, t.y));
|
getLinkedTiles(t -> editor.renderer.updateStatic(t.x, t.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -105,7 +122,7 @@ public class EditorTile extends Tile{
|
|||||||
if(skip()){
|
if(skip()){
|
||||||
super.fireChanged();
|
super.fireChanged();
|
||||||
}else{
|
}else{
|
||||||
update();
|
updateStatic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +131,7 @@ public class EditorTile extends Tile{
|
|||||||
if(skip()){
|
if(skip()){
|
||||||
super.firePreChanged();
|
super.firePreChanged();
|
||||||
}else{
|
}else{
|
||||||
update();
|
updateStatic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +176,12 @@ public class EditorTile extends Tile{
|
|||||||
return skip() && super.isDarkened();
|
return skip() && super.isDarkened();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update(){
|
private boolean requiresBlockUpdate(Block block){
|
||||||
editor.renderer.updatePoint(x, y);
|
return block != Blocks.air && block.cacheLayer == CacheLayer.normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStatic(){
|
||||||
|
editor.renderer.updateStatic(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean skip(){
|
private boolean skip(){
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ public class MapEditor{
|
|||||||
if(currentOp == null) currentOp = new DrawOperation();
|
if(currentOp == null) currentOp = new DrawOperation();
|
||||||
currentOp.addOperation(data);
|
currentOp.addOperation(data);
|
||||||
|
|
||||||
renderer.updatePoint(TileOp.x(data), TileOp.y(data));
|
renderer.updateStatic(TileOp.x(data), TileOp.y(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
class Context implements WorldContext{
|
class Context implements WorldContext{
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
|
|||||||
state.rules = (lastSavedRules == null ? new Rules() : lastSavedRules);
|
state.rules = (lastSavedRules == null ? new Rules() : lastSavedRules);
|
||||||
lastSavedRules = null;
|
lastSavedRules = null;
|
||||||
saved = false;
|
saved = false;
|
||||||
editor.renderer.updateAll();
|
editor.renderer.recache();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void editInGame(){
|
private void editInGame(){
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ public class MapGenerateDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//reset undo stack as generation... messes things up
|
//reset undo stack as generation... messes things up
|
||||||
editor.renderer.updateAll();
|
editor.renderer.recache();
|
||||||
editor.clearOp();
|
editor.clearOp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class MapProcessorsDialog extends BaseDialog{
|
|||||||
foundAny = true;
|
foundAny = true;
|
||||||
tile.setNet(Blocks.worldProcessor, Team.sharded, 0);
|
tile.setNet(Blocks.worldProcessor, Team.sharded, 0);
|
||||||
if(ui.editor.isShown()){
|
if(ui.editor.isShown()){
|
||||||
Vars.editor.renderer.updatePoint(x, y);
|
Vars.editor.renderer.updateStatic(x, y);
|
||||||
}
|
}
|
||||||
break outer;
|
break outer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,228 +3,178 @@ package mindustry.editor;
|
|||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.graphics.gl.*;
|
||||||
|
import arc.math.geom.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.environment.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class MapRenderer implements Disposable{
|
public class MapRenderer implements Disposable{
|
||||||
private static final int chunkSize = 62;
|
private static final int chunkSize = 60;
|
||||||
private IndexedRenderer[][] chunks;
|
private EditorSpriteCache[][] chunks;
|
||||||
private IntSet updates = new IntSet();
|
private IntSet recacheChunks = new IntSet();
|
||||||
private IntSet delayedUpdates = new IntSet();
|
|
||||||
private TextureRegion clearEditor;
|
|
||||||
private int width, height;
|
private int width, height;
|
||||||
|
|
||||||
|
private Shader shader;
|
||||||
|
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
updates.clear();
|
dispose();
|
||||||
delayedUpdates.clear();
|
|
||||||
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[(int)Math.ceil((float)width / chunkSize)][(int)Math.ceil((float)height / chunkSize)];
|
recacheChunks.clear();
|
||||||
|
chunks = new EditorSpriteCache[(int)Math.ceil((float)width / chunkSize)][(int)Math.ceil((float)height / chunkSize)];
|
||||||
|
|
||||||
for(int x = 0; x < chunks.length; x++){
|
|
||||||
for(int y = 0; y < chunks[0].length; y++){
|
|
||||||
chunks[x][y] = new IndexedRenderer(chunkSize * chunkSize * 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
updateAll();
|
|
||||||
|
|
||||||
renderer.blocks.floor.clearTiles();
|
recache();
|
||||||
renderer.blocks.reload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(float tx, float ty, float tw, float th, float zoom){
|
public void draw(float tx, float ty, float tw, float th){
|
||||||
|
if(shader == null){
|
||||||
|
shader = new Shader(
|
||||||
|
"""
|
||||||
|
attribute vec4 a_position;
|
||||||
|
attribute vec4 a_color;
|
||||||
|
attribute vec2 a_texCoord0;
|
||||||
|
uniform mat4 u_projTrans;
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
void main(){
|
||||||
|
v_color = a_color;
|
||||||
|
v_color.a = v_color.a * (255.0/254.0);
|
||||||
|
v_texCoords = a_texCoord0;
|
||||||
|
gl_Position = u_projTrans * a_position;
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
|
||||||
|
"""
|
||||||
|
varying lowp vec4 v_color;
|
||||||
|
varying vec2 v_texCoords;
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
gl_FragColor = v_color * texture2D(u_texture, v_texCoords);
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Draw.flush();
|
Draw.flush();
|
||||||
|
|
||||||
//TODO properly integrate this later
|
renderer.blocks.floor.checkChanges();
|
||||||
if(true){
|
|
||||||
updates.each(i -> renderer.blocks.floor.recacheTile(i % width, i / width));
|
|
||||||
updates.clear();
|
|
||||||
|
|
||||||
updates.addAll(delayedUpdates);
|
boolean prev = renderer.animateWater;
|
||||||
delayedUpdates.clear();
|
renderer.animateWater = false;
|
||||||
|
|
||||||
renderer.blocks.floor.checkChanges();
|
Core.camera.position.set(world.width()/2f * tilesize, world.height()/2f * tilesize);
|
||||||
|
Core.camera.width = 999999f;
|
||||||
|
Core.camera.height = 999999f;
|
||||||
|
Core.camera.mat.set(Draw.proj()).mul(Tmp.m3.setToTranslation(tx, ty).scale(tw / (width * tilesize), th / (height * tilesize)).translate(4f, 4f));
|
||||||
|
renderer.blocks.floor.drawFloor();
|
||||||
|
|
||||||
boolean prev = renderer.animateWater;
|
Tmp.m2.set(Draw.proj());
|
||||||
renderer.animateWater = false;
|
|
||||||
|
|
||||||
Core.camera.position.set(world.width()/2f * tilesize, world.height()/2f * tilesize);
|
//scissors are always enabled because this is drawn clipped in UI, make sure they don't interfere with drawing shadow events
|
||||||
Core.camera.width = 999999f;
|
Gl.disable(Gl.scissorTest);
|
||||||
Core.camera.height = 999999f;
|
|
||||||
Core.camera.mat.set(Draw.proj()).mul(Tmp.m3.setToTranslation(tx, ty).scale(tw / (width * tilesize), th / (height * tilesize)).translate(4f, 4f));
|
|
||||||
renderer.blocks.floor.drawFloor();
|
|
||||||
|
|
||||||
Tmp.m2.set(Draw.proj());
|
renderer.blocks.processShadows();
|
||||||
|
|
||||||
//this sure is awful!
|
Gl.enable(Gl.scissorTest);
|
||||||
Gl.disable(Gl.scissorTest);
|
|
||||||
|
|
||||||
renderer.blocks.processShadows();
|
Draw.proj(Core.camera.mat);
|
||||||
|
|
||||||
Gl.enable(Gl.scissorTest);
|
Draw.shader(Shaders.darkness);
|
||||||
|
Draw.rect(Draw.wrap(renderer.blocks.getShadowBuffer().getTexture()), world.width() * tilesize/2f - tilesize/2f, world.height() * tilesize/2f - tilesize/2f, world.width() * tilesize, -world.height() * tilesize);
|
||||||
|
Draw.shader();
|
||||||
|
|
||||||
Draw.proj(Core.camera.mat);
|
Draw.proj(Tmp.m2);
|
||||||
|
|
||||||
Draw.shader(Shaders.darkness);
|
renderer.blocks.floor.beginDraw();
|
||||||
Draw.rect(Draw.wrap(renderer.blocks.getShadowBuffer().getTexture()), world.width() * tilesize/2f - tilesize/2f, world.height() * tilesize/2f - tilesize/2f, world.width() * tilesize, -world.height() * tilesize);
|
renderer.blocks.floor.drawLayer(CacheLayer.walls);
|
||||||
Draw.shader();
|
renderer.animateWater = prev;
|
||||||
|
|
||||||
Draw.proj(Tmp.m2);
|
if(chunks == null) return;
|
||||||
|
|
||||||
renderer.blocks.floor.beginDraw();
|
recacheChunks.each(i -> recacheChunk(Point2.x(i), Point2.y(i)));
|
||||||
renderer.blocks.floor.drawLayer(CacheLayer.walls);
|
recacheChunks.clear();
|
||||||
renderer.animateWater = prev;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearEditor = Core.atlas.find("clear-editor");
|
shader.bind();
|
||||||
|
shader.setUniformMatrix4("u_projTrans", Core.camera.mat);
|
||||||
updates.each(i -> render(i % width, i / width));
|
|
||||||
updates.clear();
|
|
||||||
|
|
||||||
updates.addAll(delayedUpdates);
|
|
||||||
delayedUpdates.clear();
|
|
||||||
|
|
||||||
//????
|
|
||||||
if(chunks == null){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var texture = clearEditor.texture;
|
|
||||||
|
|
||||||
for(int x = 0; x < chunks.length; x++){
|
for(int x = 0; x < chunks.length; x++){
|
||||||
for(int y = 0; y < chunks[0].length; y++){
|
for(int y = 0; y < chunks[0].length; y++){
|
||||||
IndexedRenderer mesh = chunks[x][y];
|
EditorSpriteCache mesh = chunks[x][y];
|
||||||
|
|
||||||
if(mesh == null){
|
if(mesh == null) continue;
|
||||||
continue;
|
|
||||||
|
mesh.render(shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateStatic(int x, int y){
|
||||||
|
renderer.blocks.floor.recacheTile(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateBlock(int x, int y){
|
||||||
|
recacheChunks.add(Point2.pack(x / chunkSize, y / chunkSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
void recache(){
|
||||||
|
renderer.blocks.floor.clearTiles();
|
||||||
|
renderer.blocks.reload();
|
||||||
|
|
||||||
|
for(int x = 0; x < chunks.length; x++){
|
||||||
|
for(int y = 0; y < chunks[0].length; y++){
|
||||||
|
recacheChunk(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void recacheChunk(int cx, int cy){
|
||||||
|
if(chunks[cx][cy] != null){
|
||||||
|
chunks[cx][cy].dispose();
|
||||||
|
chunks[cx][cy] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorSpriteCache cache = new EditorSpriteCache(renderer.blocks.floor.getVertexBuffer());
|
||||||
|
|
||||||
|
for(int x = cx * chunkSize; x < (cx + 1) * chunkSize; x++){
|
||||||
|
for(int y = cy * chunkSize; y < (cy + 1) * chunkSize; y++){
|
||||||
|
Tile tile = world.tile(x, y);
|
||||||
|
|
||||||
|
if(tile != null && tile.block() != Blocks.air && tile.block().cacheLayer == CacheLayer.normal && tile.isCenter()){
|
||||||
|
Block block = tile.block();
|
||||||
|
|
||||||
|
TextureRegion region = block.fullIcon;
|
||||||
|
|
||||||
|
float width = region.width * region.scl(), height = region.height * region.scl();
|
||||||
|
|
||||||
|
cache.draw(block.fullIcon,
|
||||||
|
x * tilesize + block.offset - width / 2f,
|
||||||
|
y * tilesize + block.offset - height / 2f,
|
||||||
|
width/2f, height/2f,
|
||||||
|
width, height,
|
||||||
|
tile.build == null || !block.rotate ? 0 : tile.build.rotdeg(),
|
||||||
|
Color.whiteFloatBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.getTransformMatrix().setToTranslation(tx, ty).scale(tw / (width * tilesize), th / (height * tilesize));
|
|
||||||
mesh.setProjectionMatrix(Draw.proj());
|
|
||||||
|
|
||||||
mesh.render(texture);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void updatePoint(int x, int y){
|
if(!cache.isEmpty()){
|
||||||
updates.add(x + y * width);
|
cache.build(renderer.blocks.floor.getIndexData());
|
||||||
}
|
chunks[cx][cy] = cache;
|
||||||
|
|
||||||
public void updateAll(){
|
|
||||||
clearEditor = Core.atlas.find("clear-editor");
|
|
||||||
for(int x = 0; x < width; x++){
|
|
||||||
for(int y = 0; y < height; y++){
|
|
||||||
render(x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextureRegion getIcon(Block wall, int index){
|
|
||||||
return !wall.fullIcon.found() ?
|
|
||||||
clearEditor : wall.variants > 0 ?
|
|
||||||
wall.variantRegions()[Mathf.randomSeed(index, 0, wall.variantRegions().length - 1)] :
|
|
||||||
wall.fullIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void render(int wx, int wy){
|
|
||||||
int x = wx / chunkSize, y = wy / chunkSize;
|
|
||||||
if(x >= chunks.length || y >= chunks[0].length) return;
|
|
||||||
IndexedRenderer mesh = chunks[x][y];
|
|
||||||
Tile tile = editor.tiles().getn(wx, wy);
|
|
||||||
|
|
||||||
Floor floor = tile.floor();
|
|
||||||
Floor overlay = tile.overlay();
|
|
||||||
Block wall = tile.block();
|
|
||||||
|
|
||||||
TextureRegion region;
|
|
||||||
|
|
||||||
int idxWall = (wx % chunkSize) + (wy % chunkSize) * chunkSize;
|
|
||||||
int idxDecal = (wx % chunkSize) + (wy % chunkSize) * chunkSize + chunkSize * chunkSize;
|
|
||||||
boolean useSyntheticWall = overlay.wallOre;
|
|
||||||
|
|
||||||
//draw synthetic wall or floor OR standard wall if wall ore
|
|
||||||
if(wall != Blocks.air && useSyntheticWall){
|
|
||||||
region = getIcon(wall, idxWall);
|
|
||||||
|
|
||||||
float width = region.width * region.scl(), height = region.height * region.scl(), ox = wall.offset + (tilesize - width) / 2f, oy = wall.offset + (tilesize - height) / 2f;
|
|
||||||
|
|
||||||
//force fit to tile
|
|
||||||
if(overlay.wallOre && !wall.synthetic()){
|
|
||||||
width = height = tilesize;
|
|
||||||
ox = oy = 0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.draw(idxWall, region,
|
|
||||||
wx * tilesize + ox,
|
|
||||||
wy * tilesize + oy,
|
|
||||||
width, height,
|
|
||||||
tile.build == null || !wall.rotate ? 0 : tile.build.rotdeg());
|
|
||||||
}else{
|
|
||||||
if(floor instanceof ColoredFloor){
|
|
||||||
mesh.setColor(Tmp.c1.set(tile.extraData | 0xff));
|
|
||||||
}
|
|
||||||
|
|
||||||
region = floor.variantRegions()[Mathf.randomSeed(idxWall, 0, floor.variantRegions().length - 1)];
|
|
||||||
|
|
||||||
mesh.draw(idxWall, region, wx * tilesize, wy * tilesize, 8, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
float offsetX = -((wall.size + 1) / 3) * tilesize, offsetY = -((wall.size + 1) / 3) * tilesize;
|
|
||||||
|
|
||||||
//draw non-synthetic wall or ore
|
|
||||||
if(!(wall.update || wall.destructible) && !useSyntheticWall && wall != Blocks.air){
|
|
||||||
region = getIcon(wall, idxWall);
|
|
||||||
|
|
||||||
if(wall == Blocks.cliff){
|
|
||||||
mesh.setColor(Tmp.c1.set(floor.mapColor).mul(1.6f));
|
|
||||||
region = ((Cliff)Blocks.cliff).editorCliffs[tile.data & 0xff];
|
|
||||||
}else if(wall instanceof ColoredWall){
|
|
||||||
mesh.setColor(Tmp.c1.set(tile.extraData | 0xff));
|
|
||||||
}
|
|
||||||
|
|
||||||
offsetX = tilesize / 2f - region.width * region.scl() / 2f;
|
|
||||||
offsetY = tilesize / 2f - region.height * region.scl() / 2f;
|
|
||||||
}else if((wall == Blocks.air || overlay.wallOre) && !overlay.isAir()){
|
|
||||||
if(floor.isLiquid){
|
|
||||||
mesh.setColor(Tmp.c1.set(1f, 1f, 1f, floor.overlayAlpha));
|
|
||||||
}
|
|
||||||
region = overlay.variantRegions()[Mathf.randomSeed(idxWall, 0, tile.overlay().variantRegions().length - 1)];
|
|
||||||
}else{
|
|
||||||
region = clearEditor;
|
|
||||||
}
|
|
||||||
|
|
||||||
float width = region.width * region.scl(), height = region.height * region.scl();
|
|
||||||
if(!wall.synthetic() && wall != Blocks.air && !wall.isMultiblock()){
|
|
||||||
offsetX = offsetY = 0f;
|
|
||||||
width = height = tilesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.draw(idxDecal, region, wx * tilesize + offsetX, wy * tilesize + offsetY, width, height);
|
|
||||||
mesh.setColor(Color.white);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(){
|
public void dispose(){
|
||||||
if(chunks == null){
|
if(chunks == null) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
for(int x = 0; x < chunks.length; x++){
|
for(int x = 0; x < chunks.length; x++){
|
||||||
for(int y = 0; y < chunks[0].length; y++){
|
for(int y = 0; y < chunks[0].length; y++){
|
||||||
if(chunks[x][y] != null){
|
if(chunks[x][y] != null){
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ public class MapView extends Element implements GestureListener{
|
|||||||
Draw.color(Pal.remove);
|
Draw.color(Pal.remove);
|
||||||
Lines.stroke(2f);
|
Lines.stroke(2f);
|
||||||
Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2);
|
Lines.rect(centerx - sclwidth / 2 - 1, centery - sclheight / 2 - 1, sclwidth + 2, sclheight + 2);
|
||||||
editor.renderer.draw(centerx - sclwidth / 2 + Core.scene.marginLeft, centery - sclheight / 2 + Core.scene.marginBottom, sclwidth, sclheight, zoom);
|
editor.renderer.draw(centerx - sclwidth / 2 + Core.scene.marginLeft, centery - sclheight / 2 + Core.scene.marginBottom, sclwidth, sclheight);
|
||||||
Draw.reset();
|
Draw.reset();
|
||||||
|
|
||||||
if(grid){
|
if(grid){
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public class CacheLayer{
|
|||||||
|
|
||||||
renderer.effectBuffer.begin();
|
renderer.effectBuffer.begin();
|
||||||
Core.graphics.clear(Color.clear);
|
Core.graphics.clear(Color.clear);
|
||||||
renderer.blocks.floor.beginc();
|
renderer.blocks.floor.beginDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,7 +110,7 @@ public class CacheLayer{
|
|||||||
|
|
||||||
renderer.effectBuffer.end();
|
renderer.effectBuffer.end();
|
||||||
renderer.effectBuffer.blit(shader);
|
renderer.effectBuffer.blit(shader);
|
||||||
renderer.blocks.floor.beginc();
|
renderer.blocks.floor.beginDraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,10 @@ public class FloorRenderer{
|
|||||||
return indexData;
|
return indexData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float[] getVertexBuffer(){
|
||||||
|
return vertices;
|
||||||
|
}
|
||||||
|
|
||||||
/** Queues up a cache change for a tile. Only runs in render loop. */
|
/** Queues up a cache change for a tile. Only runs in render loop. */
|
||||||
public void recacheTile(Tile tile){
|
public void recacheTile(Tile tile){
|
||||||
recacheTile(tile.x, tile.y);
|
recacheTile(tile.x, tile.y);
|
||||||
@@ -183,14 +187,6 @@ public class FloorRenderer{
|
|||||||
underwaterDraw.clear();
|
underwaterDraw.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginc(){
|
|
||||||
shader.bind();
|
|
||||||
shader.setUniformMatrix4("u_projectionViewMatrix", Core.camera.mat);
|
|
||||||
|
|
||||||
//only ever use the base environment texture
|
|
||||||
texture.bind(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkChanges(){
|
public void checkChanges(){
|
||||||
if(recacheSet.size > 0){
|
if(recacheSet.size > 0){
|
||||||
//recache one chunk at a time
|
//recache one chunk at a time
|
||||||
@@ -215,7 +211,11 @@ public class FloorRenderer{
|
|||||||
|
|
||||||
Draw.flush();
|
Draw.flush();
|
||||||
|
|
||||||
beginc();
|
shader.bind();
|
||||||
|
shader.setUniformMatrix4("u_projectionViewMatrix", Core.camera.mat);
|
||||||
|
|
||||||
|
//only ever use the base environment texture
|
||||||
|
texture.bind(0);
|
||||||
|
|
||||||
Gl.enable(Gl.blend);
|
Gl.enable(Gl.blend);
|
||||||
}
|
}
|
||||||
@@ -343,7 +343,7 @@ public class FloorRenderer{
|
|||||||
(cx+1) * tilesize * chunksize + tilesize/2f, (cy+1) * tilesize * chunksize + tilesize/2f);
|
(cx+1) * tilesize * chunksize + tilesize/2f, (cy+1) * tilesize * chunksize + tilesize/2f);
|
||||||
|
|
||||||
mesh.setVertices(vertices, 0, vidx);
|
mesh.setVertices(vertices, 0, vidx);
|
||||||
//all vertices are shared
|
//all indices are shared and identical
|
||||||
mesh.indices = indexData;
|
mesh.indices = indexData;
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
|
|||||||
@@ -1,211 +0,0 @@
|
|||||||
package mindustry.graphics;
|
|
||||||
|
|
||||||
import arc.graphics.*;
|
|
||||||
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;
|
|
||||||
|
|
||||||
private final static Shader program = new Shader(
|
|
||||||
"""
|
|
||||||
attribute vec4 a_position;
|
|
||||||
attribute vec4 a_color;
|
|
||||||
attribute vec2 a_texCoord0;
|
|
||||||
uniform mat4 u_projTrans;
|
|
||||||
varying vec4 v_color;
|
|
||||||
varying vec2 v_texCoords;
|
|
||||||
void main(){
|
|
||||||
v_color = a_color;
|
|
||||||
v_color.a = v_color.a * (255.0/254.0);
|
|
||||||
v_texCoords = a_texCoord0;
|
|
||||||
gl_Position = u_projTrans * a_position;
|
|
||||||
}
|
|
||||||
""",
|
|
||||||
|
|
||||||
"""
|
|
||||||
varying lowp vec4 v_color;
|
|
||||||
varying vec2 v_texCoords;
|
|
||||||
uniform sampler2D u_texture;
|
|
||||||
void main(){
|
|
||||||
gl_FragColor = v_color * texture2D(u_texture, v_texCoords);
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
);
|
|
||||||
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();
|
|
||||||
private Mat combined = new Mat();
|
|
||||||
private float color = Color.white.toFloatBits();
|
|
||||||
|
|
||||||
public IndexedRenderer(int sprites){
|
|
||||||
resize(sprites);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(Texture texture){
|
|
||||||
Gl.enable(Gl.blend);
|
|
||||||
|
|
||||||
updateMatrix();
|
|
||||||
|
|
||||||
program.bind();
|
|
||||||
texture.bind();
|
|
||||||
|
|
||||||
program.setUniformMatrix4("u_projTrans", combined);
|
|
||||||
|
|
||||||
mesh.render(program, Gl.triangles, 0, mesh.getMaxVertices() * 6 / 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(Color color){
|
|
||||||
this.color = color.toFloatBits();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(int index, TextureRegion region, float x, float y, float w, float h){
|
|
||||||
float fx2 = x + w;
|
|
||||||
float fy2 = y + h;
|
|
||||||
float u = region.u;
|
|
||||||
float v = region.v2;
|
|
||||||
float u2 = region.u2;
|
|
||||||
float v2 = region.v;
|
|
||||||
|
|
||||||
float[] vertices = tmpVerts;
|
|
||||||
float color = this.color;
|
|
||||||
|
|
||||||
int idx = 0;
|
|
||||||
vertices[idx++] = x;
|
|
||||||
vertices[idx++] = y;
|
|
||||||
vertices[idx++] = color;
|
|
||||||
vertices[idx++] = u;
|
|
||||||
vertices[idx++] = v;
|
|
||||||
|
|
||||||
vertices[idx++] = x;
|
|
||||||
vertices[idx++] = fy2;
|
|
||||||
vertices[idx++] = color;
|
|
||||||
vertices[idx++] = u;
|
|
||||||
vertices[idx++] = v2;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
int dest = index * vsize * 4;
|
|
||||||
|
|
||||||
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){
|
|
||||||
float u = region.u;
|
|
||||||
float v = region.v2;
|
|
||||||
float u2 = region.u2;
|
|
||||||
float v2 = region.v;
|
|
||||||
|
|
||||||
float originX = w / 2, originY = h / 2;
|
|
||||||
|
|
||||||
float cos = Mathf.cosDeg(rotation);
|
|
||||||
float sin = Mathf.sinDeg(rotation);
|
|
||||||
|
|
||||||
float fx = -originX;
|
|
||||||
float fy = -originY;
|
|
||||||
float fx2 = w - originX;
|
|
||||||
float fy2 = h - originY;
|
|
||||||
|
|
||||||
float worldOriginX = x + originX;
|
|
||||||
float worldOriginY = y + originY;
|
|
||||||
|
|
||||||
float x1 = cos * fx - sin * fy + worldOriginX;
|
|
||||||
float y1 = sin * fx + cos * fy + worldOriginY;
|
|
||||||
float x2 = cos * fx - sin * fy2 + worldOriginX;
|
|
||||||
float y2 = sin * fx + cos * fy2 + worldOriginY;
|
|
||||||
float x3 = cos * fx2 - sin * fy2 + worldOriginX;
|
|
||||||
float y3 = sin * fx2 + cos * fy2 + worldOriginY;
|
|
||||||
float x4 = x1 + (x3 - x2);
|
|
||||||
float y4 = y3 - (y2 - y1);
|
|
||||||
|
|
||||||
float[] vertices = tmpVerts;
|
|
||||||
float color = this.color;
|
|
||||||
|
|
||||||
int idx = 0;
|
|
||||||
vertices[idx++] = x1;
|
|
||||||
vertices[idx++] = y1;
|
|
||||||
vertices[idx++] = color;
|
|
||||||
vertices[idx++] = u;
|
|
||||||
vertices[idx++] = v;
|
|
||||||
|
|
||||||
vertices[idx++] = x2;
|
|
||||||
vertices[idx++] = y2;
|
|
||||||
vertices[idx++] = color;
|
|
||||||
vertices[idx++] = u;
|
|
||||||
vertices[idx++] = v2;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
int dest = index * vsize * 4;
|
|
||||||
|
|
||||||
buffer.position(dest);
|
|
||||||
buffer.put(vertices);
|
|
||||||
|
|
||||||
//mark dirty
|
|
||||||
mesh.getVerticesBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mat getTransformMatrix(){
|
|
||||||
return transMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProjectionMatrix(Mat matrix){
|
|
||||||
projMatrix = matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resize(int sprites){
|
|
||||||
if(mesh != null) mesh.dispose();
|
|
||||||
|
|
||||||
mesh = new Mesh(true, 4 * sprites, 0,
|
|
||||||
VertexAttribute.position,
|
|
||||||
VertexAttribute.color,
|
|
||||||
VertexAttribute.texCoords);
|
|
||||||
|
|
||||||
buffer = mesh.getVerticesBuffer();
|
|
||||||
buffer.limit(buffer.capacity());
|
|
||||||
|
|
||||||
mesh.indices = Vars.renderer.blocks.floor.getIndexData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMatrix(){
|
|
||||||
combined.set(projMatrix).mul(transMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose(){
|
|
||||||
mesh.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user