diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/uniform/LevelUniforms.java b/src/main/java/com/jozufozu/flywheel/backend/engine/uniform/LevelUniforms.java new file mode 100644 index 000000000..b86fb161c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/uniform/LevelUniforms.java @@ -0,0 +1,93 @@ +package com.jozufozu.flywheel.backend.engine.uniform; + +import org.jetbrains.annotations.Nullable; +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.api.event.RenderContext; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.level.Level; + +public class LevelUniforms implements UniformProvider { + public static final int SIZE = 12 * 4 + 2 * 16; + + @Nullable + private RenderContext context; + + @Override + public int byteSize() { + return SIZE; + } + + public void setContext(RenderContext context) { + this.context = context; + } + + @Override + public void write(long ptr) { + Minecraft mc = Minecraft.getInstance(); + ClientLevel level = mc.level; + if (level == null || context == null) { + MemoryUtil.memSet(ptr, 0, SIZE); + return; + } + + float ptick = context.partialTick(); + + long dayTime = level.getDayTime(); + long levelDay = dayTime / 24000L; + long timeOfDay = dayTime - levelDay * 24000L; + MemoryUtil.memPutInt(ptr, (int) (levelDay % 0x7FFFFFFFL)); + ptr += 4; + MemoryUtil.memPutFloat(ptr, (float) timeOfDay / 24000f); + ptr += 4; + + MemoryUtil.memPutInt(ptr, level.dimensionType().hasSkyLight() ? 1 : 0); + ptr += 4; + + float sunAngle = level.getSunAngle(ptick); + MemoryUtil.memPutFloat(ptr, sunAngle); + ptr += 4; + + MemoryUtil.memPutFloat(ptr, level.getMoonBrightness()); + ptr += 4; + MemoryUtil.memPutInt(ptr, level.getMoonPhase()); + ptr += 4; + + MemoryUtil.memPutInt(ptr, level.isRaining() ? 1 : 0); + ptr += 4; + MemoryUtil.memPutFloat(ptr, level.getRainLevel(ptick)); + ptr += 4; + + MemoryUtil.memPutInt(ptr, level.isThundering() ? 1 : 0); + ptr += 4; + MemoryUtil.memPutFloat(ptr, level.getThunderLevel(ptick)); + ptr += 4; + + MemoryUtil.memPutFloat(ptr, level.getSkyDarken(ptick)); + ptr += 4; + + Vec3 skyColor = level.getSkyColor(mc.gameRenderer.getMainCamera().getPosition(), ptick); + ptr = Uniforms.writeVec4(ptr, (float) skyColor.x, (float) skyColor.y, (float) skyColor.z, 1f); + + Vec3 cloudColor = level.getCloudColor(ptick); + ptr = Uniforms.writeVec4(ptr, (float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 1f); + + // TODO: use defines for custom dimension ids + int dimensionId; + ResourceKey dimension = level.dimension(); + if (Level.OVERWORLD.equals(dimension)) { + dimensionId = 0; + } else if (Level.NETHER.equals(dimension)) { + dimensionId = 1; + } else if (Level.END.equals(dimension)) { + dimensionId = 2; + } else { + dimensionId = -1; + } + MemoryUtil.memPutInt(ptr, dimensionId); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/uniform/Uniforms.java b/src/main/java/com/jozufozu/flywheel/backend/engine/uniform/Uniforms.java index 4dee5b305..dfe5d9069 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/uniform/Uniforms.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/uniform/Uniforms.java @@ -23,6 +23,7 @@ public class Uniforms { private static @Nullable UniformBuffer fog; private static @Nullable UniformBuffer options; private static @Nullable UniformBuffer player; + private static @Nullable UniformBuffer level; public static UniformBuffer frame() { if (frame == null) { @@ -47,16 +48,24 @@ public class Uniforms { public static UniformBuffer player() { if (player == null) { - player = new UniformBuffer<>(2, new PlayerUniforms()); + player = new UniformBuffer<>(3, new PlayerUniforms()); } return player; } + public static UniformBuffer level() { + if (level == null) { + level = new UniformBuffer<>(4, new LevelUniforms()); + } + return level; + } + public static void bindForDraw() { bindFrame(); bindFog(); bindOptions(); bindPlayer(); + bindLevel(); } public static void bindFrame() { @@ -83,6 +92,12 @@ public class Uniforms { } } + public static void bindLevel() { + if (level != null) { + level.bind(); + } + } + public static void onFogUpdate() { try (var restoreState = GlStateTracker.getRestoreState()) { fog().update(); @@ -99,6 +114,10 @@ public class Uniforms { var player = player(); player.provider.setContext(ctx); player.update(); + + var level = level(); + level.provider.setContext(ctx); + level.update(); } public static void setDebugMode(DebugMode mode) { @@ -125,6 +144,11 @@ public class Uniforms { player.delete(); player = null; } + + if (level != null) { + level.delete(); + level = null; + } } static long writeVec4(long ptr, float x, float y, float z, float w) { diff --git a/src/main/resources/assets/flywheel/flywheel/internal/uniforms/frame.glsl b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/frame.glsl index add2e2764..1bf1bb410 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/uniforms/frame.glsl +++ b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/frame.glsl @@ -49,9 +49,9 @@ layout(std140) uniform _FlwFrameUniforms { float flw_renderTicks; float flw_renderSeconds; - /** Contains 1 for water, 2 for lava, max-value for any other fluid, 0 for no fluid. */ + /** 0 means no fluid. Use FLW_CAMERA_IN_FLUID_* defines to detect fluid type. */ uint flw_cameraInFluid; - /** Contains 1 for powder snow, max-value for any other block, 0 for no block. */ + /** 0 means no block. Use FLW_CAMERA_IN_BLOCK_* defines to detect block type. */ uint flw_cameraInBlock; uint _flw_debugMode; @@ -61,3 +61,10 @@ layout(std140) uniform _FlwFrameUniforms { #define flw_cameraLook _flw_cameraLook.xyz #define flw_cameraPosPrev _flw_cameraPosPrev.xyz #define flw_cameraLookPrev _flw_cameraLookPrev.xyz + +#define FLW_CAMERA_IN_FLUID_WATER 1 +#define FLW_CAMERA_IN_FLUID_LAVA 2 +#define FLW_CAMERA_IN_FLUID_UNKNOWN 0xFFFFFFFFu + +#define FLW_CAMERA_IN_BLOCK_POWDER_SNOW 1 +#define FLW_CAMERA_IN_BLOCK_UNKNOWN 0xFFFFFFFFu diff --git a/src/main/resources/assets/flywheel/flywheel/internal/uniforms/level.glsl b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/level.glsl new file mode 100644 index 000000000..4a6ff13ca --- /dev/null +++ b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/level.glsl @@ -0,0 +1,31 @@ +layout(std140) uniform _FlwLevelUniforms { + /** The current day number of the level. */ + uint flw_levelDay; + /** The current fraction of the current day that has elapsed. */ + float flw_timeOfDay; + + uint flw_levelHasSkyLight; + + float flw_sunAngle; + + float flw_moonBrightness; + /** There are normally only 8 moon phases. */ + uint flw_moonPhase; + + uint flw_isRaining; + float flw_rainLevel; + uint flw_isThundering; + float flw_thunderLevel; + + float flw_skyDarken; + vec4 flw_skyColor; + vec4 flw_cloudColor; + + /** Use FLW_DIMENSION_* ids to determine the dimension. May eventually be implemented for custom dimensions. */ + uint flw_dimension; +}; + +#define FLW_DIMENSION_OVERWORLD 0 +#define FLW_DIMENSION_NETHER 1 +#define FLW_DIMENSION_END 2 +#define FLW_DIMENSION_UNKNOWN 0xFFFFFFFFu diff --git a/src/main/resources/assets/flywheel/flywheel/internal/uniforms/player.glsl b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/player.glsl index 631b4fb74..7bd7b9989 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/uniforms/player.glsl +++ b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/player.glsl @@ -6,9 +6,9 @@ layout (std140) uniform _FlwPlayerUniforms { vec4 _flw_eyePos; /** The brightness at the player's eye position. */ vec2 flw_eyeBrightness; - /** Contains 1 for water, 2 for lava, max-value for any other fluid, 0 for no fluid. */ + /** 0 means no fluid. Use FLW_PLAYER_EYE_IN_FLUID_* defines to detect fluid type. */ uint flw_playerEyeInFluid; - /** Contains 1 for powder snow, max-value for any other block, 0 for no block. */ + /** 0 means no block. Use FLW_PLAYER_EYE_IN_BLOCK_* defines to detect block type. */ uint flw_playerEyeInBlock; uint flw_playerCrouching; @@ -26,3 +26,10 @@ layout (std140) uniform _FlwPlayerUniforms { }; #define flw_eyePos _flw_eyePos.xyz + +#define FLW_PLAYER_EYE_IN_FLUID_WATER 1 +#define FLW_PLAYER_EYE_IN_FLUID_LAVA 2 +#define FLW_PLAYER_EYE_IN_FLUID_UNKNOWN 0xFFFFFFFFu + +#define FLW_PLAYER_EYE_IN_BLOCK_POWDER_SNOW 1 +#define FLW_PLAYER_EYE_IN_BLOCK_UNKNOWN 0xFFFFFFFFu diff --git a/src/main/resources/assets/flywheel/flywheel/internal/uniforms/uniforms.glsl b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/uniforms.glsl index f2f9324b1..5fac53246 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/uniforms/uniforms.glsl +++ b/src/main/resources/assets/flywheel/flywheel/internal/uniforms/uniforms.glsl @@ -4,3 +4,4 @@ #include "flywheel:internal/uniforms/fog.glsl" #include "flywheel:internal/uniforms/options.glsl" #include "flywheel:internal/uniforms/player.glsl" +#include "flywheel:internal/uniforms/level.glsl"