weater overlay

This commit is contained in:
Bixilon 2022-11-02 22:43:28 +01:00
parent 060381bacc
commit 2bebd937d0
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
11 changed files with 286 additions and 21 deletions

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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)
}

View File

@ -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")
}

View File

@ -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<BiomePrecipitation> {
override fun deserialize(registries: Registries, data: Map<String, Any>): BiomePrecipitation {
return BiomePrecipitation(
name = data["name"].unsafeCast()
)
}
companion object : ValuesEnum<BiomePrecipitation> {
override val VALUES = values()
override val NAME_MAP = EnumUtil.getEnumValues(VALUES)
}
}

View File

@ -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<EntityAnimations> = EnumRegistry(values = EntityAnimations)
val entityActionsRegistry: EnumRegistry<EntityActionC2SP.EntityActions> = EnumRegistry(values = EntityActionC2SP.EntityActions)
val biomePrecipitationRegistry: FakeEnumRegistry<BiomePrecipitation> = FakeEnumRegistry(codec = BiomePrecipitation)
val biomeCategoryRegistry: FakeEnumRegistry<BiomeCategory> = FakeEnumRegistry(codec = BiomeCategory)
val soundGroupRegistry: FakeEnumRegistry<SoundGroup> = 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) }

View File

@ -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

View File

@ -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,
)
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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<WeatherOverlay> {
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)
}
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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)
}
}

View File

@ -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()

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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();
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*
* 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;
}