Smooth block shadows / Large procedural blocks

This commit is contained in:
Anuken 2019-01-27 12:09:01 -05:00
parent f31fd622dd
commit 5a9307e9a7
9 changed files with 1336 additions and 1233 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -5,18 +5,13 @@ precision mediump int;
uniform sampler2D u_texture;
const float round = 0.23;
const float round = 0.01;
varying vec4 v_color;
varying vec2 v_texCoord;
void main() {
vec4 color = texture2D(u_texture, v_texCoord.xy);
color.a = 1.0 - color.r;
color.rgb = vec3(0.0);
color.a = float(int(color.a / round)) * round;
if(color.a >= 1.0 - round){
color.a = 1.0;
}
color = vec4(0.0, 0.0, 0.0, 1.0 - color.r);
gl_FragColor = color * v_color;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@ -173,6 +173,7 @@ public class Renderer implements ApplicationListener{
blocks.drawShadows();
blocks.drawBlocks(Layer.block);
blocks.drawFog();
Draw.shader(Shaders.blockbuild, true);
blocks.drawBlocks(Layer.placement);

View File

@ -7,7 +7,9 @@ import io.anuke.arc.collection.Sort;
import io.anuke.arc.entities.EntityDraw;
import io.anuke.arc.entities.EntityGroup;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.Texture.TextureFilter;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.Fill;
import io.anuke.arc.graphics.glutils.FrameBuffer;
import io.anuke.arc.util.Tmp;
import io.anuke.mindustry.content.Blocks;
@ -34,6 +36,7 @@ public class BlockRenderer{
private int requestidx = 0;
private int iterateidx = 0;
private FrameBuffer shadows = new FrameBuffer(2, 2);
private FrameBuffer fog = new FrameBuffer(2, 2);
public BlockRenderer(){
@ -43,6 +46,28 @@ public class BlockRenderer{
Events.on(WorldLoadEvent.class, event -> {
lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated
fog.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
fog.resize(world.width(), world.height());
fog.begin();
Core.graphics.clear(Color.WHITE);
Draw.proj().setOrtho(0, 0, fog.getWidth(), fog.getHeight());
//TODO highly inefficient, width*height rectangles isn't great
//TODO handle shadows with GPU
for(int x = 0; x < world.width(); x++){
for(int y = 0; y < world.height(); y++){
Tile tile = world.rawTile(x, y);
if(tile.getRotation() > 0){
Draw.color(0f, 0f, 0f, Math.min((tile.getRotation() + 0.5f)/4f, 1f));
Fill.rect(tile.x + 0.5f, tile.y + 0.5f, 1, 1);
}
}
}
Draw.flush();
Draw.color();
fog.end();
});
Events.on(TileChangeEvent.class, event -> {
@ -57,6 +82,21 @@ public class BlockRenderer{
});
}
public void drawFog(){
float ww = world.width() * tilesize, wh = world.height() * tilesize;
float u = (camera.position.x - camera.width/2f) / ww,
v = (camera.position.y - camera.height/2f) / wh,
u2 = (camera.position.x + camera.width/2f) / ww,
v2 = (camera.position.y + camera.height/2f) / wh;
Tmp.tr1.set(fog.getTexture());
Tmp.tr1.set(u, v2, u2, v);
Draw.shader(Shaders.fog);
Draw.rect(Tmp.tr1, camera.position.x, camera.position.y, camera.width, camera.height);
Draw.shader();
}
public void drawShadows(){
if(disableShadows) return;
@ -122,10 +162,6 @@ public class BlockRenderer{
Tile tile = world.rawTile(x, y);
Block block = tile.block();
if(!expanded && block != Blocks.air && block.cacheLayer == CacheLayer.normal && world.isAccessible(x, y)){
tile.block().drawShadow(tile);
}
if(block != Blocks.air && block.cacheLayer == CacheLayer.normal){
if(!expanded){
addRequest(tile, Layer.shadow);

View File

@ -41,8 +41,6 @@ public class DeployDialog extends FloatingDialog{
layout.gapBetweenNodes = 40f;
layout.layout(root);
cont.setFillParent(true);
addCloseButton();
buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f);
@ -51,21 +49,10 @@ public class DeployDialog extends FloatingDialog{
public void setup(){
cont.clear();
titleTable.remove();
marginTop(0f);
cont.stack(new Table(){{
top().left().margin(10);
ObjectIntMap<Item> items = data.items();
for(Item item : content.items()){
if(item.type == ItemType.material && data.isUnlocked(item)){
label(() -> items.get(item, 0) + "").left();
addImage(item.region).size(8*4).pad(4);
add("[LIGHT_GRAY]" + item.localizedName()).left();
row();
}
}
}}, control.saves.getZoneSlot() == null ? new View() : new Table(){{
cont.stack(control.saves.getZoneSlot() == null ? new View() : new Table(){{
SaveSlot slot = control.saves.getZoneSlot();
TextButton[] b = {null};
@ -106,6 +93,19 @@ public class DeployDialog extends FloatingDialog{
});
}).growX().height(50f).pad(-12).padTop(10);
}}, new Table(){{
top().left().margin(10);
ObjectIntMap<Item> items = data.items();
for(Item item : content.items()){
if(item.type == ItemType.material && data.isUnlocked(item)){
label(() -> items.get(item, 0) + "").left();
addImage(item.region).size(8*4).pad(4);
add("[LIGHT_GRAY]" + item.localizedName()).left();
row();
}
}
}}).grow();
}

View File

@ -3,10 +3,16 @@ package io.anuke.mindustry.world.blocks;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.graphics.CacheLayer;
import io.anuke.mindustry.world.Pos;
import io.anuke.mindustry.world.Tile;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class StaticWall extends Rock{
TextureRegion[][] regions;
TextureRegion large;
public StaticWall(String name){
super(name);
@ -15,10 +21,45 @@ public class StaticWall extends Rock{
cacheLayer = CacheLayer.walls;
}
@Override
public void draw(Tile tile){
//Draw.colorl(1f - tile.getRotation() / 4f);
int rx = tile.x / 2 * 2;
int ry = tile.y / 2 * 2;
if(Core.atlas.isFound(large) && eq(rx, ry) && Mathf.randomSeed(Pos.get(rx, ry)) < 0.5){
if(rx == tile.x && ry == tile.y){
//Draw.colorl(1f - avg(rx, ry) / 4f);
Draw.rect(large, tile.worldx() + tilesize/2f, tile.worldy() + tilesize/2f);
}
}else if(variants > 0){
Draw.rect(regions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, regions.length - 1))], tile.worldx(), tile.worldy());
}else{
Draw.rect(region, tile.worldx(), tile.worldy());
}
// Draw.color();
}
@Override
public void load(){
super.load();
int size = (int)(8 / Draw.scl);
regions = Core.atlas.find("mountains-tiles").split(size, size);
large = Core.atlas.find(name + "-large");
}
//two functions for calculating 2x2 tile brightness
int min(int rx, int ry){
return Math.min(world.tile(rx + 1, ry).getRotation(), Math.min(world.tile(rx, ry).getRotation(), Math.min(world.tile(rx + 1, ry + 1).getRotation(), world.tile(rx, ry + 1).getRotation())));
}
int avg(int rx, int ry){
return (world.tile(rx + 1, ry).getRotation() + world.tile(rx, ry).getRotation() + world.tile(rx + 1, ry + 1).getRotation() + world.tile(rx, ry + 1).getRotation()) / 4;
}
boolean eq(int rx, int ry){
return world.tile(rx + 1, ry).block() == this
&& world.tile(rx, ry + 1).block() == this
&& world.tile(rx, ry).block() == this
&& world.tile(rx + 1, ry + 1).block() == this;
}
}

View File

@ -0,0 +1,23 @@
package io.anuke.mindustry.world.blocks;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
public class TreeBlock extends Block{
public TreeBlock(String name){
super(name);
solid = true;
layer = Layer.power;
}
@Override
public void draw(Tile tile){}
@Override
public void drawLayer(Tile tile){
Draw.rect(region, tile.drawx(), tile.drawy());
}
}