From 79c7aa91f863606ed16b6c9a6a5b95f38c761698 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Thu, 27 Aug 2020 20:58:27 +0300 Subject: [PATCH] Optimized tile render and added CRO tile support - CROs now support tiles - CROCube refactored - Test content: - Added sand and flower tiles - Removed grass blocks, added grass tiles --- .../progressia/client/world/ChunkRender.java | 55 ++--- .../client/world/renders/BlockRender.java | 5 - .../client/world/renders/BlockRenders.java | 5 +- .../client/world/renders/TileRenderGrass.java | 65 ++++++ .../world/renders/TileRenderSimple.java | 19 +- .../client/world/renders/TileRenders.java | 4 + .../renders/cro/ChunkRenderOptimizer.java | 13 +- .../renders/cro/ChunkRenderOptimizerCube.java | 219 +++++++++++++----- .../common/block/BlockDataRegistry.java | 1 - .../common/block/TileDataRegistry.java | 3 + .../progressia/common/world/ChunkData.java | 28 ++- .../blocks/{grass_bottom.png => dirt.png} | Bin .../assets/textures/blocks/grass_side.png | Bin 1979 -> 0 bytes .../assets/textures/tiles/grass_side.png | Bin 0 -> 5812 bytes .../textures/{blocks => tiles}/grass_top.png | Bin .../resources/assets/textures/tiles/sand.png | Bin 0 -> 6733 bytes .../assets/textures/tiles/yellow_flowers.png | Bin 0 -> 334 bytes 17 files changed, 312 insertions(+), 105 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderGrass.java rename src/main/resources/assets/textures/blocks/{grass_bottom.png => dirt.png} (100%) delete mode 100644 src/main/resources/assets/textures/blocks/grass_side.png create mode 100644 src/main/resources/assets/textures/tiles/grass_side.png rename src/main/resources/assets/textures/{blocks => tiles}/grass_top.png (100%) create mode 100644 src/main/resources/assets/textures/tiles/sand.png create mode 100644 src/main/resources/assets/textures/tiles/yellow_flowers.png diff --git a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java index dea8fa2..122ad19 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/ChunkRender.java @@ -19,13 +19,13 @@ package ru.windcorp.progressia.client.world; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import glm.mat._4.Mat4; import glm.vec._3.Vec3; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.Model; -import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.StaticModel; import ru.windcorp.progressia.client.graphics.model.WorldRenderable; @@ -114,12 +114,10 @@ public class ChunkRender { } } - for (ChunkRenderOptimizer optimizer : optimizers) { - Shape result = optimizer.endRender(); - if (result != null) { - builder.addPart(result); - } - } + optimizers.stream() + .map(ChunkRenderOptimizer::endRender) + .filter(Objects::nonNull) + .forEach(builder::addPart); model = new StaticModel(builder); needsUpdate = false; @@ -131,55 +129,41 @@ public class ChunkRender { Builder builder ) { BlockRender block = getBlock(cursor); - int x = cursor.x; - int y = cursor.y; - int z = cursor.z; if (block instanceof BlockRenderNone) { return; } - forwardBlockToOptimizers(block, x, y, z, optimizers); + forwardBlockToOptimizers(block, cursor, optimizers); if (!block.needsOwnRenderable()) { return; } - if (tryToCreateBlockRenderable(block, x, y, z, builder)) { - return; - } - - addBlockRenderAsRenderable(block, x, y, z, builder); + addBlockRenderable(block, cursor, builder); } private void forwardBlockToOptimizers( - BlockRender block, int x, int y, int z, + BlockRender block, Vec3i cursor, Collection optimizers ) { - optimizers.forEach(bro -> bro.processBlock(block, x, y, z)); + optimizers.forEach(cro -> cro.processBlock(block, cursor)); } - - private boolean tryToCreateBlockRenderable( - BlockRender block, int x, int y, int z, + + private void addBlockRenderable( + BlockRender block, + Vec3i cursor, Builder builder ) { WorldRenderable renderable = block.createRenderable(); if (renderable == null) { - return false; + renderable = block::render; } - builder.addPart(renderable, new Mat4().identity().translate(x, y, z)); - return true; - } - - private void addBlockRenderAsRenderable( - BlockRender block, int x, int y, int z, - Builder builder - ) { builder.addPart( - block::render, - new Mat4().identity().translate(x, y, z) + renderable, + new Mat4().identity().translate(cursor.x, cursor.y, cursor.z) ); } @@ -230,6 +214,13 @@ public class ChunkRender { Vec3 pos = Vectors.grab3().set(cursor.x, cursor.y, cursor.z); + optimizers.forEach(cro -> cro.processTile(tile, cursor, face)); + + if (!tile.needsOwnRenderable()) { + Vectors.release(pos); + return; + } + Vec3 offset = Vectors.grab3().set( face.getVector().x, face.getVector().y, face.getVector().z ); diff --git a/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRender.java b/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRender.java index 7d4f218..b0635d1 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRender.java +++ b/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRender.java @@ -19,7 +19,6 @@ package ru.windcorp.progressia.client.world.renders; import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper; import ru.windcorp.progressia.client.graphics.model.WorldRenderable; -import ru.windcorp.progressia.client.world.renders.cro.ChunkRenderOptimizer; import ru.windcorp.progressia.common.util.Namespaced; public abstract class BlockRender extends Namespaced { @@ -38,10 +37,6 @@ public abstract class BlockRender extends Namespaced { return null; } - public boolean canBeOptimized(ChunkRenderOptimizer optimizer) { - return true; - } - public boolean needsOwnRenderable() { return true; } diff --git a/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRenders.java b/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRenders.java index cc1cd6f..5c48a36 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRenders.java +++ b/src/main/java/ru/windcorp/progressia/client/world/renders/BlockRenders.java @@ -34,9 +34,7 @@ public class BlockRenders { private static final AtlasGroup BLOCKS_ATLAS_GROUP = new AtlasGroup("Blocks", 1 << 12); - private static Texture grassTop = getTexture("grass_top"); - private static Texture grassSide = getTexture("grass_side"); - private static Texture dirt = getTexture("grass_bottom"); + private static Texture dirt = getTexture("dirt"); private static Texture stone = getTexture("stone"); private static Texture glass = getTexture("glass_clear"); private static Texture compass = getTexture("compass"); @@ -44,7 +42,6 @@ public class BlockRenders { private BlockRenders() {} public static void registerTest() { - register(new BlockRenderOpaqueCube("Test", "Grass", grassTop, dirt, grassSide, grassSide, grassSide, grassSide)); register(new BlockRenderOpaqueCube("Test", "Dirt", dirt, dirt, dirt, dirt, dirt, dirt)); register(new BlockRenderOpaqueCube("Test", "Stone", stone, stone, stone, stone, stone, stone)); diff --git a/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderGrass.java b/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderGrass.java new file mode 100644 index 0000000..05fbed0 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderGrass.java @@ -0,0 +1,65 @@ +package ru.windcorp.progressia.client.world.renders; + +import glm.vec._3.Vec3; +import ru.windcorp.progressia.client.graphics.backend.Usage; +import ru.windcorp.progressia.client.graphics.model.Faces; +import ru.windcorp.progressia.client.graphics.model.Shape; +import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram; +import ru.windcorp.progressia.client.graphics.model.WorldRenderable; +import ru.windcorp.progressia.client.graphics.texture.Texture; +import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.client.world.renders.cro.ChunkRenderOptimizerCube.OpaqueTile; +import ru.windcorp.progressia.common.block.BlockFace; +import ru.windcorp.progressia.common.util.Vectors; + +public class TileRenderGrass extends TileRender implements OpaqueTile { + + private final Texture topTexture; + private final Texture sideTexture; + + public TileRenderGrass( + String namespace, String name, + Texture top, Texture side + ) { + super(namespace, name); + this.topTexture = top; + this.sideTexture = side; + } + + @Override + public Texture getTexture(BlockFace face) { + return (face == BlockFace.TOP) ? topTexture : sideTexture; + } + + @Override + public boolean isOpaque(BlockFace face) { + return face == BlockFace.TOP; + } + + @Override + public WorldRenderable createRenderable(BlockFace face) { + ShapeRenderProgram program = WorldRenderProgram.getDefault(); + + Vec3 color = Vectors.grab3().set(1, 1, 1); + Vec3 center = Vectors.grab3().set(0, 0, 0); + + try { + return new Shape( + Usage.STATIC, WorldRenderProgram.getDefault(), + Faces.createBlockFace( + program, getTexture(face), color, + center, face, false + ) + ); + } finally { + Vectors.release(color); + Vectors.release(center); + } + } + + @Override + public boolean needsOwnRenderable() { + return false; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderSimple.java b/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderSimple.java index 61dbf52..889be5b 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderSimple.java +++ b/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenderSimple.java @@ -8,10 +8,11 @@ import ru.windcorp.progressia.client.graphics.model.ShapeRenderProgram; import ru.windcorp.progressia.client.graphics.model.WorldRenderable; import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; +import ru.windcorp.progressia.client.world.renders.cro.ChunkRenderOptimizerCube.OpaqueTile; import ru.windcorp.progressia.common.block.BlockFace; import ru.windcorp.progressia.common.util.Vectors; -public class TileRenderSimple extends TileRender { +public class TileRenderSimple extends TileRender implements OpaqueTile { private final Texture texture; @@ -20,10 +21,16 @@ public class TileRenderSimple extends TileRender { this.texture = texture; } - public Texture getTexture() { + @Override + public Texture getTexture(BlockFace face) { return texture; } + @Override + public boolean isOpaque(BlockFace face) { + return false; + } + @Override public WorldRenderable createRenderable(BlockFace face) { ShapeRenderProgram program = WorldRenderProgram.getDefault(); @@ -35,7 +42,8 @@ public class TileRenderSimple extends TileRender { return new Shape( Usage.STATIC, WorldRenderProgram.getDefault(), Faces.createBlockFace( - program, texture, color, center, face, false + program, getTexture(face), color, + center, face, false ) ); } finally { @@ -43,5 +51,10 @@ public class TileRenderSimple extends TileRender { Vectors.release(center); } } + + @Override + public boolean needsOwnRenderable() { + return false; + } } diff --git a/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenders.java b/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenders.java index 3c464ee..94a995c 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenders.java +++ b/src/main/java/ru/windcorp/progressia/client/world/renders/TileRenders.java @@ -37,7 +37,11 @@ public class TileRenders { private TileRenders() {} public static void registerTest() { + register(new TileRenderGrass("Test", "Grass", getTexture("grass_top"), getTexture("grass_side"))); + register(new TileRenderSimple("Test", "Stones", getTexture("stones"))); + register(new TileRenderSimple("Test", "YellowFlowers", getTexture("yellow_flowers"))); + register(new TileRenderSimple("Test", "Sand", getTexture("sand"))); } public static TileRender get(String name) { diff --git a/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizer.java b/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizer.java index abea2af..79153a2 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizer.java +++ b/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizer.java @@ -17,15 +17,26 @@ *******************************************************************************/ package ru.windcorp.progressia.client.world.renders.cro; +import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.client.graphics.model.Shape; import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.renders.BlockRender; +import ru.windcorp.progressia.client.world.renders.TileRender; +import ru.windcorp.progressia.common.block.BlockFace; public abstract class ChunkRenderOptimizer { public abstract void startRender(ChunkRender chunk); - public abstract void processBlock(BlockRender block, int x, int y, int z); + public abstract void processBlock( + BlockRender block, + Vec3i posInChunk + ); + + public abstract void processTile( + TileRender tile, + Vec3i posInChunk, BlockFace face + ); public abstract Shape endRender(); diff --git a/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizerCube.java b/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizerCube.java index 3048a85..a720d75 100644 --- a/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizerCube.java +++ b/src/main/java/ru/windcorp/progressia/client/world/renders/cro/ChunkRenderOptimizerCube.java @@ -17,7 +17,9 @@ *******************************************************************************/ package ru.windcorp.progressia.client.world.renders.cro; +import static ru.windcorp.progressia.common.block.BlockFace.BLOCK_FACE_COUNT; import static ru.windcorp.progressia.common.world.ChunkData.BLOCKS_PER_CHUNK; +import static ru.windcorp.progressia.common.world.ChunkData.TILES_PER_FACE; import java.util.ArrayList; import java.util.Collection; @@ -33,7 +35,9 @@ import ru.windcorp.progressia.client.graphics.texture.Texture; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.world.ChunkRender; import ru.windcorp.progressia.client.world.renders.BlockRender; +import ru.windcorp.progressia.client.world.renders.TileRender; import ru.windcorp.progressia.common.block.BlockFace; +import ru.windcorp.progressia.common.util.Vectors; public class ChunkRenderOptimizerCube extends ChunkRenderOptimizer { @@ -43,12 +47,58 @@ public class ChunkRenderOptimizerCube extends ChunkRenderOptimizer { public boolean isBlockOpaque(); } + public static interface OpaqueTile { + public Texture getTexture(BlockFace face); + public boolean isOpaque(BlockFace face); + } + + private static class BlockInfo { + OpaqueCube block; + final FaceInfo[] faces = new FaceInfo[BLOCK_FACE_COUNT]; + + { + for (int i = 0; i < faces.length; ++i) { + faces[i] = new FaceInfo(); + } + } + } + + private static class FaceInfo { + static final int NO_OPAQUE_TILES = -1; + + int topOpaqueTile = NO_OPAQUE_TILES; + final OpaqueTile[] tiles = new OpaqueTile[TILES_PER_FACE]; + int tileCount = 0; + } + private static final Vec3 COLOR_MULTIPLIER = new Vec3(1, 1, 1); - private final OpaqueCube[][][] data = - new OpaqueCube[BLOCKS_PER_CHUNK] - [BLOCKS_PER_CHUNK] - [BLOCKS_PER_CHUNK]; +// private final OpaqueCube[][][] blocks = +// new OpaqueCube[BLOCKS_PER_CHUNK] +// [BLOCKS_PER_CHUNK] +// [BLOCKS_PER_CHUNK]; +// +// private final OpaqueTile[][][][][] tiles = +// new OpaqueTile[BLOCKS_PER_CHUNK] +// [BLOCKS_PER_CHUNK] +// [BLOCKS_PER_CHUNK] +// [BLOCK_FACE_COUNT] +// [TILES_PER_FACE]; + + private final BlockInfo[][][] data = + new BlockInfo[BLOCKS_PER_CHUNK] + [BLOCKS_PER_CHUNK] + [BLOCKS_PER_CHUNK]; + + { + for (int x = 0; x < BLOCKS_PER_CHUNK; ++x) { + for (int y = 0; y < BLOCKS_PER_CHUNK; ++y) { + for (int z = 0; z < BLOCKS_PER_CHUNK; ++z) { + data[x][y][z] = new BlockInfo(); + } + } + } + } @Override public void startRender(ChunkRender chunk) { @@ -56,19 +106,43 @@ public class ChunkRenderOptimizerCube extends ChunkRenderOptimizer { } @Override - public void processBlock(BlockRender block, int x, int y, int z) { + public void processBlock(BlockRender block, Vec3i pos) { if (!(block instanceof OpaqueCube)) return; OpaqueCube opaqueCube = (OpaqueCube) block; - addBlock(x, y, z, opaqueCube); + addBlock(pos, opaqueCube); } - protected void addBlock(int x, int y, int z, OpaqueCube cube) { - data[x][y][z] = cube; + @Override + public void processTile(TileRender tile, Vec3i pos, BlockFace face) { + if (!(tile instanceof OpaqueTile)) return; + OpaqueTile opaqueTile = (OpaqueTile) tile; + addTile(pos, face, opaqueTile); + } + + protected void addBlock(Vec3i pos, OpaqueCube cube) { + getBlock(pos).block = cube; } - protected OpaqueCube getBlock(Vec3i cursor) { + private void addTile(Vec3i pos, BlockFace face, OpaqueTile opaqueTile) { + FaceInfo faceInfo = getFace(pos, face); + + int index = faceInfo.tileCount; + faceInfo.tileCount++; + + faceInfo.tiles[index] = opaqueTile; + + if (opaqueTile.isOpaque(face)) { + faceInfo.topOpaqueTile = index; + } + } + + protected BlockInfo getBlock(Vec3i cursor) { return data[cursor.x][cursor.y][cursor.z]; } + + protected FaceInfo getFace(Vec3i cursor, BlockFace face) { + return getBlock(cursor).faces[face.getId()]; + } @Override public Shape endRender() { @@ -82,12 +156,8 @@ public class ChunkRenderOptimizerCube extends ChunkRenderOptimizer { for (cursor.x = 0; cursor.x < BLOCKS_PER_CHUNK; ++cursor.x) { for (cursor.y = 0; cursor.y < BLOCKS_PER_CHUNK; ++cursor.y) { for (cursor.z = 0; cursor.z < BLOCKS_PER_CHUNK; ++cursor.z) { - OpaqueCube block = getBlock(cursor); - - if (block == null) continue; - - processInnerFaces(block, cursor, shapeFaces::add); - processOuterFaces(block, cursor, shapeFaces::add); + processInnerFaces(cursor, shapeFaces::add); + processOuterFaces(cursor, shapeFaces::add); } } } @@ -98,63 +168,83 @@ public class ChunkRenderOptimizerCube extends ChunkRenderOptimizer { shapeFaces.toArray(new Face[shapeFaces.size()]) ); } - - private void processInnerFaces( - OpaqueCube block, - Vec3i cursor, - Consumer output - ) { - if (block.isBlockOpaque()) return; - - for (BlockFace face : BlockFace.getFaces()) { - - Texture texture = block.getTexture(face); - if (texture == null) continue; - - output.accept(Faces.createBlockFace( - WorldRenderProgram.getDefault(), - texture, - COLOR_MULTIPLIER, - new Vec3(cursor.x, cursor.y, cursor.z), - face, - true - )); - - } - } private void processOuterFaces( - OpaqueCube block, Vec3i cursor, Consumer output ) { + Vec3 faceOrigin = Vectors.grab3(); + Vec3 offset = Vectors.grab3(); + for (BlockFace face : BlockFace.getFaces()) { + if (!shouldRenderOuterFace(cursor, face)) continue; - Texture texture = block.getTexture(face); - if (texture == null) continue; + faceOrigin.set(cursor.x, cursor.y, cursor.z); + offset + .set(face.getVector().x, face.getVector().y, face.getVector().z) + .mul(1f / 128); - if (!shouldRenderFace(cursor, face)) continue; + FaceInfo info = getFace(cursor, face); - output.accept(Faces.createBlockFace( - WorldRenderProgram.getDefault(), - texture, - COLOR_MULTIPLIER, - new Vec3(cursor.x, cursor.y, cursor.z), - face, - false - )); + if (info.topOpaqueTile == FaceInfo.NO_OPAQUE_TILES) { + OpaqueCube block = getBlock(cursor).block; + + if (block != null) { + addFace( + faceOrigin, face, + getBlock(cursor).block.getTexture(face), + output + ); + + faceOrigin.add(offset); + } + } + int startLayer = info.topOpaqueTile; + if (startLayer == FaceInfo.NO_OPAQUE_TILES) { + startLayer = 0; + } + + for (int layer = startLayer; layer < info.tileCount; ++layer) { + addFace( + faceOrigin, face, + info.tiles[layer].getTexture(face), + output + ); + + faceOrigin.add(offset); + } } + + Vectors.release(offset); + Vectors.release(faceOrigin); } - private boolean shouldRenderFace(Vec3i cursor, BlockFace face) { + private void addFace( + Vec3 cursor, BlockFace face, + Texture texture, + Consumer output + ) { + if (texture == null) return; + + output.accept(Faces.createBlockFace( + WorldRenderProgram.getDefault(), + texture, + COLOR_MULTIPLIER, + new Vec3(cursor), + face, + false + )); + } + + private boolean shouldRenderOuterFace(Vec3i cursor, BlockFace face) { cursor.add(face.getVector()); try { // TODO handle neighboring chunks properly if (!isInBounds(cursor)) return true; - OpaqueCube adjacent = getBlock(cursor); + OpaqueCube adjacent = getBlock(cursor).block; if (adjacent == null) return true; if (adjacent.isOpaque(face)) return false; @@ -166,6 +256,29 @@ public class ChunkRenderOptimizerCube extends ChunkRenderOptimizer { } } + private void processInnerFaces( + Vec3i cursor, + Consumer output + ) { +// if (block.isBlockOpaque()) return; +// +// for (BlockFace face : BlockFace.getFaces()) { +// +// Texture texture = block.getTexture(face); +// if (texture == null) continue; +// +// output.accept(Faces.createBlockFace( +// WorldRenderProgram.getDefault(), +// texture, +// COLOR_MULTIPLIER, +// new Vec3(cursor.x, cursor.y, cursor.z), +// face, +// true +// )); +// +// } + } + private boolean isInBounds(Vec3i cursor) { return isInBounds(cursor.x) && diff --git a/src/main/java/ru/windcorp/progressia/common/block/BlockDataRegistry.java b/src/main/java/ru/windcorp/progressia/common/block/BlockDataRegistry.java index 7aaafef..d7e67a4 100644 --- a/src/main/java/ru/windcorp/progressia/common/block/BlockDataRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/block/BlockDataRegistry.java @@ -25,7 +25,6 @@ public class BlockDataRegistry { private static final Map REGISTRY = new HashMap<>(); static { - register(new BlockData("Test", "Grass")); register(new BlockData("Test", "Dirt")); register(new BlockData("Test", "Stone")); register(new BlockData("Test", "Air")); diff --git a/src/main/java/ru/windcorp/progressia/common/block/TileDataRegistry.java b/src/main/java/ru/windcorp/progressia/common/block/TileDataRegistry.java index 9e9650f..2769546 100644 --- a/src/main/java/ru/windcorp/progressia/common/block/TileDataRegistry.java +++ b/src/main/java/ru/windcorp/progressia/common/block/TileDataRegistry.java @@ -25,7 +25,10 @@ public class TileDataRegistry { private static final Map REGISTRY = new HashMap<>(); static { + register(new TileData("Test", "Grass")); register(new TileData("Test", "Stones")); + register(new TileData("Test", "YellowFlowers")); + register(new TileData("Test", "Sand")); } public static TileData get(String name) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java index 58671df..6e7cfed 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/ChunkData.java @@ -59,12 +59,14 @@ public class ChunkData { } private void tmp_generate() { - BlockData grass = BlockDataRegistry.get("Test:Grass"); BlockData dirt = BlockDataRegistry.get("Test:Dirt"); BlockData stone = BlockDataRegistry.get("Test:Stone"); BlockData air = BlockDataRegistry.get("Test:Air"); - + + TileData grass = TileDataRegistry.get("Test:Grass"); TileData stones = TileDataRegistry.get("Test:Stones"); + TileData flowers = TileDataRegistry.get("Test:YellowFlowers"); + TileData sand = TileDataRegistry.get("Test:Sand"); Vec3i aPoint = new Vec3i(5, 0, BLOCKS_PER_CHUNK + BLOCKS_PER_CHUNK/2); Vec3i pos = new Vec3i(); @@ -95,12 +97,26 @@ public class ChunkData { for (pos.z = BLOCKS_PER_CHUNK - 1; pos.z >= 0 && getBlock(pos) == air; --pos.z); - setBlock(pos, grass); + getTiles(pos, BlockFace.TOP).add(grass); + for (BlockFace face : BlockFace.getFaces()) { + if (face.getVector().z != 0) continue; + getTiles(pos, face).add(grass); + } - int hash = x*x * 13 ^ y*y * 37 ^ pos.z*pos.z * 129; + int hash = x*x * 19 ^ y*y * 41 ^ pos.z*pos.z * 147; + if (hash % 5 == 0) { + getTiles(pos, BlockFace.TOP).add(sand); + } + + hash = x*x * 13 ^ y*y * 37 ^ pos.z*pos.z * 129; if (hash % 5 == 0) { getTiles(pos, BlockFace.TOP).add(stones); } + + hash = x*x * 17 ^ y*y * 39 ^ pos.z*pos.z * 131; + if (hash % 9 == 0) { + getTiles(pos, BlockFace.TOP).add(flowers); + } } } } @@ -218,8 +234,8 @@ public class ChunkData { return (blockInChunk.x == min && face == SOUTH ) || (blockInChunk.x == max && face == NORTH ) || - (blockInChunk.y == min && face == WEST ) || - (blockInChunk.y == max && face == EAST ) || + (blockInChunk.y == min && face == EAST ) || + (blockInChunk.y == max && face == WEST ) || (blockInChunk.z == min && face == BOTTOM) || (blockInChunk.z == max && face == TOP ); } diff --git a/src/main/resources/assets/textures/blocks/grass_bottom.png b/src/main/resources/assets/textures/blocks/dirt.png similarity index 100% rename from src/main/resources/assets/textures/blocks/grass_bottom.png rename to src/main/resources/assets/textures/blocks/dirt.png diff --git a/src/main/resources/assets/textures/blocks/grass_side.png b/src/main/resources/assets/textures/blocks/grass_side.png deleted file mode 100644 index f57c49f7557cd788bcc99c03bf0af21521eaa68b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1979 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/blocks/grass_top.png b/src/main/resources/assets/textures/tiles/grass_top.png similarity index 100% rename from src/main/resources/assets/textures/blocks/grass_top.png rename to src/main/resources/assets/textures/tiles/grass_top.png diff --git a/src/main/resources/assets/textures/tiles/sand.png b/src/main/resources/assets/textures/tiles/sand.png new file mode 100644 index 0000000000000000000000000000000000000000..69b833ab71e424166a4a37421fbae3869b4d3606 GIT binary patch literal 6733 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 C+M8Ga literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/textures/tiles/yellow_flowers.png b/src/main/resources/assets/textures/tiles/yellow_flowers.png new file mode 100644 index 0000000000000000000000000000000000000000..51eccb0aa32aa530debfe2ec004ee04209975da6 GIT binary patch literal 334 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkEbHUgGKN%Kn5yT9DDqR)_TqP)M@GHKN2hKQ}iuuY|$5C^fMpHASI3 zvm`^o-P1Q9ypc~FsA!v~i(`nz>9fHHc@Hb_*o5C*P@CTHXBXSVO%B(y*))QT*?t;2 z+)rWqE-b7dptQ9=YE#b1U7I)ZC#BUStIzj6l6l2BJU#u{Ro;j{KLcd0a_wWZe*Q^? z_0v~Qb2Ww?d)6~BNm>@)I_6$~%1w VJ*>7auN3G522WQ%mvv4FO#u77cYgo? literal 0 HcmV?d00001