-
Notifications
You must be signed in to change notification settings - Fork 382
/
TerrainRenderContext.java
131 lines (112 loc) · 4.64 KB
/
TerrainRenderContext.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.client.indigo.renderer.render;
import java.util.function.Consumer;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.chunk.BlockBufferBuilderStorage;
import net.minecraft.client.render.chunk.ChunkBuilder.ChunkData;
import net.minecraft.client.render.chunk.ChunkBuilder.BuiltChunk;
import net.minecraft.client.render.chunk.ChunkRendererRegion;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.crash.CrashException;
import net.minecraft.util.crash.CrashReport;
import net.minecraft.util.crash.CrashReportSection;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Matrix3f;
import net.minecraft.client.util.math.MatrixStack;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator;
/**
* Implementation of {@link RenderContext} used during terrain rendering.
* Dispatches calls from models during chunk rebuild to the appropriate consumer,
* and holds/manages all of the state needed by them.
*/
public class TerrainRenderContext extends AbstractRenderContext implements RenderContext {
public static final ThreadLocal<TerrainRenderContext> POOL = ThreadLocal.withInitial(TerrainRenderContext::new);
private final TerrainBlockRenderInfo blockInfo = new TerrainBlockRenderInfo();
private final ChunkRenderInfo chunkInfo = new ChunkRenderInfo();
private final AoCalculator aoCalc = new AoCalculator(blockInfo, chunkInfo::cachedBrightness, chunkInfo::cachedAoLevel);
private final AbstractMeshConsumer meshConsumer = new AbstractMeshConsumer(blockInfo, chunkInfo::getInitializedBuffer, aoCalc, this::transform) {
@Override
protected int overlay() {
return overlay;
}
@Override
protected Matrix4f matrix() {
return matrix;
}
@Override
protected Matrix3f normalMatrix() {
return normalMatrix;
}
};
private final TerrainFallbackConsumer fallbackConsumer = new TerrainFallbackConsumer(blockInfo, chunkInfo::getInitializedBuffer, aoCalc, this::transform) {
@Override
protected int overlay() {
return overlay;
}
@Override
protected Matrix4f matrix() {
return matrix;
}
@Override
protected Matrix3f normalMatrix() {
return normalMatrix;
}
};
public TerrainRenderContext prepare(ChunkRendererRegion blockView, BuiltChunk chunkRenderer, ChunkData chunkData, BlockBufferBuilderStorage builders) {
blockInfo.setBlockView(blockView);
chunkInfo.prepare(blockView, chunkRenderer, chunkData, builders);
return this;
}
public void release() {
chunkInfo.release();
blockInfo.release();
}
/** Called from chunk renderer hook. */
public boolean tesselateBlock(BlockState blockState, BlockPos blockPos, final BakedModel model, MatrixStack matrixStack) {
this.matrix = matrixStack.peek().getModel();
this.normalMatrix = matrixStack.peek().getNormal();
try {
aoCalc.clear();
blockInfo.prepareForBlock(blockState, blockPos, model.useAmbientOcclusion());
((FabricBakedModel) model).emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
} catch (Throwable var9) {
CrashReport crashReport_1 = CrashReport.create(var9, "Tesselating block in world - Indigo Renderer");
CrashReportSection crashReportElement_1 = crashReport_1.addElement("Block being tesselated");
CrashReportSection.addBlockInfo(crashReportElement_1, chunkInfo.blockView, blockPos, blockState);
throw new CrashException(crashReport_1);
}
// false because we've already marked the chunk as populated - caller doesn't need to
return false;
}
@Override
public Consumer<Mesh> meshConsumer() {
return meshConsumer;
}
@Override
public Consumer<BakedModel> fallbackConsumer() {
return fallbackConsumer;
}
@Override
public QuadEmitter getEmitter() {
return meshConsumer.getEmitter();
}
}