diff --git a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java index 3ee18a60be..c70adcc466 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/gui/SodiumGameOptionPages.java @@ -144,12 +144,12 @@ public static OptionPage quality() { .build()); groups.add(OptionGroup.createBuilder() - .add(OptionImpl.createBuilder(boolean.class, vanillaOpts) + .add(OptionImpl.createBuilder(CloudRenderMode.class, vanillaOpts) .setName(Text.translatable("options.renderClouds")) .setTooltip(Text.translatable("sodium.options.clouds_quality.tooltip")) - .setControl(TickBoxControl::new) + .setControl(option -> new CyclingControl<>(option, CloudRenderMode.class, new Text[] { Text.translatable("addServer.resourcePack.disabled"), Text.literal("2D"), Text.literal("3D") })) .setBinding((opts, value) -> { - opts.getCloudRenderMode().setValue(value ? CloudRenderMode.FANCY : CloudRenderMode.OFF); + opts.getCloudRenderMode().setValue(value); if (MinecraftClient.isFabulousGraphicsOrBetter()) { Framebuffer framebuffer = MinecraftClient.getInstance().worldRenderer.getCloudsFramebuffer(); @@ -157,7 +157,7 @@ public static OptionPage quality() { framebuffer.clear(MinecraftClient.IS_SYSTEM_MAC); } } - }, opts -> opts.getCloudRenderMode().getValue() == CloudRenderMode.FANCY) + }, opts -> opts.getCloudRenderMode().getValue()) .setImpact(OptionImpact.LOW) .build()) .add(OptionImpl.createBuilder(SodiumGameOptions.GraphicsQuality.class, sodiumOpts) diff --git a/src/main/java/me/jellysquid/mods/sodium/client/render/immediate/CloudRenderer.java b/src/main/java/me/jellysquid/mods/sodium/client/render/immediate/CloudRenderer.java index 99d8bcadc1..c26e4cd75e 100644 --- a/src/main/java/me/jellysquid/mods/sodium/client/render/immediate/CloudRenderer.java +++ b/src/main/java/me/jellysquid/mods/sodium/client/render/immediate/CloudRenderer.java @@ -13,6 +13,7 @@ import net.minecraft.client.gl.ShaderProgram; import net.minecraft.client.gl.VertexBuffer; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.option.CloudRenderMode; import net.minecraft.client.render.*; import net.minecraft.client.texture.NativeImage; import net.minecraft.client.util.math.MatrixStack; @@ -57,6 +58,7 @@ public class CloudRenderer { private final BackgroundRenderer.FogData fogData = new BackgroundRenderer.FogData(BackgroundRenderer.FogType.FOG_TERRAIN); private int prevCenterCellX, prevCenterCellY, cachedRenderDistance; + private CloudRenderMode cloudRenderMode; public CloudRenderer(ResourceFactory factory) { this.reloadTextures(factory); @@ -86,10 +88,12 @@ public void render(@Nullable ClientWorld world, ClientPlayerEntity player, Matri int centerCellX = (int) (Math.floor(cloudCenterX / 12)); int centerCellZ = (int) (Math.floor(cloudCenterZ / 12)); - if (this.vertexBuffer == null || this.prevCenterCellX != centerCellX || this.prevCenterCellY != centerCellZ || this.cachedRenderDistance != renderDistance) { + if (this.vertexBuffer == null || this.prevCenterCellX != centerCellX || this.prevCenterCellY != centerCellZ || this.cachedRenderDistance != renderDistance || cloudRenderMode != MinecraftClient.getInstance().options.getCloudRenderModeValue()) { BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer(); bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); + this.cloudRenderMode = MinecraftClient.getInstance().options.getCloudRenderModeValue(); + this.rebuildGeometry(bufferBuilder, cloudDistance, centerCellX, centerCellZ); if (this.vertexBuffer == null) { @@ -125,8 +129,9 @@ public void render(@Nullable ClientWorld world, ClientPlayerEntity player, Matri this.vertexBuffer.bind(); boolean insideClouds = cameraY < cloudHeight + 4.5f && cameraY > cloudHeight - 0.5f; + boolean fastClouds = cloudRenderMode == CloudRenderMode.FAST; - if (insideClouds) { + if (insideClouds || fastClouds) { RenderSystem.disableCull(); } else { RenderSystem.enableCull(); @@ -220,6 +225,7 @@ private void applyFogModifiers(ClientWorld world, BackgroundRenderer.FogData fog private void rebuildGeometry(BufferBuilder bufferBuilder, int cloudDistance, int centerCellX, int centerCellZ) { var writer = VertexBufferWriter.of(bufferBuilder); + boolean fastClouds = cloudRenderMode == CloudRenderMode.FAST; for (int offsetX = -cloudDistance; offsetX < cloudDistance; offsetX++) { for (int offsetZ = -cloudDistance; offsetZ < cloudDistance; offsetZ++) { @@ -235,14 +241,14 @@ private void rebuildGeometry(BufferBuilder bufferBuilder, int cloudDistance, int float z = offsetZ * 12; try (MemoryStack stack = MemoryStack.stackPush()) { - final long buffer = stack.nmalloc(6 * 4 * ColorVertex.STRIDE); + final long buffer = stack.nmalloc((fastClouds ? 4 : (6 * 4)) * ColorVertex.STRIDE); long ptr = buffer; int count = 0; // -Y if ((connectedEdges & DIR_NEG_Y) != 0) { - int mixedColor = ColorMixer.mul(texel, CLOUD_COLOR_NEG_Y); + int mixedColor = ColorMixer.mul(texel, fastClouds ? CLOUD_COLOR_POS_Y : CLOUD_COLOR_NEG_Y); ptr = writeVertex(ptr, x + 12, 0.0f, z + 12, mixedColor); ptr = writeVertex(ptr, x + 0.0f, 0.0f, z + 12, mixedColor); @@ -252,6 +258,12 @@ private void rebuildGeometry(BufferBuilder bufferBuilder, int cloudDistance, int count += 4; } + // Only emit -Y geometry to emulate vanilla fast clouds + if (fastClouds) { + writer.push(stack, buffer, count, ColorVertex.FORMAT); + continue; + } + // +Y if ((connectedEdges & DIR_POS_Y) != 0) { int mixedColor = ColorMixer.mul(texel, CLOUD_COLOR_POS_Y);