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
@ -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<ChunkRenderOptimizer> 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
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
@ -44,4 +52,9 @@ public class TileRenderSimple extends TileRender {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsOwnRenderable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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,33 +47,103 @@ 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]
|
||||
// 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) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@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 OpaqueCube getBlock(Vec3i cursor) {
|
||||
protected void addBlock(Vec3i pos, OpaqueCube cube) {
|
||||
getBlock(pos).block = cube;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -99,62 +169,82 @@ public class ChunkRenderOptimizerCube extends ChunkRenderOptimizer {
|
||||
);
|
||||
}
|
||||
|
||||
private void processInnerFaces(
|
||||
OpaqueCube block,
|
||||
Vec3i cursor,
|
||||
Consumer<Face> 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<Face> 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);
|
||||
|
||||
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 void addFace(
|
||||
Vec3 cursor, BlockFace face,
|
||||
Texture texture,
|
||||
Consumer<Face> output
|
||||
) {
|
||||
if (texture == null) return;
|
||||
|
||||
output.accept(Faces.createBlockFace(
|
||||
WorldRenderProgram.getDefault(),
|
||||
texture,
|
||||
COLOR_MULTIPLIER,
|
||||
new Vec3(cursor.x, cursor.y, cursor.z),
|
||||
new Vec3(cursor),
|
||||
face,
|
||||
false
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldRenderFace(Vec3i cursor, BlockFace face) {
|
||||
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<Face> 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) &&
|
||||
|
@ -25,7 +25,6 @@ public class BlockDataRegistry {
|
||||
private static final Map<String, BlockData> REGISTRY = new HashMap<>();
|
||||
|
||||
static {
|
||||
register(new BlockData("Test", "Grass"));
|
||||
register(new BlockData("Test", "Dirt"));
|
||||
register(new BlockData("Test", "Stone"));
|
||||
register(new BlockData("Test", "Air"));
|
||||
|
@ -25,7 +25,10 @@ public class TileDataRegistry {
|
||||
private static final Map<String, TileData> 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) {
|
||||
|
@ -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 );
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.9 KiB |
BIN
src/main/resources/assets/textures/tiles/grass_side.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
src/main/resources/assets/textures/tiles/sand.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
src/main/resources/assets/textures/tiles/yellow_flowers.png
Normal file
After Width: | Height: | Size: 334 B |