mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 10:55:01 -04:00
Rendering of world, integrate in minosoft, minimal cleanup
This commit is contained in:
parent
98beee726d
commit
463896ae78
@ -21,9 +21,18 @@ public enum Directions {
|
|||||||
WEST,
|
WEST,
|
||||||
EAST;
|
EAST;
|
||||||
|
|
||||||
private static final Directions[] DIRECTIONS = values();
|
public static final Directions[] DIRECTIONS = values();
|
||||||
|
|
||||||
public static Directions byId(int id) {
|
public static Directions byId(int id) {
|
||||||
return DIRECTIONS[id];
|
return DIRECTIONS[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Directions inverse() {
|
||||||
|
var ordinal = ordinal();
|
||||||
|
if (ordinal % 2 == 0) {
|
||||||
|
return byId(ordinal + 1);
|
||||||
|
}
|
||||||
|
return byId(ordinal - 1);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
package de.bixilon.minosoft.data.mappings.blocks;
|
package de.bixilon.minosoft.data.mappings.blocks;
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.Directions;
|
||||||
import de.bixilon.minosoft.data.mappings.ModIdentifier;
|
import de.bixilon.minosoft.data.mappings.ModIdentifier;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -104,4 +105,8 @@ public class Block extends ModIdentifier {
|
|||||||
}
|
}
|
||||||
return String.format("%s%s", getFullIdentifier(), out);
|
return String.format("%s%s", getFullIdentifier(), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean forceDrawFace(Directions direction) {
|
||||||
|
return false; // ToDo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.world;
|
|||||||
|
|
||||||
import de.bixilon.minosoft.data.entities.block.BlockEntityMetaData;
|
import de.bixilon.minosoft.data.entities.block.BlockEntityMetaData;
|
||||||
import de.bixilon.minosoft.data.mappings.blocks.Block;
|
import de.bixilon.minosoft.data.mappings.blocks.Block;
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@ -22,9 +23,9 @@ import java.util.HashMap;
|
|||||||
* Collection of 16 chunks sections
|
* Collection of 16 chunks sections
|
||||||
*/
|
*/
|
||||||
public class Chunk {
|
public class Chunk {
|
||||||
private final HashMap<Byte, ChunkSection> sections;
|
private final HashMap<Integer, ChunkSection> sections;
|
||||||
|
|
||||||
public Chunk(HashMap<Byte, ChunkSection> sections) {
|
public Chunk(HashMap<Integer, ChunkSection> sections) {
|
||||||
this.sections = sections;
|
this.sections = sections;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ public class Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlock(int x, int y, int z) {
|
public Block getBlock(int x, int y, int z) {
|
||||||
byte section = (byte) (y / 16);
|
int section = (y / 16);
|
||||||
if (!this.sections.containsKey(section)) {
|
if (!this.sections.containsKey(section)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -41,15 +42,15 @@ public class Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(int x, int y, int z, Block block) {
|
public void setBlock(int x, int y, int z, Block block) {
|
||||||
byte section = (byte) (y / 16);
|
int section = y / 16;
|
||||||
createSection(section);
|
createSection(section);
|
||||||
this.sections.get(section).setBlock(x, y % 16, z, block);
|
this.sections.get(section).setBlock(x, y % 16, z, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void createSection(byte section) {
|
void createSection(int height) {
|
||||||
if (this.sections.get(section) == null) {
|
if (this.sections.get(height) == null) {
|
||||||
// section was empty before, creating it
|
// section was empty before, creating it
|
||||||
this.sections.put(section, new ChunkSection());
|
this.sections.put(height, new ChunkSection());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,13 +59,13 @@ public class Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setBlock(InChunkLocation location, Block block) {
|
public void setBlock(InChunkLocation location, Block block) {
|
||||||
byte section = (byte) (location.getY() / 16);
|
int section = (location.getY() / ProtocolDefinition.SECTION_HEIGHT_Y);
|
||||||
createSection(section);
|
createSection(section);
|
||||||
this.sections.get(section).setBlock(location.getInChunkSectionLocation(), block);
|
this.sections.get(section).setBlock(location.getInChunkSectionLocation(), block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockEntityData(InChunkLocation position, BlockEntityMetaData data) {
|
public void setBlockEntityData(InChunkLocation position, BlockEntityMetaData data) {
|
||||||
ChunkSection section = this.sections.get((byte) (position.getY() / 16));
|
ChunkSection section = this.sections.get((position.getY() / ProtocolDefinition.SECTION_HEIGHT_Y));
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -72,7 +73,7 @@ public class Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BlockEntityMetaData getBlockEntityData(InChunkLocation position) {
|
public BlockEntityMetaData getBlockEntityData(InChunkLocation position) {
|
||||||
ChunkSection section = this.sections.get((byte) (position.getY() / 16));
|
ChunkSection section = this.sections.get((position.getY() / ProtocolDefinition.SECTION_HEIGHT_Y));
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -83,7 +84,7 @@ public class Chunk {
|
|||||||
blockEntities.forEach(this::setBlockEntityData);
|
blockEntities.forEach(this::setBlockEntityData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<Byte, ChunkSection> getSections() {
|
public HashMap<Integer, ChunkSection> getSections() {
|
||||||
return this.sections;
|
return this.sections;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package de.bixilon.minosoft.data.world
|
package de.bixilon.minosoft.data.world
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.Directions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chunk X and Z location (block position / 16, rounded down)
|
* Chunk X and Z location (block position / 16, rounded down)
|
||||||
*/
|
*/
|
||||||
@ -20,4 +22,14 @@ data class ChunkLocation(val x: Int, val z: Int) {
|
|||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "($x $z)"
|
return "($x $z)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLocationByDirection(direction: Directions): ChunkLocation {
|
||||||
|
return when (direction) {
|
||||||
|
Directions.NORTH -> ChunkLocation(x, z - 1)
|
||||||
|
Directions.SOUTH -> ChunkLocation(x, z + 1)
|
||||||
|
Directions.WEST -> ChunkLocation(x - 1, z)
|
||||||
|
Directions.EAST -> ChunkLocation(x + 1, z)
|
||||||
|
else -> throw IllegalArgumentException("Chunk location is just 2d")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
package de.bixilon.minosoft.data.world
|
package de.bixilon.minosoft.data.world
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.Directions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chunk X, Y and Z location (max 16x16x16)
|
* Chunk X, Y and Z location (max 16x16x16)
|
||||||
*/
|
*/
|
||||||
@ -20,4 +22,15 @@ data class InChunkSectionLocation(val x: Int, val y: Int, val z: Int) {
|
|||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "($x $y $z)"
|
return "($x $y $z)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getLocationByDirection(direction: Directions): InChunkSectionLocation {
|
||||||
|
return when (direction) {
|
||||||
|
Directions.DOWN -> InChunkSectionLocation(x, y - 1, z)
|
||||||
|
Directions.UP -> InChunkSectionLocation(x, y + 1, z)
|
||||||
|
Directions.NORTH -> InChunkSectionLocation(x, y, z - 1)
|
||||||
|
Directions.SOUTH -> InChunkSectionLocation(x, y, z + 1)
|
||||||
|
Directions.WEST -> InChunkSectionLocation(x - 1, y, z)
|
||||||
|
Directions.EAST -> InChunkSectionLocation(x + 1, y, z)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ class Camera(private var fov: Float, private val windowId: Long) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun calculateProjectionMatrix(screenWidth: Int, screenHeight: Int, shader: Shader) {
|
fun calculateProjectionMatrix(screenWidth: Int, screenHeight: Int, shader: Shader) {
|
||||||
shader.use().setMat4("projection", calculateProjectionMatrix(screenWidth, screenHeight))
|
shader.use().setMat4("projectionMatrix", calculateProjectionMatrix(screenWidth, screenHeight))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateProjectionMatrix(screenWidth: Int, screenHeight: Int): Mat4 {
|
private fun calculateProjectionMatrix(screenWidth: Int, screenHeight: Int): Mat4 {
|
||||||
@ -69,7 +69,7 @@ class Camera(private var fov: Float, private val windowId: Long) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun calculateViewMatrix(shader: Shader) {
|
fun calculateViewMatrix(shader: Shader) {
|
||||||
shader.use().setMat4("view", calculateViewMatrix())
|
shader.use().setMat4("viewMatrix", calculateViewMatrix())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateViewMatrix(): Mat4 {
|
private fun calculateViewMatrix(): Mat4 {
|
||||||
@ -80,6 +80,10 @@ class Camera(private var fov: Float, private val windowId: Long) {
|
|||||||
this.fov = fov
|
this.fov = fov
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setPosition(position: Vec3) {
|
||||||
|
cameraPosition = position
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val CAMERA_UP_VEC3 = Vec3(0.0f, 1.0f, 0.0f)
|
private val CAMERA_UP_VEC3 = Vec3(0.0f, 1.0f, 0.0f)
|
||||||
}
|
}
|
||||||
|
112
src/main/java/de/bixilon/minosoft/gui/rendering/ChunkPreparer.kt
Normal file
112
src/main/java/de/bixilon/minosoft/gui/rendering/ChunkPreparer.kt
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.Directions
|
||||||
|
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||||
|
import de.bixilon.minosoft.data.world.ChunkLocation
|
||||||
|
import de.bixilon.minosoft.data.world.ChunkSection
|
||||||
|
import de.bixilon.minosoft.data.world.World
|
||||||
|
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||||
|
import glm_.mat4x4.Mat4
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
import glm_.vec4.Vec4
|
||||||
|
|
||||||
|
object ChunkPreparer {
|
||||||
|
fun prepareChunk(world: World, chunkLocation: ChunkLocation, sectionHeight: Int, section: ChunkSection): FloatArray {
|
||||||
|
val data: MutableList<Float> = mutableListOf()
|
||||||
|
|
||||||
|
// ToDo: Greedy meshing!
|
||||||
|
|
||||||
|
val below = world.allChunks[chunkLocation]?.sections?.get(sectionHeight - 1)
|
||||||
|
val above = world.allChunks[chunkLocation]?.sections?.get(sectionHeight + 1)
|
||||||
|
//val north = (world.allChunks[chunkLocation.getLocationByDirection(Directions.NORTH)]?: throw ChunkNotLoadedException("North not loaded")).sections?.get(sectionHeight)
|
||||||
|
//val south = (world.allChunks[chunkLocation.getLocationByDirection(Directions.SOUTH)]?: throw ChunkNotLoadedException("South not loaded")).sections?.get(sectionHeight)
|
||||||
|
//val west = (world.allChunks[chunkLocation.getLocationByDirection(Directions.WEST)]?: throw ChunkNotLoadedException("West not loaded")).sections?.get(sectionHeight)
|
||||||
|
//val east = (world.allChunks[chunkLocation.getLocationByDirection(Directions.EAST)]?: throw ChunkNotLoadedException("North not loaded")).sections?.get(sectionHeight)
|
||||||
|
val north = world.allChunks[chunkLocation.getLocationByDirection(Directions.NORTH)]?.sections?.get(sectionHeight)
|
||||||
|
val south = world.allChunks[chunkLocation.getLocationByDirection(Directions.SOUTH)]?.sections?.get(sectionHeight)
|
||||||
|
val west = world.allChunks[chunkLocation.getLocationByDirection(Directions.WEST)]?.sections?.get(sectionHeight)
|
||||||
|
val east = world.allChunks[chunkLocation.getLocationByDirection(Directions.EAST)]?.sections?.get(sectionHeight)
|
||||||
|
|
||||||
|
for ((position, block) in section.blocks) {
|
||||||
|
for (direction in Directions.DIRECTIONS) {
|
||||||
|
var blockToCheck: Block? = null
|
||||||
|
when (direction) {
|
||||||
|
Directions.DOWN -> {
|
||||||
|
if (position.y == 0) {
|
||||||
|
below?.let {
|
||||||
|
blockToCheck = it.getBlock(position.x, ProtocolDefinition.SECTION_HEIGHT_Y - 1, position.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Directions.UP -> {
|
||||||
|
if (position.y == ProtocolDefinition.SECTION_HEIGHT_Y - 1) {
|
||||||
|
above?.let {
|
||||||
|
blockToCheck = it.getBlock(position.x, 0, position.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Directions.NORTH -> {
|
||||||
|
if (position.z == 0) {
|
||||||
|
north?.let {
|
||||||
|
blockToCheck = it.getBlock(position.x, position.y, ProtocolDefinition.SECTION_WIDTH_Z - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Directions.SOUTH -> {
|
||||||
|
if (position.z == ProtocolDefinition.SECTION_WIDTH_Z - 1) {
|
||||||
|
south?.let {
|
||||||
|
blockToCheck = it.getBlock(position.x, position.y, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Directions.WEST -> {
|
||||||
|
if (position.x == 0) {
|
||||||
|
west?.let {
|
||||||
|
blockToCheck = it.getBlock(ProtocolDefinition.SECTION_WIDTH_X - 1, position.y, position.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Directions.EAST -> {
|
||||||
|
if (position.x == ProtocolDefinition.SECTION_WIDTH_X - 1) {
|
||||||
|
east?.let {
|
||||||
|
blockToCheck = it.getBlock(0, position.y, position.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blockToCheck == null) {
|
||||||
|
blockToCheck = section.getBlock(position.getLocationByDirection(direction))
|
||||||
|
}
|
||||||
|
if (blockToCheck != null) {
|
||||||
|
// if (block.forceDrawFace(direction.inverse())) {
|
||||||
|
continue
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
val model = Mat4().translate(Vec3(position.x, position.y, position.z))
|
||||||
|
val vertexArray = RenderConstants.VERTICIES[direction.ordinal]
|
||||||
|
var vertex = 0
|
||||||
|
while (vertex < vertexArray.size) {
|
||||||
|
val input = Vec4(vertexArray[vertex++], vertexArray[vertex++], vertexArray[vertex++], 1.0f)
|
||||||
|
val output = model * input
|
||||||
|
// Log.debug("input=%s; position=%s; output=%s;", input, position, output);
|
||||||
|
data.add(output.x)
|
||||||
|
data.add(output.y)
|
||||||
|
data.add(output.z)
|
||||||
|
data.add(vertexArray[vertex++])
|
||||||
|
data.add(getTextureLayerByBlock(block).toFloat()) // ToDo: Compact this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data.toFloatArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTextureLayerByBlock(block: Block): Int {
|
||||||
|
return when (block.fullIdentifier) {
|
||||||
|
"minecraft:bedrock" -> 0
|
||||||
|
"minecraft:dirt" -> 1
|
||||||
|
"minecraft:stone" -> 2
|
||||||
|
else -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,16 +9,19 @@ import java.util.HashMap;
|
|||||||
public class DummyData {
|
public class DummyData {
|
||||||
private static final Block BEDROCK = new Block("bedrock");
|
private static final Block BEDROCK = new Block("bedrock");
|
||||||
private static final Block DIRT = new Block("dirt");
|
private static final Block DIRT = new Block("dirt");
|
||||||
|
private static final Block STONE = new Block("stone");
|
||||||
|
|
||||||
public static Chunk getDummyChunk() {
|
public static Chunk getDummyChunk() {
|
||||||
Chunk chunk = new Chunk(new HashMap<>());
|
Chunk chunk = new Chunk(new HashMap<>());
|
||||||
for (int y = 0; y < ProtocolDefinition.SECTION_HEIGHT_Y; y++) {
|
for (int y = 0; y < ProtocolDefinition.SECTION_HEIGHT_Y * ProtocolDefinition.SECTIONS_PER_CHUNK; y++) {
|
||||||
for (int x = 0; x < ProtocolDefinition.SECTION_WIDTH_X; x++) {
|
for (int x = 0; x < ProtocolDefinition.SECTION_WIDTH_X; x++) {
|
||||||
for (int z = 0; z < ProtocolDefinition.SECTION_WIDTH_Z; z++) {
|
for (int z = 0; z < ProtocolDefinition.SECTION_WIDTH_Z; z++) {
|
||||||
if (y == 0) {
|
if (y == 0) {
|
||||||
chunk.setBlock(x, y, z, BEDROCK);
|
chunk.setBlock(x, y, z, BEDROCK);
|
||||||
} else if (y < 8) {
|
} else if (y < 8) {
|
||||||
chunk.setBlock(x, y, z, DIRT);
|
chunk.setBlock(x, y, z, DIRT);
|
||||||
|
} else if (y < 60) {
|
||||||
|
chunk.setBlock(x, y, z, STONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering;
|
|
||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException;
|
|
||||||
import org.lwjgl.Version;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class DummyRender {
|
|
||||||
public static void main(String[] args) throws IOException, ShaderLoadingException {
|
|
||||||
System.out.println("Hello LWJGL " + Version.getVersion() + "!");
|
|
||||||
|
|
||||||
RenderWindow renderWindow = new RenderWindow();
|
|
||||||
renderWindow.init();
|
|
||||||
renderWindow.startLoop();
|
|
||||||
renderWindow.exit();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +1,7 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering;
|
package de.bixilon.minosoft.gui.rendering;
|
||||||
|
|
||||||
import glm_.mat4x4.Mat4;
|
import de.bixilon.minosoft.data.world.ChunkLocation;
|
||||||
import glm_.vec3.Vec3;
|
import glm_.vec3.Vec3;
|
||||||
import glm_.vec4.Vec4;
|
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
import org.lwjgl.opengl.GL15;
|
import org.lwjgl.opengl.GL15;
|
||||||
import org.lwjgl.opengl.GL20;
|
import org.lwjgl.opengl.GL20;
|
||||||
@ -14,87 +13,21 @@ import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
|||||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||||
|
|
||||||
public class Mesh {
|
public class Mesh {
|
||||||
public static final float[][] VERTICIES = {
|
|
||||||
{
|
|
||||||
-0.5f, -0.5f, -0.5f, 0.0f,
|
|
||||||
0.5f, -0.5f, -0.5f, 1.0f,
|
|
||||||
0.5f, 0.5f, -0.5f, 2.0f,
|
|
||||||
0.5f, 0.5f, -0.5f, 2.0f,
|
|
||||||
-0.5f, 0.5f, -0.5f, 3.0f,
|
|
||||||
-0.5f, -0.5f, -0.5f, 0.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
-0.5f, -0.5f, 0.5f, 0.0f,
|
|
||||||
0.5f, -0.5f, 0.5f, 1.0f,
|
|
||||||
0.5f, 0.5f, 0.5f, 2.0f,
|
|
||||||
0.5f, 0.5f, 0.5f, 2.0f,
|
|
||||||
-0.5f, 0.5f, 0.5f, 3.0f,
|
|
||||||
-0.5f, -0.5f, 0.5f, 0.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
-0.5f, 0.5f, 0.5f, 1.0f,
|
|
||||||
-0.5f, 0.5f, -0.5f, 2.0f,
|
|
||||||
-0.5f, -0.5f, -0.5f, 3.0f,
|
|
||||||
-0.5f, -0.5f, -0.5f, 3.0f,
|
|
||||||
-0.5f, -0.5f, 0.5f, 0.0f,
|
|
||||||
-0.5f, 0.5f, 0.5f, 1.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0.5f, 0.5f, 0.5f, 1.0f,
|
|
||||||
0.5f, 0.5f, -0.5f, 2.0f,
|
|
||||||
0.5f, -0.5f, -0.5f, 3.0f,
|
|
||||||
0.5f, -0.5f, -0.5f, 3.0f,
|
|
||||||
0.5f, -0.5f, 0.5f, 0.0f,
|
|
||||||
0.5f, 0.5f, 0.5f, 1.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
-0.5f, -0.5f, -0.5f, 3.0f,
|
|
||||||
0.5f, -0.5f, -0.5f, 2.0f,
|
|
||||||
0.5f, -0.5f, 0.5f, 1.0f,
|
|
||||||
0.5f, -0.5f, 0.5f, 1.0f,
|
|
||||||
-0.5f, -0.5f, 0.5f, 0.0f,
|
|
||||||
-0.5f, -0.5f, -0.5f, 3.0f,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
-0.5f, 0.5f, -0.5f, 3.0f,
|
|
||||||
0.5f, 0.5f, -0.5f, 2.0f,
|
|
||||||
0.5f, 0.5f, 0.5f, 1.0f,
|
|
||||||
0.5f, 0.5f, 0.5f, 1.0f,
|
|
||||||
-0.5f, 0.5f, 0.5f, 0.0f,
|
|
||||||
-0.5f, 0.5f, -0.5f, 3.0f,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
int textureLayer;
|
|
||||||
int vAO;
|
int vAO;
|
||||||
int vBO;
|
int vBO;
|
||||||
|
Vec3 chunkPosition;
|
||||||
|
int trianglesCount;
|
||||||
|
|
||||||
public Mesh(int textureLayer, Vec3 position) {
|
public Mesh(float[] data, ChunkLocation location, int sectionHeight) {
|
||||||
this.textureLayer = textureLayer;
|
this.chunkPosition = new Vec3(location.getX(), sectionHeight, location.getZ());
|
||||||
float[] result = new float[VERTICIES.length * VERTICIES[0].length + (VERTICIES.length * VERTICIES[0].length / 2)];
|
this.trianglesCount = data.length / 5;
|
||||||
int resultIndex = 0;
|
|
||||||
|
|
||||||
var model = new Mat4().translate(position);
|
|
||||||
|
|
||||||
for (float[] side : VERTICIES) {
|
|
||||||
for (int vertex = 0; vertex < side.length; ) {
|
|
||||||
Vec4 input = new Vec4(side[vertex++], side[vertex++], side[vertex++], 1.0f);
|
|
||||||
var output = model.times(input);
|
|
||||||
// Log.debug("input=%s; position=%s; output=%s;", input, position, output);
|
|
||||||
result[resultIndex++] = output.x;
|
|
||||||
result[resultIndex++] = output.y;
|
|
||||||
result[resultIndex++] = output.z;
|
|
||||||
result[resultIndex++] = side[vertex++];
|
|
||||||
result[resultIndex++] = textureLayer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.vAO = glGenVertexArrays();
|
this.vAO = glGenVertexArrays();
|
||||||
this.vBO = glGenBuffers();
|
this.vBO = glGenBuffers();
|
||||||
|
|
||||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||||
glBindVertexArray(this.vAO);
|
glBindVertexArray(this.vAO);
|
||||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.vBO);
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.vBO);
|
||||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, result, GL15.GL_STATIC_DRAW);
|
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW);
|
||||||
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 5 * Float.BYTES, 0L);
|
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 5 * Float.BYTES, 0L);
|
||||||
GL20.glEnableVertexAttribArray(0);
|
GL20.glEnableVertexAttribArray(0);
|
||||||
GL20.glVertexAttribPointer(1, 1, GL11.GL_FLOAT, false, 5 * Float.BYTES, 3 * Float.BYTES);
|
GL20.glVertexAttribPointer(1, 1, GL11.GL_FLOAT, false, 5 * Float.BYTES, 3 * Float.BYTES);
|
||||||
@ -106,8 +39,9 @@ public class Mesh {
|
|||||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw() {
|
public void draw(Shader chunkShader) {
|
||||||
|
chunkShader.setVec3("chunkPosition", this.chunkPosition);
|
||||||
glBindVertexArray(this.vAO);
|
glBindVertexArray(this.vAO);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
glDrawArrays(GL_TRIANGLES, 0, this.trianglesCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering;
|
||||||
|
|
||||||
|
public class RenderConstants {
|
||||||
|
public static final float[][] VERTICIES = {
|
||||||
|
// down
|
||||||
|
{
|
||||||
|
-0.5f, -0.5f, -0.5f, 3.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 2.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 3.0f,
|
||||||
|
},
|
||||||
|
// up
|
||||||
|
{
|
||||||
|
-0.5f, 0.5f, -0.5f, 3.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 2.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 3.0f,
|
||||||
|
},
|
||||||
|
// north
|
||||||
|
{
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 1.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 2.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 2.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 3.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f,
|
||||||
|
},
|
||||||
|
// south
|
||||||
|
{
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 2.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 2.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 3.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f,
|
||||||
|
},
|
||||||
|
// west
|
||||||
|
{
|
||||||
|
-0.5f, 0.5f, 0.5f, 1.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 2.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 3.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 3.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 1.0f,
|
||||||
|
},
|
||||||
|
// east
|
||||||
|
{
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 2.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 3.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 3.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package de.bixilon.minosoft.gui.rendering
|
package de.bixilon.minosoft.gui.rendering
|
||||||
|
|
||||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
import de.bixilon.minosoft.protocol.network.Connection
|
||||||
import glm_.vec3.Vec3
|
|
||||||
import org.lwjgl.*
|
import org.lwjgl.*
|
||||||
import org.lwjgl.glfw.Callbacks
|
import org.lwjgl.glfw.Callbacks
|
||||||
import org.lwjgl.glfw.GLFW.*
|
import org.lwjgl.glfw.GLFW.*
|
||||||
@ -11,8 +10,9 @@ import org.lwjgl.opengl.*
|
|||||||
import org.lwjgl.opengl.GL11.glClear
|
import org.lwjgl.opengl.GL11.glClear
|
||||||
import org.lwjgl.system.MemoryStack
|
import org.lwjgl.system.MemoryStack
|
||||||
import org.lwjgl.system.MemoryUtil
|
import org.lwjgl.system.MemoryUtil
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
|
|
||||||
class RenderWindow {
|
class RenderWindow(private val connection: Connection) {
|
||||||
private var screenWidth = 800
|
private var screenWidth = 800
|
||||||
private var screenHeight = 600
|
private var screenHeight = 600
|
||||||
private var polygonEnabled = false
|
private var polygonEnabled = false
|
||||||
@ -22,7 +22,11 @@ class RenderWindow {
|
|||||||
private var deltaTime = 0.0 // time between current frame and last frame
|
private var deltaTime = 0.0 // time between current frame and last frame
|
||||||
|
|
||||||
private var lastFrame = 0.0
|
private var lastFrame = 0.0
|
||||||
private lateinit var camera: Camera
|
lateinit var camera: Camera
|
||||||
|
|
||||||
|
val meshesToDraw = ConcurrentLinkedQueue<Mesh>()
|
||||||
|
val renderQueue = ConcurrentLinkedQueue<Runnable>()
|
||||||
|
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
// Setup an error callback. The default implementation
|
// Setup an error callback. The default implementation
|
||||||
@ -104,9 +108,11 @@ class RenderWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun startLoop() {
|
fun startLoop() {
|
||||||
val chunk = DummyData.getDummyChunk()
|
// val world = World()
|
||||||
|
// world.setChunk(ChunkLocation(0, 0), DummyData.getDummyChunk())
|
||||||
|
// world.setChunk(ChunkLocation(1, 0), DummyData.getDummyChunk())
|
||||||
|
|
||||||
texture0 = TextureArray(arrayOf("/textures/emerald_block.png", "/textures/brown_wool.png"))
|
texture0 = TextureArray(arrayOf("/textures/bedrock.png", "/textures/dirt.png", "/textures/stone.png"))
|
||||||
texture0.load()
|
texture0.load()
|
||||||
|
|
||||||
shader = Shader("vertex.glsl", "fragment.glsl")
|
shader = Shader("vertex.glsl", "fragment.glsl")
|
||||||
@ -117,21 +123,12 @@ class RenderWindow {
|
|||||||
camera.calculateProjectionMatrix(screenWidth, screenHeight, shader)
|
camera.calculateProjectionMatrix(screenWidth, screenHeight, shader)
|
||||||
camera.calculateViewMatrix(shader)
|
camera.calculateViewMatrix(shader)
|
||||||
|
|
||||||
val preparedChunks = mutableListOf<Mesh>()
|
|
||||||
|
|
||||||
|
// for ((chunkLocation, chunk) in world.allChunks) {
|
||||||
|
// for ((sectionHeight, section) in chunk.sections) {
|
||||||
for ((sectionHeight, section) in chunk.sections) {
|
// meshesToDraw.add(Mesh(ChunkPreparer.prepareChunk(world, chunkLocation, sectionHeight, section), chunkLocation, sectionHeight))
|
||||||
for ((location, block) in section.blocks) {
|
// }
|
||||||
val textureIndex = when (block.fullIdentifier) {
|
// }
|
||||||
"minecraft:dirt" -> 1
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
preparedChunks.add(Mesh(textureIndex, Vec3(location.x, location.y + ProtocolDefinition.SECTION_HEIGHT_Y * sectionHeight, location.z)))
|
|
||||||
// break
|
|
||||||
}
|
|
||||||
// break
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var framesLastSecond = 0
|
var framesLastSecond = 0
|
||||||
@ -150,18 +147,10 @@ class RenderWindow {
|
|||||||
|
|
||||||
camera.calculateViewMatrix(shader)
|
camera.calculateViewMatrix(shader)
|
||||||
|
|
||||||
for (mesh in preparedChunks) {
|
for (mesh in meshesToDraw) {
|
||||||
mesh.draw()
|
mesh.draw(shader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for ((key, value) in chunk.sections) {
|
|
||||||
// for ((key1) in value.blocks) {
|
|
||||||
// val model = Mat4().translate(Vec3(key1.x, key1.y + ProtocolDefinition.SECTION_HEIGHT_Y * key, key1.z))
|
|
||||||
// shader.setMat4("model", model)
|
|
||||||
// glDrawArrays(GL11.GL_TRIANGLES, 0, 36)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
glfwSwapBuffers(windowId) // swap the color buffers
|
glfwSwapBuffers(windowId) // swap the color buffers
|
||||||
|
|
||||||
// Poll for window events. The key callback above will only be
|
// Poll for window events. The key callback above will only be
|
||||||
@ -175,6 +164,10 @@ class RenderWindow {
|
|||||||
framesLastSecond = 0
|
framesLastSecond = 0
|
||||||
}
|
}
|
||||||
framesLastSecond++
|
framesLastSecond++
|
||||||
|
for (renderQueueElement in renderQueue) {
|
||||||
|
renderQueueElement.run()
|
||||||
|
renderQueue.remove(renderQueueElement)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
50
src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt
Normal file
50
src/main/java/de/bixilon/minosoft/gui/rendering/Renderer.kt
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.data.entities.Location
|
||||||
|
import de.bixilon.minosoft.data.world.Chunk
|
||||||
|
import de.bixilon.minosoft.data.world.ChunkLocation
|
||||||
|
import de.bixilon.minosoft.data.world.ChunkSection
|
||||||
|
import de.bixilon.minosoft.gui.rendering.ChunkPreparer.prepareChunk
|
||||||
|
import de.bixilon.minosoft.protocol.network.Connection
|
||||||
|
import de.bixilon.minosoft.util.Util
|
||||||
|
import glm_.vec3.Vec3
|
||||||
|
import org.lwjgl.Version
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
class Renderer(private val connection: Connection) {
|
||||||
|
private val renderWindow: RenderWindow = RenderWindow(connection)
|
||||||
|
private val executor: ExecutorService = Executors.newFixedThreadPool(2, Util.getThreadFactory(String.format("Rendering#%d", connection.connectionId)))
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
Thread({
|
||||||
|
println("Hello LWJGL " + Version.getVersion() + "!")
|
||||||
|
renderWindow.init()
|
||||||
|
renderWindow.startLoop()
|
||||||
|
renderWindow.exit()
|
||||||
|
}, "Rendering").start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prepareChunk(chunkLocation: ChunkLocation, chunk: Chunk) {
|
||||||
|
for ((sectionHeight, section) in chunk.sections) {
|
||||||
|
prepareChunkSection(chunkLocation, sectionHeight, section)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prepareChunkSection(chunkLocation: ChunkLocation, sectionHeight: Int, section: ChunkSection) {
|
||||||
|
executor.execute {
|
||||||
|
val data = prepareChunk(connection.player.world, chunkLocation, sectionHeight, section)
|
||||||
|
renderWindow.renderQueue.add {
|
||||||
|
renderWindow.meshesToDraw.add(Mesh(data, chunkLocation, sectionHeight))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun teleport(position: Location) {
|
||||||
|
renderWindow.renderQueue.add {
|
||||||
|
renderWindow.camera.setPosition(Vec3(position.x, position.y, position.z))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ package de.bixilon.minosoft.gui.rendering;
|
|||||||
|
|
||||||
import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException;
|
import de.bixilon.minosoft.gui.rendering.exceptions.ShaderLoadingException;
|
||||||
import glm_.mat4x4.Mat4;
|
import glm_.mat4x4.Mat4;
|
||||||
|
import glm_.vec3.Vec3;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.ARBFragmentShader;
|
import org.lwjgl.opengl.ARBFragmentShader;
|
||||||
import org.lwjgl.opengl.ARBShaderObjects;
|
import org.lwjgl.opengl.ARBShaderObjects;
|
||||||
@ -77,10 +78,14 @@ public class Shader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void set4f(String variableName, float[] floats) {
|
public void set4f(String variableName, float[] floats) {
|
||||||
glUniformMatrix4fv(glGetUniformLocation(this.programId, variableName), false, floats);
|
glUniformMatrix4fv(getUniformLocation(variableName), false, floats);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMat4(String variableName, Mat4 mat4) {
|
public void setMat4(String variableName, Mat4 mat4) {
|
||||||
glUniformMatrix4fv(glGetUniformLocation(this.programId, variableName), false, mat4.to(BufferUtils.createFloatBuffer(16)));
|
glUniformMatrix4fv(getUniformLocation(variableName), false, mat4.to(BufferUtils.createFloatBuffer(16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVec3(String name, Vec3 vec3) {
|
||||||
|
glUniform3f(getUniformLocation(name), vec3.x, vec3.y, vec3.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
package de.bixilon.minosoft.gui.rendering.exceptions
|
||||||
|
|
||||||
|
class ChunkNotLoadedException(message: String) : Exception(message)
|
@ -22,6 +22,7 @@ import de.bixilon.minosoft.data.mappings.recipes.Recipes;
|
|||||||
import de.bixilon.minosoft.data.mappings.versions.Version;
|
import de.bixilon.minosoft.data.mappings.versions.Version;
|
||||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping;
|
import de.bixilon.minosoft.data.mappings.versions.VersionMapping;
|
||||||
import de.bixilon.minosoft.data.mappings.versions.Versions;
|
import de.bixilon.minosoft.data.mappings.versions.Versions;
|
||||||
|
import de.bixilon.minosoft.gui.rendering.Renderer;
|
||||||
import de.bixilon.minosoft.logging.Log;
|
import de.bixilon.minosoft.logging.Log;
|
||||||
import de.bixilon.minosoft.logging.LogLevels;
|
import de.bixilon.minosoft.logging.LogLevels;
|
||||||
import de.bixilon.minosoft.modding.event.EventInvoker;
|
import de.bixilon.minosoft.modding.event.EventInvoker;
|
||||||
@ -69,6 +70,7 @@ public class Connection {
|
|||||||
private CommandRootNode commandRootNode;
|
private CommandRootNode commandRootNode;
|
||||||
private ConnectionPing connectionStatusPing;
|
private ConnectionPing connectionStatusPing;
|
||||||
private ServerListPongEvent pong;
|
private ServerListPongEvent pong;
|
||||||
|
private final Renderer renderer = new Renderer(this);
|
||||||
|
|
||||||
public Connection(int connectionId, String hostname, Player player) {
|
public Connection(int connectionId, String hostname, Player player) {
|
||||||
this.connectionId = connectionId;
|
this.connectionId = connectionId;
|
||||||
@ -360,7 +362,10 @@ public class Connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case FAILED_NO_RETRY -> handlePingCallbacks(null);
|
case FAILED_NO_RETRY -> handlePingCallbacks(null);
|
||||||
case PLAY -> Minosoft.CONNECTIONS.put(getConnectionId(), this);
|
case PLAY -> {
|
||||||
|
Minosoft.CONNECTIONS.put(getConnectionId(), this);
|
||||||
|
this.renderer.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// handle callbacks
|
// handle callbacks
|
||||||
fireEvent(new ConnectionStateChangeEvent(this, previousState, state));
|
fireEvent(new ConnectionStateChangeEvent(this, previousState, state));
|
||||||
@ -429,4 +434,8 @@ public class Connection {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("id=%d, address=%s, account=\"%s\")", getConnectionId(), getAddress(), getPlayer().getAccount());
|
return String.format("id=%d, address=%s, account=\"%s\")", getConnectionId(), getAddress(), getPlayer().getAccount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Renderer getRenderer() {
|
||||||
|
return this.renderer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +118,7 @@ public class PacketChunkData extends ClientboundPacket {
|
|||||||
|
|
||||||
connection.getPlayer().getWorld().setChunk(getLocation(), getChunk());
|
connection.getPlayer().getWorld().setChunk(getLocation(), getChunk());
|
||||||
connection.getPlayer().getWorld().setBlockEntityData(getBlockEntities());
|
connection.getPlayer().getWorld().setBlockEntityData(getBlockEntities());
|
||||||
|
connection.getRenderer().prepareChunk(this.location, this.chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,6 +58,7 @@ public class PacketPlayerPositionAndRotation extends ClientboundPacket {
|
|||||||
} else {
|
} else {
|
||||||
connection.sendPacket(new PacketPlayerPositionAndRotationSending(getLocation(), getRotation(), isOnGround()));
|
connection.sendPacket(new PacketPlayerPositionAndRotationSending(getLocation(), getRotation(), isOnGround()));
|
||||||
}
|
}
|
||||||
|
connection.getRenderer().teleport(this.location);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,8 +52,8 @@ public final class ChunkUtil {
|
|||||||
|
|
||||||
// parse data
|
// parse data
|
||||||
int arrayPos = 0;
|
int arrayPos = 0;
|
||||||
HashMap<Byte, ChunkSection> sectionMap = new HashMap<>();
|
HashMap<Integer, ChunkSection> sectionMap = new HashMap<>();
|
||||||
for (byte c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
|
for (int c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
|
||||||
if (BitByte.isBitSet(sectionBitMask, c)) {
|
if (BitByte.isBitSet(sectionBitMask, c)) {
|
||||||
HashMap<InChunkSectionLocation, Block> blockMap = new HashMap<>();
|
HashMap<InChunkSectionLocation, Block> blockMap = new HashMap<>();
|
||||||
|
|
||||||
@ -114,8 +114,8 @@ public final class ChunkUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int arrayPos = 0;
|
int arrayPos = 0;
|
||||||
HashMap<Byte, ChunkSection> sectionMap = new HashMap<>();
|
HashMap<Integer, ChunkSection> sectionMap = new HashMap<>();
|
||||||
for (byte c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
|
for (int c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
|
||||||
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -140,8 +140,8 @@ public final class ChunkUtil {
|
|||||||
return new Chunk(sectionMap);
|
return new Chunk(sectionMap);
|
||||||
}
|
}
|
||||||
// really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712
|
// really big thanks to: https://wiki.vg/index.php?title=Chunk_Format&oldid=13712
|
||||||
HashMap<Byte, ChunkSection> sectionMap = new HashMap<>();
|
HashMap<Integer, ChunkSection> sectionMap = new HashMap<>();
|
||||||
for (byte c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
|
for (int c = 0; c < ProtocolDefinition.SECTIONS_PER_CHUNK; c++) { // max sections per chunks in chunk column
|
||||||
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
if (!BitByte.isBitSet(sectionBitMask, c)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,9 @@ out vec3 vertexColor;
|
|||||||
out vec3 passTextureCoordinates;
|
out vec3 passTextureCoordinates;
|
||||||
|
|
||||||
|
|
||||||
uniform mat4 view;
|
uniform mat4 viewMatrix;
|
||||||
uniform mat4 projection;
|
uniform mat4 projectionMatrix;
|
||||||
|
uniform vec3 chunkPosition;
|
||||||
|
|
||||||
vec2 textureIndexCoordinates[4] = vec2[4](
|
vec2 textureIndexCoordinates[4] = vec2[4](
|
||||||
vec2(0.0f, 0.0f),
|
vec2(0.0f, 0.0f),
|
||||||
@ -18,6 +19,6 @@ vec2(0.0f, 1.0f)
|
|||||||
);
|
);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * view * vec4(inPosition, 1.0f);
|
gl_Position = projectionMatrix * viewMatrix * vec4(inPosition + vec3(chunkPosition.x * 16u, chunkPosition.y * 16u, chunkPosition.z * 16u), 1.0f);
|
||||||
passTextureCoordinates = vec3(textureIndexCoordinates[int(textureIndex)], textureLayer);
|
passTextureCoordinates = vec3(textureIndexCoordinates[int(textureIndex)], textureLayer);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user