diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/rendering/overlay/weather/WeatherC.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/rendering/overlay/weather/WeatherC.kt new file mode 100644 index 000000000..26da0e278 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/rendering/overlay/weather/WeatherC.kt @@ -0,0 +1,30 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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.config.profile.profiles.rendering.overlay.weather + +import de.bixilon.minosoft.config.profile.profiles.rendering.RenderingProfileManager.delegate + +class WeatherC { + + /** + * Enables rain overlay + */ + var rain by delegate(true) + + /** + * Enables snow overlay + */ + var snow by delegate(true) + +} diff --git a/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt b/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt index bec40a4a4..8fb4ac722 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/biomes/Biome.kt @@ -72,7 +72,7 @@ data class Biome( waterColor = TintManager.getJsonColor(data["water_color"]?.toInt() ?: 0), waterFogColor = TintManager.getJsonColor(data["water_fog_color"]?.toInt() ?: 0), category = registries.biomeCategoryRegistry[data["category"]?.toInt() ?: -1] ?: DEFAULT_CATEGORY, - precipitation = registries.biomePrecipitationRegistry[data["precipitation"]?.toInt() ?: -1] ?: DEFAULT_PRECIPITATION, + precipitation = data["precipitation"]?.toInt()?.let { BiomePrecipitation[it] } ?: BiomePrecipitation.NONE, skyColor = data["sky_color"]?.toInt()?.asRGBColor() ?: RenderConstants.GRASS_FAILOVER_COLOR, fogColor = data["fog_color"]?.toInt()?.asRGBColor(), descriptionId = null, @@ -84,7 +84,6 @@ data class Biome( ) } - private val DEFAULT_PRECIPITATION = BiomePrecipitation("NONE") private val DEFAULT_CATEGORY = BiomeCategory("NONE") } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/biomes/BiomePrecipitation.kt b/src/main/java/de/bixilon/minosoft/data/registries/biomes/BiomePrecipitation.kt index a28bf6a94..7f304744a 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/biomes/BiomePrecipitation.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/biomes/BiomePrecipitation.kt @@ -13,20 +13,17 @@ package de.bixilon.minosoft.data.registries.biomes -import de.bixilon.kutil.cast.CastUtil.unsafeCast -import de.bixilon.minosoft.data.registries.registries.Registries -import de.bixilon.minosoft.data.registries.registries.registry.RegistryFakeEnumerable -import de.bixilon.minosoft.data.registries.registries.registry.codec.IdCodec +import de.bixilon.kutil.enums.EnumUtil +import de.bixilon.kutil.enums.ValuesEnum -data class BiomePrecipitation( - override val name: String, -) : RegistryFakeEnumerable { +enum class BiomePrecipitation { + NONE, + RAIN, + SNOW, + ; - companion object : IdCodec { - override fun deserialize(registries: Registries, data: Map): BiomePrecipitation { - return BiomePrecipitation( - name = data["name"].unsafeCast() - ) - } + companion object : ValuesEnum { + override val VALUES = values() + override val NAME_MAP = EnumUtil.getEnumValues(VALUES) } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt b/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt index be84631ae..887270b59 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt @@ -31,7 +31,6 @@ import de.bixilon.minosoft.data.registries.RegistryUtil import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.biomes.Biome import de.bixilon.minosoft.data.registries.biomes.BiomeCategory -import de.bixilon.minosoft.data.registries.biomes.BiomePrecipitation import de.bixilon.minosoft.data.registries.blocks.entites.BlockEntityTypeRegistry import de.bixilon.minosoft.data.registries.blocks.types.Block import de.bixilon.minosoft.data.registries.chat.ChatMessageType @@ -105,7 +104,6 @@ class Registries { val entityAnimationRegistry: EnumRegistry = EnumRegistry(values = EntityAnimations) val entityActionsRegistry: EnumRegistry = EnumRegistry(values = EntityActionC2SP.EntityActions) - val biomePrecipitationRegistry: FakeEnumRegistry = FakeEnumRegistry(codec = BiomePrecipitation) val biomeCategoryRegistry: FakeEnumRegistry = FakeEnumRegistry(codec = BiomeCategory) val soundGroupRegistry: FakeEnumRegistry = FakeEnumRegistry(codec = SoundGroup) @@ -168,7 +166,6 @@ class Registries { // id stuff worker += WorkerTask(this::biomeCategoryRegistry) { biomeCategoryRegistry.update(pixlyzerData["biome_categories"]?.unsafeCast(), this) } - worker += WorkerTask(this::biomePrecipitationRegistry) { biomePrecipitationRegistry.update(pixlyzerData["biome_precipitations"]?.unsafeCast(), this) } // id resource location stuff worker += WorkerTask(this::containerTypeRegistry) { containerTypeRegistry.rawUpdate(pixlyzerData["container_types"]?.toJsonObject(), this) } @@ -187,7 +184,7 @@ class Registries { worker += WorkerTask(this::materialRegistry) { materialRegistry.rawUpdate(pixlyzerData["materials"]?.toJsonObject(), this) } worker += WorkerTask(this::enchantmentRegistry) { enchantmentRegistry.rawUpdate(pixlyzerData["enchantments"]?.toJsonObject(), this) } worker += WorkerTask(this::statusEffectRegistry) { statusEffectRegistry.rawUpdate(pixlyzerData["status_effects"]?.toJsonObject(), this) } - worker += WorkerTask(this::biomeRegistry, dependencies = arrayOf(this::biomeCategoryRegistry, this::biomePrecipitationRegistry)) { biomeRegistry.rawUpdate(pixlyzerData["biomes"]?.toJsonObject(), this) } + worker += WorkerTask(this::biomeRegistry, dependencies = arrayOf(this::biomeCategoryRegistry)) { biomeRegistry.rawUpdate(pixlyzerData["biomes"]?.toJsonObject(), this) } worker += WorkerTask(this::dimensionRegistry) { dimensionRegistry.rawUpdate(pixlyzerData["dimensions"]?.toJsonObject(), this) } worker += WorkerTask(this::fluidRegistry) { fluidRegistry.rawUpdate(pixlyzerData["fluids"]?.toJsonObject(), this) } worker += WorkerTask(this::blockRegistry, dependencies = arrayOf(this::fluidRegistry, this::shapes)) { blockRegistry.rawUpdate(pixlyzerData["blocks"]?.toJsonObject(), this) } diff --git a/src/main/java/de/bixilon/minosoft/data/world/weather/WorldWeather.kt b/src/main/java/de/bixilon/minosoft/data/world/weather/WorldWeather.kt index e0d8846e0..148edb0f1 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/weather/WorldWeather.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/weather/WorldWeather.kt @@ -14,7 +14,7 @@ package de.bixilon.minosoft.data.world.weather data class WorldWeather( - val rain: Float = 0.0f, + val rain: Float = 1.0f, val thunder: Float = 0.0f, ) { val raining: Boolean get() = rain > 0.0f diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/DefaultOverlays.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/DefaultOverlays.kt index f5fef071b..daac70d2e 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/DefaultOverlays.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/DefaultOverlays.kt @@ -14,6 +14,7 @@ package de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.simple.* +import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.weather.WeatherOverlay object DefaultOverlays { val OVERLAYS = listOf( @@ -23,5 +24,6 @@ object DefaultOverlays { PowderSnowOverlay, FireOverlay, WorldBorderOverlay, + WeatherOverlay, ) } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/weather/WeatherOverlay.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/weather/WeatherOverlay.kt new file mode 100644 index 000000000..2d1270730 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/weather/WeatherOverlay.kt @@ -0,0 +1,121 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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.framebuffer.world.overlay.overlays.weather + +import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.kutil.time.TimeUtil.millis +import de.bixilon.minosoft.data.registries.biomes.BiomePrecipitation +import de.bixilon.minosoft.gui.rendering.RenderWindow +import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.Overlay +import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.OverlayFactory +import de.bixilon.minosoft.gui.rendering.system.base.shader.Shader +import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture +import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture +import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh +import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY +import de.bixilon.minosoft.util.KUtil.minosoft +import de.bixilon.minosoft.util.KUtil.toResourceLocation +import java.util.* + +class WeatherOverlay(private val renderWindow: RenderWindow, private val z: Float) : Overlay { + private val world = renderWindow.connection.world + private val config = renderWindow.connection.profiles.rendering.overlay + private val rain = renderWindow.textureManager.staticTextures.createTexture(RAIN) + private val snow = renderWindow.textureManager.staticTextures.createTexture(SNOW) + private val precipitation get() = renderWindow.connection.player.positionInfo.biome?.precipitation ?: BiomePrecipitation.NONE + override val render: Boolean + get() = world.weather.raining && precipitation != BiomePrecipitation.NONE // ToDo: Check if exposed to the sky + private val texture: AbstractTexture? + get() = when (precipitation) { + BiomePrecipitation.NONE -> null + BiomePrecipitation.RAIN -> rain + BiomePrecipitation.SNOW -> snow + } + + private val shader: Shader = renderWindow.renderSystem.createShader(minosoft("weather/overlay")) + private var mesh = WeatherOverlayMesh(renderWindow) + private var windowSize = Vec2.EMPTY + + + private fun updateMesh(windowSize: Vec2) { + if (mesh.state == Mesh.MeshStates.LOADED) { + mesh.unload() + } + mesh = WeatherOverlayMesh(renderWindow) + + val texture = texture!! + val scale = windowSize.y / texture.size.y + val step = texture.size.x * scale + var offset = 0.0f + val random = Random() + while (true) { + val timeOffset = random.nextFloat(0.0f, 1.0f) + val offsetMultiplicator = random.nextFloat(0.8f, 1.2f) + val alpha = random.nextFloat(0.8f, 1.0f) + mesh.addZQuad( + Vec2(offset, 0), z, Vec2(offset + step, windowSize.y), Vec2(0.0f), texture.textureArrayUV + ) { position, uv -> + val transformed = Vec2() + transformed.x = position.x / (windowSize.x / 2) - 1.0f + transformed.y = position.y / (windowSize.y / 2) - 1.0f + mesh.addVertex(Vec3(transformed.x, transformed.y, z), uv, timeOffset, offsetMultiplicator, alpha) + } + offset += step + if (offset > windowSize.x) { + break + } + } + this.windowSize = windowSize + mesh.load() + } + + override fun init() { + shader.load() + } + + override fun postInit() { + shader.use() + renderWindow.textureManager.staticTextures.use(shader) + } + + private fun updateShader() { + shader.setFloat("uIntensity", world.weather.rain) + val offset = (millis() % 500L) / 500.0f + println("Offset: $offset") + shader.setFloat("uOffset", -offset) + shader.setUInt("uIndexLayer", texture!!.shaderId) +// shader.setVec2("uMaxUV", texture!!.textureArrayUV) + } + + override fun draw() { + renderWindow.renderSystem.reset(blending = true) + val windowSize = renderWindow.window.sizef + if (this.windowSize != windowSize) { + updateMesh(windowSize) + } + shader.use() + updateShader() + mesh.draw() + } + + companion object : OverlayFactory { + private val RAIN = "environment/rain".toResourceLocation().texture() + private val SNOW = "environment/snow".toResourceLocation().texture() + + override fun build(renderWindow: RenderWindow, z: Float): WeatherOverlay { + return WeatherOverlay(renderWindow, z) + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/weather/WeatherOverlayMesh.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/weather/WeatherOverlayMesh.kt new file mode 100644 index 000000000..58b6402e0 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/framebuffer/world/overlay/overlays/weather/WeatherOverlayMesh.kt @@ -0,0 +1,46 @@ +/* + * Minosoft + * Copyright (C) 2020-2022 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.framebuffer.world.overlay.overlays.weather + +import de.bixilon.kotlinglm.vec2.Vec2 +import de.bixilon.kotlinglm.vec3.Vec3 +import de.bixilon.minosoft.gui.rendering.RenderWindow +import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes +import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh +import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct + +open class WeatherOverlayMesh(renderWindow: RenderWindow, primitiveType: PrimitiveTypes = renderWindow.renderSystem.preferredPrimitiveType) : Mesh(renderWindow, WeatherOverlayMeshStruct, primitiveType, initialCacheSize = 2 * 3 * WeatherOverlayMeshStruct.FLOATS_PER_VERTEX) { + + fun addVertex(position: Vec3, uv: Vec2, offset: Float, offsetMultiplicator: Float, alphaMultiplicator: Float) { + data.add(position.x) + data.add(position.y) + data.add(position.z) + data.add(uv.x) + data.add(uv.y) + data.add(offset) + data.add(offsetMultiplicator) + data.add(alphaMultiplicator) + } + + + data class WeatherOverlayMeshStruct( + val position: Vec3, + val uv: Vec2, + val offset: Float, + val vinOffsetMultiplicator: Float, + val alphaMultiplicator: Float, + ) { + companion object : MeshStruct(WeatherOverlayMeshStruct::class) + } +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/GameEventS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/GameEventS2CP.kt index 026458997..40a9dc897 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/GameEventS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/play/GameEventS2CP.kt @@ -22,7 +22,7 @@ import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType -@LoadPacket +@LoadPacket(threadSafe = false) class GameEventS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket { val event = buffer.connection.registries.gameEventRegistry[buffer.readUnsignedByte()] val data: Float = buffer.readFloat() diff --git a/src/main/resources/assets/minosoft/rendering/shader/weather/overlay/overlay.fsh b/src/main/resources/assets/minosoft/rendering/shader/weather/overlay/overlay.fsh new file mode 100644 index 000000000..c067dfd6b --- /dev/null +++ b/src/main/resources/assets/minosoft/rendering/shader/weather/overlay/overlay.fsh @@ -0,0 +1,33 @@ +/* + * Minosoft + * Copyright (C) 2020 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. + */ + +#version 330 core + +out vec4 foutColor; + +in vec2 finUV; +flat in uint finTextureIndex; +in vec3 finTextureCoordinates; + +uniform float uIntensity; + +#include "minosoft:texture" +#include "minosoft:alpha" + +void main() { + vec4 texelColor = getTexture(finTextureIndex, finTextureCoordinates); + texelColor.a *= uIntensity; + foutColor = texelColor; + + discard_alpha(); +} diff --git a/src/main/resources/assets/minosoft/rendering/shader/weather/overlay/overlay.vsh b/src/main/resources/assets/minosoft/rendering/shader/weather/overlay/overlay.vsh new file mode 100644 index 000000000..1cc35ba7b --- /dev/null +++ b/src/main/resources/assets/minosoft/rendering/shader/weather/overlay/overlay.vsh @@ -0,0 +1,40 @@ +/* + * Minosoft + * Copyright (C) 2020 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. + */ + +#version 330 core + +layout (location = 0) in vec3 vinPosition; +layout (location = 1) in vec2 vinUV; +layout (location = 2) in float vinOffset; +layout (location = 3) in float vinOffsetMultiplicator; +layout (location = 4) in float vinAlphaMultiplicator; + + +flat out uint finTextureIndex; +out vec3 finTextureCoordinates; + +uniform vec2 uMaxUV; +uniform float uIntensity; +uniform float uOffset; +uniform uint uIndexLayer; + + +void main() { + gl_Position = vec4(vinPosition, 1.0f); + + finTextureIndex = uIndexLayer >> 28u; + finTextureCoordinates = vec3(vinUV, ((uIndexLayer >> 12) & 0xFFFFu)); + float offset = vinOffset + (uOffset * vinOffsetMultiplicator); + + finTextureCoordinates.y += offset; +}