mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-09 10:18:40 +07:00
Smooth block shadows / Large procedural blocks
This commit is contained in:
parent
f31fd622dd
commit
5a9307e9a7
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;
|
||||
|
||||
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 |
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
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());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user