WorldBorderRenderer.java
net.minecraft.client.renderer.WorldBorderRenderer
信息
- 全限定名:net.minecraft.client.renderer.WorldBorderRenderer
- 类型:public class
- 包:net.minecraft.client.renderer
- 源码路径:src/main/java/net/minecraft/client/renderer/WorldBorderRenderer.java
- 起始行号:L36
- 职责:
TODO
字段/常量
-
FORCEFIELD_LOCATION- 类型:
Identifier - 修饰符:
public static final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
needsRebuild- 类型:
boolean - 修饰符:
private - 源码定位:
L38 - 说明:
TODO
- 类型:
-
lastMinX- 类型:
double - 修饰符:
private - 源码定位:
L39 - 说明:
TODO
- 类型:
-
lastMinZ- 类型:
double - 修饰符:
private - 源码定位:
L40 - 说明:
TODO
- 类型:
-
lastBorderMinX- 类型:
double - 修饰符:
private - 源码定位:
L41 - 说明:
TODO
- 类型:
-
lastBorderMaxX- 类型:
double - 修饰符:
private - 源码定位:
L42 - 说明:
TODO
- 类型:
-
lastBorderMinZ- 类型:
double - 修饰符:
private - 源码定位:
L43 - 说明:
TODO
- 类型:
-
lastBorderMaxZ- 类型:
double - 修饰符:
private - 源码定位:
L44 - 说明:
TODO
- 类型:
-
worldBorderBuffer- 类型:
GpuBuffer - 修饰符:
private final - 源码定位:
L45 - 说明:
TODO
- 类型:
-
indices- 类型:
RenderSystem.AutoStorageIndexBuffer - 修饰符:
private final - 源码定位:
L47 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
- 无
方法
下面的方法块按源码顺序生成。
private void rebuildWorldBorderBuffer(WorldBorderRenderState state, double renderDistance, double cameraZ, double cameraX, float halfHeightY, float v1, float v0) @ L49
- 方法名:rebuildWorldBorderBuffer
- 源码定位:L49
- 返回类型:void
- 修饰符:private
参数:
- state: WorldBorderRenderState
- renderDistance: double
- cameraZ: double
- cameraX: double
- halfHeightY: float
- v1: float
- v0: float
说明:
TODO
public void extract(WorldBorder border, float deltaPartialTick, Vec3 cameraPos, double renderDistance, WorldBorderRenderState state) @ L97
- 方法名:extract
- 源码定位:L97
- 返回类型:void
- 修饰符:public
参数:
- border: WorldBorder
- deltaPartialTick: float
- cameraPos: Vec3
- renderDistance: double
- state: WorldBorderRenderState
说明:
TODO
public void render(WorldBorderRenderState state, Vec3 cameraPos, double renderDistance, double depthFar) @ L121
- 方法名:render
- 源码定位:L121
- 返回类型:void
- 修饰符:public
参数:
- state: WorldBorderRenderState
- cameraPos: Vec3
- renderDistance: double
- depthFar: double
说明:
TODO
public void invalidate() @ L183
- 方法名:invalidate
- 源码定位:L183
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private boolean shouldRebuildWorldBorderBuffer(WorldBorderRenderState state) @ L187
- 方法名:shouldRebuildWorldBorderBuffer
- 源码定位:L187
- 返回类型:boolean
- 修饰符:private
参数:
- state: WorldBorderRenderState
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class WorldBorderRenderer {
public static final Identifier FORCEFIELD_LOCATION = Identifier.withDefaultNamespace("textures/misc/forcefield.png");
private boolean needsRebuild = true;
private double lastMinX;
private double lastMinZ;
private double lastBorderMinX;
private double lastBorderMaxX;
private double lastBorderMinZ;
private double lastBorderMaxZ;
private final GpuBuffer worldBorderBuffer = RenderSystem.getDevice()
.createBuffer(() -> "World border vertex buffer", 40, 16L * DefaultVertexFormat.POSITION_TEX.getVertexSize());
private final RenderSystem.AutoStorageIndexBuffer indices = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS);
private void rebuildWorldBorderBuffer(
WorldBorderRenderState state, double renderDistance, double cameraZ, double cameraX, float halfHeightY, float v1, float v0
) {
try (ByteBufferBuilder byteBufferBuilder = ByteBufferBuilder.exactlySized(DefaultVertexFormat.POSITION_TEX.getVertexSize() * 4 * 4)) {
double borderMinX = state.minX;
double borderMaxX = state.maxX;
double borderMinZ = state.minZ;
double borderMaxZ = state.maxZ;
double minZ = Math.max((double)Mth.floor(cameraZ - renderDistance), borderMinZ);
double maxZ = Math.min((double)Mth.ceil(cameraZ + renderDistance), borderMaxZ);
float u0z = (Mth.floor(minZ) & 1) * 0.5F;
float u1z = (float)(maxZ - minZ) / 2.0F;
double minX = Math.max((double)Mth.floor(cameraX - renderDistance), borderMinX);
double maxX = Math.min((double)Mth.ceil(cameraX + renderDistance), borderMaxX);
float u0x = (Mth.floor(minX) & 1) * 0.5F;
float u1x = (float)(maxX - minX) / 2.0F;
BufferBuilder bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX);
bufferBuilder.addVertex(0.0F, -halfHeightY, (float)(borderMaxZ - minZ)).setUv(u0x, v1);
bufferBuilder.addVertex((float)(maxX - minX), -halfHeightY, (float)(borderMaxZ - minZ)).setUv(u1x + u0x, v1);
bufferBuilder.addVertex((float)(maxX - minX), halfHeightY, (float)(borderMaxZ - minZ)).setUv(u1x + u0x, v0);
bufferBuilder.addVertex(0.0F, halfHeightY, (float)(borderMaxZ - minZ)).setUv(u0x, v0);
bufferBuilder.addVertex(0.0F, -halfHeightY, 0.0F).setUv(u0z, v1);
bufferBuilder.addVertex(0.0F, -halfHeightY, (float)(maxZ - minZ)).setUv(u1z + u0z, v1);
bufferBuilder.addVertex(0.0F, halfHeightY, (float)(maxZ - minZ)).setUv(u1z + u0z, v0);
bufferBuilder.addVertex(0.0F, halfHeightY, 0.0F).setUv(u0z, v0);
bufferBuilder.addVertex((float)(maxX - minX), -halfHeightY, 0.0F).setUv(u0x, v1);
bufferBuilder.addVertex(0.0F, -halfHeightY, 0.0F).setUv(u1x + u0x, v1);
bufferBuilder.addVertex(0.0F, halfHeightY, 0.0F).setUv(u1x + u0x, v0);
bufferBuilder.addVertex((float)(maxX - minX), halfHeightY, 0.0F).setUv(u0x, v0);
bufferBuilder.addVertex((float)(borderMaxX - minX), -halfHeightY, (float)(maxZ - minZ)).setUv(u0z, v1);
bufferBuilder.addVertex((float)(borderMaxX - minX), -halfHeightY, 0.0F).setUv(u1z + u0z, v1);
bufferBuilder.addVertex((float)(borderMaxX - minX), halfHeightY, 0.0F).setUv(u1z + u0z, v0);
bufferBuilder.addVertex((float)(borderMaxX - minX), halfHeightY, (float)(maxZ - minZ)).setUv(u0z, v0);
try (MeshData meshData = bufferBuilder.buildOrThrow()) {
RenderSystem.getDevice().createCommandEncoder().writeToBuffer(this.worldBorderBuffer.slice(), meshData.vertexBuffer());
}
this.lastBorderMinX = borderMinX;
this.lastBorderMaxX = borderMaxX;
this.lastBorderMinZ = borderMinZ;
this.lastBorderMaxZ = borderMaxZ;
this.lastMinX = minX;
this.lastMinZ = minZ;
this.needsRebuild = false;
}
}
public void extract(WorldBorder border, float deltaPartialTick, Vec3 cameraPos, double renderDistance, WorldBorderRenderState state) {
state.minX = border.getMinX(deltaPartialTick);
state.maxX = border.getMaxX(deltaPartialTick);
state.minZ = border.getMinZ(deltaPartialTick);
state.maxZ = border.getMaxZ(deltaPartialTick);
if ((
!(cameraPos.x < state.maxX - renderDistance)
|| !(cameraPos.x > state.minX + renderDistance)
|| !(cameraPos.z < state.maxZ - renderDistance)
|| !(cameraPos.z > state.minZ + renderDistance)
)
&& !(cameraPos.x < state.minX - renderDistance)
&& !(cameraPos.x > state.maxX + renderDistance)
&& !(cameraPos.z < state.minZ - renderDistance)
&& !(cameraPos.z > state.maxZ + renderDistance)) {
state.alpha = 1.0 - border.getDistanceToBorder(cameraPos.x, cameraPos.z) / renderDistance;
state.alpha = Math.pow(state.alpha, 4.0);
state.alpha = Mth.clamp(state.alpha, 0.0, 1.0);
state.tint = border.getStatus().getColor();
} else {
state.alpha = 0.0;
}
}
public void render(WorldBorderRenderState state, Vec3 cameraPos, double renderDistance, double depthFar) {
if (!(state.alpha <= 0.0)) {
double cameraX = cameraPos.x;
double cameraZ = cameraPos.z;
float halfHeightY = (float)depthFar;
float red = ARGB.red(state.tint) / 255.0F;
float green = ARGB.green(state.tint) / 255.0F;
float blue = ARGB.blue(state.tint) / 255.0F;
float offset = (float)(Util.getMillis() % 3000L) / 3000.0F;
float v0 = (float)(-Mth.frac(cameraPos.y * 0.5));
float v1 = v0 + halfHeightY;
if (this.shouldRebuildWorldBorderBuffer(state)) {
this.rebuildWorldBorderBuffer(state, renderDistance, cameraZ, cameraX, halfHeightY, v1, v0);
}
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
AbstractTexture abstractTexture = textureManager.getTexture(FORCEFIELD_LOCATION);
RenderPipeline renderPipeline = RenderPipelines.WORLD_BORDER;
RenderTarget mainRenderTarget = Minecraft.getInstance().getMainRenderTarget();
RenderTarget weatherTarget = Minecraft.getInstance().levelRenderer.getWeatherTarget();
GpuTextureView colorTexture;
GpuTextureView depthTexture;
if (weatherTarget != null) {
colorTexture = weatherTarget.getColorTextureView();
depthTexture = weatherTarget.getDepthTextureView();
} else {
colorTexture = mainRenderTarget.getColorTextureView();
depthTexture = mainRenderTarget.getDepthTextureView();
}
GpuBuffer indexBuffer = this.indices.getBuffer(6);
GpuBufferSlice dynamicTransforms = RenderSystem.getDynamicUniforms()
.writeTransform(
RenderSystem.getModelViewMatrix(),
new Vector4f(red, green, blue, (float)state.alpha),
new Vector3f((float)(this.lastMinX - cameraX), (float)(-cameraPos.y), (float)(this.lastMinZ - cameraZ)),
new Matrix4f().translation(offset, offset, 0.0F)
);
try (RenderPass renderPass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(() -> "World border", colorTexture, OptionalInt.empty(), depthTexture, OptionalDouble.empty())) {
renderPass.setPipeline(renderPipeline);
RenderSystem.bindDefaultUniforms(renderPass);
renderPass.setUniform("DynamicTransforms", dynamicTransforms);
renderPass.setIndexBuffer(indexBuffer, this.indices.type());
renderPass.bindTexture("Sampler0", abstractTexture.getTextureView(), abstractTexture.getSampler());
renderPass.setVertexBuffer(0, this.worldBorderBuffer);
ArrayList<RenderPass.Draw<WorldBorderRenderer>> draws = new ArrayList<>();
for (WorldBorderRenderState.DistancePerDirection distancePerDirection : state.closestBorder(cameraX, cameraZ)) {
if (distancePerDirection.distance() < renderDistance) {
int sideIndex = distancePerDirection.direction().get2DDataValue();
draws.add(new RenderPass.Draw<>(0, this.worldBorderBuffer, indexBuffer, this.indices.type(), 6 * sideIndex, 6, 0));
}
}
renderPass.drawMultipleIndexed(draws, null, null, Collections.emptyList(), this);
}
}
}
public void invalidate() {
this.needsRebuild = true;
}
private boolean shouldRebuildWorldBorderBuffer(WorldBorderRenderState state) {
return this.needsRebuild
|| state.minX != this.lastBorderMinX
|| state.minZ != this.lastBorderMinZ
|| state.maxX != this.lastBorderMaxX
|| state.maxZ != this.lastBorderMaxZ;
}
}引用的其他类
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
RenderSystem.bindDefaultUniforms(), RenderSystem.getDevice(), RenderSystem.getDynamicUniforms(), RenderSystem.getModelViewMatrix(), RenderSystem.getSequentialBuffer()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
BufferBuilder()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ByteBufferBuilder.exactlySized()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ARGB.blue(), ARGB.green(), ARGB.red()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.ceil(), Mth.clamp(), Mth.floor(), Mth.frac()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getMillis()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置: