package net.minecraft.client.renderer; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.BufferUploader; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.MeshData; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.Util; import net.minecraft.client.Minecraft; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.ARGB; import net.minecraft.util.Mth; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.phys.Vec3; @Environment(EnvType.CLIENT) public class WorldBorderRenderer { private static final ResourceLocation FORCEFIELD_LOCATION = ResourceLocation.withDefaultNamespace("textures/misc/forcefield.png"); public void render(WorldBorder worldBorder, Vec3 cameraPosition, double renderDistance, double farPlaneDepth) { double d = worldBorder.getMinX(); double e = worldBorder.getMaxX(); double f = worldBorder.getMinZ(); double g = worldBorder.getMaxZ(); if (!(cameraPosition.x < e - renderDistance) || !(cameraPosition.x > d + renderDistance) || !(cameraPosition.z < g - renderDistance) || !(cameraPosition.z > f + renderDistance)) { double h = 1.0 - worldBorder.getDistanceToBorder(cameraPosition.x, cameraPosition.z) / renderDistance; h = Math.pow(h, 4.0); h = Mth.clamp(h, 0.0, 1.0); double i = cameraPosition.x; double j = cameraPosition.z; float k = (float)farPlaneDepth; RenderSystem.enableBlend(); RenderSystem.enableDepthTest(); RenderSystem.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO ); RenderSystem.setShaderTexture(0, FORCEFIELD_LOCATION); RenderSystem.depthMask(Minecraft.useShaderTransparency()); int l = worldBorder.getStatus().getColor(); float m = ARGB.red(l) / 255.0F; float n = ARGB.green(l) / 255.0F; float o = ARGB.blue(l) / 255.0F; RenderSystem.setShaderColor(m, n, o, (float)h); RenderSystem.setShader(CoreShaders.POSITION_TEX); RenderSystem.polygonOffset(-3.0F, -3.0F); RenderSystem.enablePolygonOffset(); RenderSystem.disableCull(); float p = (float)(Util.getMillis() % 3000L) / 3000.0F; float q = (float)(-Mth.frac(cameraPosition.y * 0.5)); float r = q + k; BufferBuilder bufferBuilder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); double s = Math.max(Mth.floor(j - renderDistance), f); double t = Math.min(Mth.ceil(j + renderDistance), g); float u = (Mth.floor(s) & 1) * 0.5F; if (i > e - renderDistance) { float v = u; for (double w = s; w < t; v += 0.5F) { double x = Math.min(1.0, t - w); float y = (float)x * 0.5F; bufferBuilder.addVertex((float)(e - i), -k, (float)(w - j)).setUv(p - v, p + r); bufferBuilder.addVertex((float)(e - i), -k, (float)(w + x - j)).setUv(p - (y + v), p + r); bufferBuilder.addVertex((float)(e - i), k, (float)(w + x - j)).setUv(p - (y + v), p + q); bufferBuilder.addVertex((float)(e - i), k, (float)(w - j)).setUv(p - v, p + q); w++; } } if (i < d + renderDistance) { float v = u; for (double w = s; w < t; v += 0.5F) { double x = Math.min(1.0, t - w); float y = (float)x * 0.5F; bufferBuilder.addVertex((float)(d - i), -k, (float)(w - j)).setUv(p + v, p + r); bufferBuilder.addVertex((float)(d - i), -k, (float)(w + x - j)).setUv(p + y + v, p + r); bufferBuilder.addVertex((float)(d - i), k, (float)(w + x - j)).setUv(p + y + v, p + q); bufferBuilder.addVertex((float)(d - i), k, (float)(w - j)).setUv(p + v, p + q); w++; } } s = Math.max(Mth.floor(i - renderDistance), d); t = Math.min(Mth.ceil(i + renderDistance), e); u = (Mth.floor(s) & 1) * 0.5F; if (j > g - renderDistance) { float v = u; for (double w = s; w < t; v += 0.5F) { double x = Math.min(1.0, t - w); float y = (float)x * 0.5F; bufferBuilder.addVertex((float)(w - i), -k, (float)(g - j)).setUv(p + v, p + r); bufferBuilder.addVertex((float)(w + x - i), -k, (float)(g - j)).setUv(p + y + v, p + r); bufferBuilder.addVertex((float)(w + x - i), k, (float)(g - j)).setUv(p + y + v, p + q); bufferBuilder.addVertex((float)(w - i), k, (float)(g - j)).setUv(p + v, p + q); w++; } } if (j < f + renderDistance) { float v = u; for (double w = s; w < t; v += 0.5F) { double x = Math.min(1.0, t - w); float y = (float)x * 0.5F; bufferBuilder.addVertex((float)(w - i), -k, (float)(f - j)).setUv(p - v, p + r); bufferBuilder.addVertex((float)(w + x - i), -k, (float)(f - j)).setUv(p - (y + v), p + r); bufferBuilder.addVertex((float)(w + x - i), k, (float)(f - j)).setUv(p - (y + v), p + q); bufferBuilder.addVertex((float)(w - i), k, (float)(f - j)).setUv(p - v, p + q); w++; } } MeshData meshData = bufferBuilder.build(); if (meshData != null) { BufferUploader.drawWithShader(meshData); } RenderSystem.enableCull(); RenderSystem.polygonOffset(0.0F, 0.0F); RenderSystem.disablePolygonOffset(); RenderSystem.disableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.depthMask(true); } } }