From e5c8f43aa92b2bd8e8be5bdd29b24b4323261c87 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Wed, 10 Mar 2021 16:54:51 +0100 Subject: [PATCH] fix 3d biome detection, fix some transparency issues --- .../minosoft/data/mappings/Dimension.kt | 2 ++ .../data/world/biome/BiomeAccessor.kt | 2 +- .../data/world/biome/DummyBiomeAccessor.kt | 3 +- .../data/world/biome/NoiseBiomeAccessor.kt | 9 ++++-- .../data/world/biome/XZBiomeAccessor.kt | 2 +- .../bixilon/minosoft/gui/rendering/Camera.kt | 4 +-- .../minosoft/gui/rendering/RenderConstants.kt | 1 + .../gui/rendering/chunk/WorldRenderer.kt | 31 ++++++++++++------- .../chunk/models/renderable/BlockRenderer.kt | 29 ++++++++++++++--- .../gui/rendering/textures/Texture.kt | 10 ++++-- .../textures/TextureTransparencies.kt | 20 ++++++++++++ 11 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureTransparencies.kt diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/Dimension.kt b/src/main/java/de/bixilon/minosoft/data/mappings/Dimension.kt index 4f7df0370..22366f760 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/Dimension.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/Dimension.kt @@ -46,6 +46,8 @@ data class Dimension( height / ProtocolDefinition.SECTION_HEIGHT_Y } + val supports3DBiomes = resourceLocation.full != "minecraft:overworld" // ToDo + override fun toString(): String { return resourceLocation.toString() } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/BiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/BiomeAccessor.kt index 8fe57d957..24dd904a4 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/BiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/BiomeAccessor.kt @@ -18,5 +18,5 @@ import de.bixilon.minosoft.data.world.BlockPosition interface BiomeAccessor { - fun getBiome(position: BlockPosition): Biome? + fun getBiome(position: BlockPosition, is3d: Boolean = true): Biome? } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/DummyBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/DummyBiomeAccessor.kt index ebc331eae..d8376dce5 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/DummyBiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/DummyBiomeAccessor.kt @@ -17,7 +17,8 @@ import de.bixilon.minosoft.data.mappings.biomes.Biome import de.bixilon.minosoft.data.world.BlockPosition class DummyBiomeAccessor(private val biome: Biome) : BiomeAccessor { - override fun getBiome(position: BlockPosition): Biome { + + override fun getBiome(position: BlockPosition, is3d: Boolean): Biome { return biome } } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/NoiseBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/NoiseBiomeAccessor.kt index 901020f05..4011712e3 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/NoiseBiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/NoiseBiomeAccessor.kt @@ -20,9 +20,14 @@ class NoiseBiomeAccessor( private val biomes: Array, ) : BiomeAccessor { - override fun getBiome(position: BlockPosition): Biome? { + override fun getBiome(position: BlockPosition, is3d: Boolean): Biome? { val inChunk = position.getInChunkSectionPosition() - val index = (inChunk.y / 4 * 16 + ((inChunk.z / 4 * 4) + (inChunk.x / 4))) + val y = if (is3d) { + inChunk.y / 4 * 16 + } else { + 0 + } + val index = (y + ((inChunk.z / 4 * 4) + (inChunk.x / 4))) if (index < 0 || index > biomes.size) { return null } diff --git a/src/main/java/de/bixilon/minosoft/data/world/biome/XZBiomeAccessor.kt b/src/main/java/de/bixilon/minosoft/data/world/biome/XZBiomeAccessor.kt index e1819f9e9..8af1d6d25 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/biome/XZBiomeAccessor.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/biome/XZBiomeAccessor.kt @@ -20,7 +20,7 @@ class XZBiomeAccessor( private val biomes: Array, ) : BiomeAccessor { - override fun getBiome(position: BlockPosition): Biome { + override fun getBiome(position: BlockPosition, is3d: Boolean): Biome { return biomes[(position.x and 0x0F) or ((position.z and 0x0F) shl 4)] } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt index 56971a125..30afc58f7 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/Camera.kt @@ -206,14 +206,14 @@ class Camera( headLocation = Position(cameraPosition) feetLocation = Position(headLocation.x, headLocation.y - PLAYER_HEIGHT, headLocation.z) blockPosition = feetLocation.toBlockPosition() - currentBiome = connection.player.world.getChunk(blockPosition.getChunkPosition())?.biomeAccessor?.getBiome(blockPosition) + currentBiome = connection.player.world.getChunk(blockPosition.getChunkPosition())?.biomeAccessor?.getBiome(blockPosition, connection.player.world.dimension?.supports3DBiomes ?: false) chunkPosition = blockPosition.getChunkPosition() sectionHeight = blockPosition.getSectionHeight() inChunkSectionPosition = blockPosition.getInChunkSectionPosition() // recalculate sky color for current biome val blockPosition = Position(cameraPosition).toBlockPosition() - renderWindow.setSkyColor(connection.player.world.getChunk(blockPosition.getChunkPosition())?.biomeAccessor?.getBiome(blockPosition)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR) + renderWindow.setSkyColor(connection.player.world.getChunk(blockPosition.getChunkPosition())?.biomeAccessor?.getBiome(blockPosition, connection.player.world.dimension?.supports3DBiomes ?: false)?.skyColor ?: RenderConstants.DEFAULT_SKY_COLOR) connection.renderer.renderWindow.worldRenderer.recalculateFrustum(Frustum(this)) connection.player.world.dimension?.hasSkyLight?.let { if (it) { diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt index 2838cab67..1208cbba8 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/RenderConstants.kt @@ -29,6 +29,7 @@ object RenderConstants { val EXPERIENCE_BAR_LEVEL_COLOR = RGBColor("#80ff20") + val HP_TEXT_COLOR = RGBColor("#ff1313") const val COLORMAP_SIZE = 255 diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt index d7da68164..cc7397303 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/WorldRenderer.kt @@ -53,7 +53,7 @@ class WorldRenderer( visibleChunks.add(chunkPosition) } val chunk = world.getChunk(chunkPosition)!! - + val dimensionSupports3dBiomes = connection.player.world.dimension?.supports3DBiomes ?: false val mesh = ChunkMesh() for ((index, blockInfo) in section.blocks.withIndex()) { @@ -67,7 +67,7 @@ class WorldRenderer( neighborBlocks[direction.ordinal] = world.getBlockInfo(blockPosition + direction) } - val biome = chunk.biomeAccessor!!.getBiome(blockPosition) + val biome = chunk.biomeAccessor!!.getBiome(blockPosition, dimensionSupports3dBiomes) var tintColor: RGBColor? = null if (StaticConfiguration.BIOME_DEBUG_MODE) { @@ -106,6 +106,12 @@ class WorldRenderer( override fun postInit() { renderWindow.textures.use(chunkShader, "textureArray") + + for (block in connection.version.mapping.blockStateIdMap.values) { + for (model in block.renders) { + model.postInit() + } + } } override fun draw() { @@ -143,6 +149,7 @@ class WorldRenderer( return textures } + fun prepareChunk(chunkPosition: ChunkPosition, chunk: Chunk? = world.getChunk(chunkPosition), checkQueued: Boolean = true) { if (chunk == null || !chunk.isFullyLoaded) { return @@ -193,17 +200,17 @@ class WorldRenderer( } fun prepareChunkSection(chunkPosition: ChunkPosition, sectionHeight: Int, section: ChunkSection) { - Minosoft.THREAD_POOL.execute { - val mesh = prepareChunk(chunkPosition, sectionHeight, section) + Minosoft.THREAD_POOL.execute { + val mesh = prepareChunk(chunkPosition, sectionHeight, section) - var sectionMap = chunkSectionsToDraw[chunkPosition] - if (sectionMap == null) { - sectionMap = ConcurrentHashMap() - chunkSectionsToDraw[chunkPosition] = sectionMap - } - renderWindow.renderQueue.add { - mesh.load() - sectionMap[sectionHeight]?.unload() + var sectionMap = chunkSectionsToDraw[chunkPosition] + if (sectionMap == null) { + sectionMap = ConcurrentHashMap() + chunkSectionsToDraw[chunkPosition] = sectionMap + } + renderWindow.renderQueue.add { + mesh.load() + sectionMap[sectionHeight]?.unload() sectionMap[sectionHeight] = mesh } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt index 7a72d2eb6..4fc4abecc 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/renderable/BlockRenderer.kt @@ -24,6 +24,7 @@ import de.bixilon.minosoft.data.world.light.LightAccessor import de.bixilon.minosoft.gui.rendering.chunk.ChunkMesh import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel import de.bixilon.minosoft.gui.rendering.textures.Texture +import de.bixilon.minosoft.gui.rendering.textures.TextureTransparencies import glm_.mat4x4.Mat4 class BlockRenderer { @@ -67,18 +68,38 @@ class BlockRenderer { textureMapping[key] = texture!! } } + } + + fun postInit() { for (direction in Directions.DIRECTIONS) { + var directionIsCullface: Boolean? = null + var directionIsNotTransparent: Boolean? = null + var directionIsFull: Boolean? = null for (element in elements) { if (element.isCullFace(direction)) { - cullFaces.add(direction) + directionIsCullface = true } - if (textureMapping[element.getTexture(direction)]?.isTransparent == true) { // THIS IS BROKEN! - transparentFaces.add(direction) + if (textureMapping[element.getTexture(direction)]?.transparency != TextureTransparencies.OPAQUE) { + if (directionIsNotTransparent == null) { + directionIsNotTransparent = false + } + } else { + directionIsNotTransparent = true } if (element.isFullTowards(direction)) { - fullFaceDirections.add(direction) + directionIsFull = true } } + + if (directionIsCullface == true) { + cullFaces.add(direction) + } + if (directionIsNotTransparent == false) { + transparentFaces.add(direction) + } + if (directionIsFull == true) { + fullFaceDirections.add(direction) + } } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/Texture.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/Texture.kt index 69147b3f7..be54d83f1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/Texture.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/Texture.kt @@ -28,7 +28,8 @@ class Texture( var layer = -1 var width: Int = 0 var height: Int = 0 - var isTransparent: Boolean = false + lateinit var transparency: TextureTransparencies + private set lateinit var buffer: ByteBuffer var loaded = false @@ -49,10 +50,13 @@ class Texture( width = decoder.width height = decoder.height buffer.rewind() + transparency = TextureTransparencies.OPAQUE for (i in 0 until buffer.limit() step 4) { val color = RGBColor(buffer.get(), buffer.get(), buffer.get(), buffer.get()) - if (color.alpha < 0xFF) { - isTransparent = true + if (color.alpha == 0x00 && transparency != TextureTransparencies.SEMI_TRANSPARENT) { + transparency = TextureTransparencies.TRANSPARENT + } else if (color.alpha < 0xFF) { + transparency = TextureTransparencies.SEMI_TRANSPARENT } } buffer.flip() diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureTransparencies.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureTransparencies.kt new file mode 100644 index 000000000..f6b0d25ec --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/textures/TextureTransparencies.kt @@ -0,0 +1,20 @@ +/* + * Minosoft + * Copyright (C) 2021 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program.If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.gui.rendering.textures + +enum class TextureTransparencies { + OPAQUE, + TRANSPARENT, + SEMI_TRANSPARENT, +}