diff --git a/src/main/java/com/github/halotroop/litecraft/types/block/BlockEntity.java b/src/main/java/com/github/halotroop/litecraft/types/block/BlockEntity.java index 79299be..c0b8fd6 100644 --- a/src/main/java/com/github/halotroop/litecraft/types/block/BlockEntity.java +++ b/src/main/java/com/github/halotroop/litecraft/types/block/BlockEntity.java @@ -16,7 +16,5 @@ public class BlockEntity extends RenderObject public void processCulling(Chunk chunk) { Vector3f southNeighbourBlockLocation = this.getPosition(); southNeighbourBlockLocation.x--; - - } } diff --git a/src/main/java/com/github/halotroop/litecraft/world/Chunk.java b/src/main/java/com/github/halotroop/litecraft/world/Chunk.java index 113876f..457eccd 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/Chunk.java +++ b/src/main/java/com/github/halotroop/litecraft/world/Chunk.java @@ -23,18 +23,18 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage private static long posHash(int x, int y, int z) { return ((long) x & MAX_POS) | (((long) y & MAX_POS) << POS_SHIFT) | (((long) z & MAX_POS) << DOUBLE_SHIFT); } - List renderList; - private final Long2ObjectMap blocks = new Long2ObjectArrayMap<>(); - private final Long2ObjectMap blockEntities = new Long2ObjectArrayMap<>(); + private final Block[] blocks = new Block[CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE]; + private BlockEntity[] blockEntities = new BlockEntity[CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE]; private boolean render = false; public final int chunkX, chunkY, chunkZ; public final int chunkStartX, chunkStartY, chunkStartZ; private boolean fullyGenerated = false; public final int dimension; + private boolean dirty = true; + private BlockEntity[] renderedBlocks; public Chunk(int chunkX, int chunkY, int chunkZ, int dimension) { - renderList = new ArrayList(); this.chunkX = chunkX; this.chunkY = chunkY; this.chunkZ = chunkZ; @@ -53,31 +53,59 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage @Override public Block getBlock(int x, int y, int z) { - long hash = posHash(x, y, z); - return this.blocks.get(hash); + if (x > CHUNK_SIZE || y > CHUNK_SIZE || z > CHUNK_SIZE || x < 0 || y < 0 || z < 0) + { + throw new RuntimeException("Block [" + x + ", " + y + ", " + z + ", " + "] out of chunk bounds!"); + } + + return blocks[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y]; } public BlockEntity getBlockEntity(int x, int y, int z) { - long hash = posHash(x, y, z); - return this.blockEntities.get(hash); + if (x > CHUNK_SIZE || y > CHUNK_SIZE || z > CHUNK_SIZE || x < 0 || y < 0 || z < 0) + { + throw new RuntimeException("Block [" + x + ", " + y + ", " + z + ", " + "] out of chunk bounds!"); + } + + return this.blockEntities[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y]; } public void render(BlockRenderer blockRenderer) { - renderList.clear(); + if (render) { - for(int i = 0; i < CHUNK_SIZE; i++) { - for(int j = 0; j < CHUNK_SIZE; j++) { - for(int k = 0; k < CHUNK_SIZE; k++) { - BlockEntity block = getBlockEntity(i, j, k); - renderList.add(block); + if (dirty) + { + dirty = false; + renderedBlocks = new BlockEntity[CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE]; + for(int x = 0; x < CHUNK_SIZE; x++) + { + for(int y = 0; y < CHUNK_SIZE; y++) + { + for(int z = 0; z < CHUNK_SIZE; z++) + { + BlockEntity block = getBlockEntity(x, y, z); + if (x == 0 || x == CHUNK_SIZE-1 || z == 0 || z == CHUNK_SIZE-1 || y == 0 || y == CHUNK_SIZE-1) + { + renderedBlocks[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y] = block; + continue; + } + + // check for air. Yes this is stupid, TODO fix this + if (getBlockEntity(x-1, y, z) == null || getBlockEntity(x+1, y, z) == null || + getBlockEntity(x, y-1, z) == null || getBlockEntity(x, y+1, z) == null || + getBlockEntity(x, y, z-1) == null || getBlockEntity(x, y, z+1) == null) + { + renderedBlocks[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y] = block; + } + } } } } - blockRenderer.render(renderList); + blockRenderer.render(renderedBlocks); } } @@ -93,12 +121,12 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage if (z > MAX_POS) z = MAX_POS; else if (z < 0) z = 0; - long hash = posHash(x, y, z); - this.blocks.put(hash, block); + this.blocks[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y] = block; if (this.render) { - this.blockEntities.put(hash, new BlockEntity(block, new Vector3f(this.chunkStartX + x, this.chunkStartY + y, this.chunkStartZ + z))); + this.blockEntities[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y] = new BlockEntity(block, new Vector3f(this.chunkStartX + x, this.chunkStartY + y, this.chunkStartZ + z)); } + dirty = true; } public void setRender(boolean render) @@ -111,24 +139,22 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage { for (int z = 0; z < CHUNK_SIZE; ++z) { - long hash = posHash(x, y, z); - Block block = this.blocks.get(hash); - if (block.isVisible()) this.blockEntities.put(hash, new BlockEntity(block, + Block block = this.blocks[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y]; + if (block.isVisible()) this.blockEntities[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y] = new BlockEntity(block, new Vector3f( this.chunkStartX + x, this.chunkStartY + y, - this.chunkStartZ + z))); + this.chunkStartZ + z)); } } } } else if (this.render) // else if it has been changed to false { - int length = blockEntities.size(); - for (int i = length; i >= 0; --i) - { this.blockEntities.remove(i); } + blockEntities = new BlockEntity[CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE]; } this.render = render; + dirty = true; } public boolean isFullyGenerated() @@ -166,7 +192,7 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage { for (int x = 0; x < CHUNK_SIZE; ++x) { - this.blocks.put(posHash, palette.get(blockData.readInt((int) posHash))); + blocks[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y] = palette.get(blockData.readInt((int) posHash)); ++posHash; } } @@ -194,7 +220,7 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage { for (int x = 0; x < CHUNK_SIZE; ++x) { - Block b = this.blocks.get(posHash); + Block b = blocks[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y]; blockData.writeInt(palette.computeIntIfAbsent(b, nextIdProvider)); ++posHash; } @@ -208,5 +234,7 @@ public class Chunk implements BlockAccess, WorldGenConstants, DataStorage data.put("palette", paletteData); data.put("block", blockData); + + dirty = true; } } diff --git a/src/main/java/com/github/halotroop/litecraft/world/GenWorld.java b/src/main/java/com/github/halotroop/litecraft/world/GenWorld.java deleted file mode 100644 index 4542101..0000000 --- a/src/main/java/com/github/halotroop/litecraft/world/GenWorld.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.halotroop.litecraft.world; - -import com.github.halotroop.litecraft.types.block.Block; -import com.github.halotroop.litecraft.world.gen.WorldGenConstants; - -final class GenWorld implements BlockAccess, WorldGenConstants -{ - GenWorld(World parent) - { - this.parent = parent; - } - - public final World parent; - - @Override - public Block getBlock(int x, int y, int z) - { return this.parent.getGenChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).getBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS); } - - @Override - public void setBlock(int x, int y, int z, Block block) - { this.parent.getGenChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).setBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS, block); } -} diff --git a/src/main/java/com/github/halotroop/litecraft/world/World.java b/src/main/java/com/github/halotroop/litecraft/world/World.java index 8afb623..b5ea94d 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/World.java +++ b/src/main/java/com/github/halotroop/litecraft/world/World.java @@ -34,7 +34,7 @@ public class World implements BlockAccess, WorldGenConstants this.seed = seed; this.chunkGenerator = dim.createChunkGenerator(seed); this.worldModifiers = dim.getWorldModifierArray(); - this.genBlockAccess = new GenWorld(this); + this.genBlockAccess = new GenerationWorld(this); this.save = save; this.dimension = dim.id; } @@ -53,10 +53,14 @@ public class World implements BlockAccess, WorldGenConstants { this(seed, dim, save); + long time = System.currentTimeMillis(); + System.out.println("Generating world!"); for (int i = (0 - (size/2)); i < (size/2); i++) for (int k = (0 - (size/2)); k < (size/2); k++) for (int y = -2; y < 0; ++y) this.getChunk(i, y, k).setRender(true); + + System.out.println("Generated world in " + (System.currentTimeMillis() - time) + " milliseconds"); } public Chunk getChunk(int chunkX, int chunkY, int chunkZ) @@ -123,7 +127,6 @@ public class World implements BlockAccess, WorldGenConstants //used for model combining and culling public Chunk optimiseChunk(Chunk chunk) { - return chunk; } @@ -131,7 +134,7 @@ public class World implements BlockAccess, WorldGenConstants { Chunk chunk = getChunk(0, -1, 0); if(chunk!= null) { - blockRenderer.prepareModel(chunk.getBlockEntity(0, -2, 0).getModel()); + blockRenderer.prepareModel(chunk.getBlockEntity(0, 0, 0).getModel()); this.chunks.forEach((pos, c) -> c.render(blockRenderer)); blockRenderer.unbindModel(); } @@ -148,4 +151,22 @@ public class World implements BlockAccess, WorldGenConstants chunkPositions.forEach((LongConsumer) (pos -> this.chunks.remove(pos))); // remove all chunks } + + private static final class GenerationWorld implements BlockAccess, WorldGenConstants + { + GenerationWorld(World parent) + { + this.parent = parent; + } + + public final World parent; + + @Override + public Block getBlock(int x, int y, int z) + { return this.parent.getGenChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).getBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS); } + + @Override + public void setBlock(int x, int y, int z, Block block) + { this.parent.getGenChunk(x >> POS_SHIFT, y >> POS_SHIFT, z >> POS_SHIFT).setBlock(x & MAX_POS, y & MAX_POS, z & MAX_POS, block); } + } } diff --git a/src/main/java/com/github/halotroop/litecraft/world/block/BlockRenderer.java b/src/main/java/com/github/halotroop/litecraft/world/block/BlockRenderer.java index 0c2f49a..701e9f5 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/block/BlockRenderer.java +++ b/src/main/java/com/github/halotroop/litecraft/world/block/BlockRenderer.java @@ -2,6 +2,7 @@ package com.github.halotroop.litecraft.world.block; import java.util.*; +import com.github.halotroop.litecraft.world.gen.WorldGenConstants; import org.lwjgl.opengl.*; import com.github.halotroop.litecraft.Litecraft; @@ -16,7 +17,7 @@ import com.github.hydos.ginger.engine.render.models.*; import com.github.hydos.ginger.engine.render.shaders.StaticShader; import com.github.hydos.ginger.engine.render.texture.ModelTexture; -public class BlockRenderer extends Renderer +public class BlockRenderer extends Renderer implements WorldGenConstants { private StaticShader shader; @@ -59,32 +60,37 @@ public class BlockRenderer extends Renderer GL30.glBindVertexArray(0); } - public void render(List renderList) + public void render(BlockEntity[] renderList) { shader.start(); shader.loadSkyColour(Window.getColour()); shader.loadViewMatrix(GingerRegister.getInstance().game.data.camera); - TexturedModel model = renderList.get(0).getModel(); + TexturedModel model = renderList[0].getModel(); if(GingerRegister.getInstance().wireframe) { - GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE ); + GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE); } - for (RenderObject entity : renderList) + for(int x = 0; x < CHUNK_SIZE; x++) { - if (entity != null && entity.getModel() != null) { - prepTexture(entity.getModel().getTexture(), entity.getModel().getTexture().getTextureID()); - prepBlockInstance(entity); - GL11.glDrawElements(GL11.GL_TRIANGLES, model.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0); - + for (int y = 0; y < CHUNK_SIZE; y++) + { + for (int z = 0; z < CHUNK_SIZE; z++) + { + BlockEntity entity = renderList[x*CHUNK_SIZE*CHUNK_SIZE + z*CHUNK_SIZE + y]; + if (entity != null && entity.getModel() != null) + { + prepTexture(entity.getModel().getTexture(), entity.getModel().getTexture().getTextureID()); + prepBlockInstance(entity); + GL11.glDrawElements(GL11.GL_TRIANGLES, model.getRawModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0); + } + } } } + if(GingerRegister.getInstance().wireframe) { - GL11.glPolygonMode( GL11.GL_FRONT_AND_BACK,GL11.GL_FILL ); + GL11.glPolygonMode( GL11.GL_FRONT_AND_BACK,GL11.GL_FILL); } shader.stop(); } - - - } diff --git a/src/main/java/com/github/halotroop/litecraft/world/gen/Dimension.java b/src/main/java/com/github/halotroop/litecraft/world/gen/Dimension.java index 501bcbe..3cb90a2 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/gen/Dimension.java +++ b/src/main/java/com/github/halotroop/litecraft/world/gen/Dimension.java @@ -22,7 +22,7 @@ public abstract class Dimension } public WorldModifier[] getWorldModifierArray() { - return this.worldModifiers.toArray(new WorldModifier[0]); + return this.worldModifiers.toArray(WorldModifier[]::new); } public abstract T createChunkGenerator(long seed); diff --git a/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldChunkGenerator.java b/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldChunkGenerator.java index c5527b3..09bbc27 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldChunkGenerator.java +++ b/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldChunkGenerator.java @@ -22,13 +22,16 @@ public class OverworldChunkGenerator implements ChunkGenerator, WorldGenConstant { Chunk chunk = new Chunk(chunkX, chunkY, chunkZ, this.dimension); - for (int x = 0; x < CHUNK_SIZE; ++x) { + for (int x = 0; x < CHUNK_SIZE; ++x) + { double totalX = x + chunk.chunkStartX; - for (int z = 0; z < CHUNK_SIZE; ++z) { + for (int z = 0; z < CHUNK_SIZE; ++z) + { int height = (int) this.noise.sample(totalX, (double) (chunk.chunkStartZ + z)); - for (int y = 0; y < CHUNK_SIZE; ++y) { + for (int y = 0; y < CHUNK_SIZE; ++y) + { int totalY = chunk.chunkStartY + y; Block block = Blocks.AIR; diff --git a/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldDimension.java b/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldDimension.java index 3e5c242..d4c5062 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldDimension.java +++ b/src/main/java/com/github/halotroop/litecraft/world/gen/OverworldDimension.java @@ -12,4 +12,4 @@ public class OverworldDimension extends Dimension { return new OverworldChunkGenerator(seed, this.id); } -} +} \ No newline at end of file diff --git a/src/main/java/com/github/halotroop/litecraft/world/gen/WorldGenConstants.java b/src/main/java/com/github/halotroop/litecraft/world/gen/WorldGenConstants.java index 296eb9d..9acd457 100644 --- a/src/main/java/com/github/halotroop/litecraft/world/gen/WorldGenConstants.java +++ b/src/main/java/com/github/halotroop/litecraft/world/gen/WorldGenConstants.java @@ -2,8 +2,8 @@ package com.github.halotroop.litecraft.world.gen; public interface WorldGenConstants { - static final int POS_SHIFT = 3; - static final int DOUBLE_SHIFT = POS_SHIFT * 2; - static final int CHUNK_SIZE = (int) Math.pow(2, POS_SHIFT); - static final int MAX_POS = CHUNK_SIZE - 1; + int POS_SHIFT = 3; + int DOUBLE_SHIFT = POS_SHIFT * 2; + int CHUNK_SIZE = (int) Math.pow(2, POS_SHIFT); + int MAX_POS = CHUNK_SIZE - 1; } diff --git a/src/main/java/com/github/hydos/ginger/engine/elements/objects/Player.java b/src/main/java/com/github/hydos/ginger/engine/elements/objects/Player.java index 9066e9e..11360b7 100644 --- a/src/main/java/com/github/hydos/ginger/engine/elements/objects/Player.java +++ b/src/main/java/com/github/hydos/ginger/engine/elements/objects/Player.java @@ -44,7 +44,12 @@ public class Player extends RenderObject if (Window.isKeyDown(GLFW.GLFW_KEY_SPACE)) { - jump(); +// jump(); + position.y += Constants.movementSpeed; + } + if (Window.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) + { + position.y -= Constants.movementSpeed; } } @@ -64,6 +69,6 @@ public class Player extends RenderObject upwardsSpeed += Constants.gravity.y() * Window.getTime(); isInAir = false; upwardsSpeed = 0; - super.getPosition().y = 0; +// super.getPosition().y = 0; } }