Smooth block shadows / Large procedural blocks
This commit is contained in:
BIN
core/assets-raw/sprites/blocks/environment/rocks-large.png
Normal file
BIN
core/assets-raw/sprites/blocks/environment/rocks-large.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -5,18 +5,13 @@ precision mediump int;
|
|||||||
|
|
||||||
uniform sampler2D u_texture;
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
const float round = 0.23;
|
const float round = 0.01;
|
||||||
|
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
varying vec2 v_texCoord;
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 color = texture2D(u_texture, v_texCoord.xy);
|
vec4 color = texture2D(u_texture, v_texCoord.xy);
|
||||||
color.a = 1.0 - color.r;
|
color = vec4(0.0, 0.0, 0.0, 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;
|
|
||||||
}
|
|
||||||
gl_FragColor = color * v_color;
|
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 |
@@ -173,6 +173,7 @@ public class Renderer implements ApplicationListener{
|
|||||||
|
|
||||||
blocks.drawShadows();
|
blocks.drawShadows();
|
||||||
blocks.drawBlocks(Layer.block);
|
blocks.drawBlocks(Layer.block);
|
||||||
|
blocks.drawFog();
|
||||||
|
|
||||||
Draw.shader(Shaders.blockbuild, true);
|
Draw.shader(Shaders.blockbuild, true);
|
||||||
blocks.drawBlocks(Layer.placement);
|
blocks.drawBlocks(Layer.placement);
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import io.anuke.arc.collection.Sort;
|
|||||||
import io.anuke.arc.entities.EntityDraw;
|
import io.anuke.arc.entities.EntityDraw;
|
||||||
import io.anuke.arc.entities.EntityGroup;
|
import io.anuke.arc.entities.EntityGroup;
|
||||||
import io.anuke.arc.graphics.Color;
|
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.Draw;
|
||||||
|
import io.anuke.arc.graphics.g2d.Fill;
|
||||||
import io.anuke.arc.graphics.glutils.FrameBuffer;
|
import io.anuke.arc.graphics.glutils.FrameBuffer;
|
||||||
import io.anuke.arc.util.Tmp;
|
import io.anuke.arc.util.Tmp;
|
||||||
import io.anuke.mindustry.content.Blocks;
|
import io.anuke.mindustry.content.Blocks;
|
||||||
@@ -34,6 +36,7 @@ public class BlockRenderer{
|
|||||||
private int requestidx = 0;
|
private int requestidx = 0;
|
||||||
private int iterateidx = 0;
|
private int iterateidx = 0;
|
||||||
private FrameBuffer shadows = new FrameBuffer(2, 2);
|
private FrameBuffer shadows = new FrameBuffer(2, 2);
|
||||||
|
private FrameBuffer fog = new FrameBuffer(2, 2);
|
||||||
|
|
||||||
public BlockRenderer(){
|
public BlockRenderer(){
|
||||||
|
|
||||||
@@ -43,6 +46,28 @@ public class BlockRenderer{
|
|||||||
|
|
||||||
Events.on(WorldLoadEvent.class, event -> {
|
Events.on(WorldLoadEvent.class, event -> {
|
||||||
lastCamY = lastCamX = -99; //invalidate camera position so blocks get updated
|
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 -> {
|
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(){
|
public void drawShadows(){
|
||||||
if(disableShadows) return;
|
if(disableShadows) return;
|
||||||
|
|
||||||
@@ -122,10 +162,6 @@ public class BlockRenderer{
|
|||||||
Tile tile = world.rawTile(x, y);
|
Tile tile = world.rawTile(x, y);
|
||||||
Block block = tile.block();
|
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(block != Blocks.air && block.cacheLayer == CacheLayer.normal){
|
||||||
if(!expanded){
|
if(!expanded){
|
||||||
addRequest(tile, Layer.shadow);
|
addRequest(tile, Layer.shadow);
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ public class DeployDialog extends FloatingDialog{
|
|||||||
layout.gapBetweenNodes = 40f;
|
layout.gapBetweenNodes = 40f;
|
||||||
layout.layout(root);
|
layout.layout(root);
|
||||||
|
|
||||||
cont.setFillParent(true);
|
|
||||||
|
|
||||||
addCloseButton();
|
addCloseButton();
|
||||||
buttons.addImageTextButton("$techtree", "icon-tree", 16 * 2, () -> ui.tech.show()).size(230f, 64f);
|
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(){
|
public void setup(){
|
||||||
cont.clear();
|
cont.clear();
|
||||||
|
titleTable.remove();
|
||||||
|
marginTop(0f);
|
||||||
|
|
||||||
cont.stack(new Table(){{
|
cont.stack(control.saves.getZoneSlot() == null ? new View() : 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(){{
|
|
||||||
SaveSlot slot = control.saves.getZoneSlot();
|
SaveSlot slot = control.saves.getZoneSlot();
|
||||||
|
|
||||||
TextButton[] b = {null};
|
TextButton[] b = {null};
|
||||||
@@ -106,6 +93,19 @@ public class DeployDialog extends FloatingDialog{
|
|||||||
});
|
});
|
||||||
}).growX().height(50f).pad(-12).padTop(10);
|
}).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();
|
}}).grow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,16 @@ package io.anuke.mindustry.world.blocks;
|
|||||||
import io.anuke.arc.Core;
|
import io.anuke.arc.Core;
|
||||||
import io.anuke.arc.graphics.g2d.Draw;
|
import io.anuke.arc.graphics.g2d.Draw;
|
||||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||||
|
import io.anuke.arc.math.Mathf;
|
||||||
import io.anuke.mindustry.graphics.CacheLayer;
|
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{
|
public class StaticWall extends Rock{
|
||||||
TextureRegion[][] regions;
|
TextureRegion large;
|
||||||
|
|
||||||
public StaticWall(String name){
|
public StaticWall(String name){
|
||||||
super(name);
|
super(name);
|
||||||
@@ -15,10 +21,45 @@ public class StaticWall extends Rock{
|
|||||||
cacheLayer = CacheLayer.walls;
|
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
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
super.load();
|
super.load();
|
||||||
int size = (int)(8 / Draw.scl);
|
large = Core.atlas.find(name + "-large");
|
||||||
regions = Core.atlas.find("mountains-tiles").split(size, size);
|
}
|
||||||
|
|
||||||
|
//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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
core/src/io/anuke/mindustry/world/blocks/TreeBlock.java
Normal file
23
core/src/io/anuke/mindustry/world/blocks/TreeBlock.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user