mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-06 04:16:36 +01:00
BatchingDrawManager
- Merge BatchLists, BatchedModel, and some parts of BatchingEngine into BatchingDrawManager for consistency with instancing code - Have InstancingEngine accept the max origin distance as a constructor parameter - Rename TransformSet to TransformCall
This commit is contained in:
parent
2fe69350ef
commit
ba30aca869
12 changed files with 204 additions and 177 deletions
|
@ -37,7 +37,7 @@ public class InstanceWorld implements AutoCloseable {
|
|||
|
||||
public static InstanceWorld create(LevelAccessor level) {
|
||||
var engine = switch (Backend.getBackendType()) {
|
||||
case INSTANCING -> new InstancingEngine(Components.WORLD);
|
||||
case INSTANCING -> new InstancingEngine(Components.WORLD, 100 * 100);
|
||||
case BATCHING -> new BatchingEngine();
|
||||
case OFF -> throw new IllegalStateException("Cannot create instance world when backend is off.");
|
||||
};
|
||||
|
|
|
@ -7,6 +7,8 @@ import net.minecraft.client.Camera;
|
|||
|
||||
public interface RenderDispatcher {
|
||||
|
||||
void beginFrame(TaskEngine taskEngine, RenderContext context);
|
||||
|
||||
void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage);
|
||||
|
||||
/**
|
||||
|
@ -16,7 +18,5 @@ public interface RenderDispatcher {
|
|||
*/
|
||||
boolean maintainOriginCoordinate(Camera camera);
|
||||
|
||||
void beginFrame(TaskEngine taskEngine, RenderContext context);
|
||||
|
||||
void delete();
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class BatchLists {
|
||||
public final Multimap<RenderType, TransformSet<?>> renderLists = ArrayListMultimap.create();
|
||||
|
||||
public void add(TransformSet<?> set) {
|
||||
renderLists.put(set.getMaterial().getBatchingRenderType(), set);
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
|
||||
public class BatchedModel<D extends InstancedPart> {
|
||||
|
||||
private final StructType<D> type;
|
||||
private final Model model;
|
||||
private final CPUInstancer<D> instancer;
|
||||
private List<TransformSet<D>> layers;
|
||||
|
||||
public BatchedModel(StructType<D> type, Model model) {
|
||||
this.type = type;
|
||||
this.model = model;
|
||||
this.instancer = new CPUInstancer<>(type);
|
||||
}
|
||||
|
||||
public void init(BatchLists batchLists) {
|
||||
layers = model.getMeshes()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(entry -> new TransformSet<>(instancer, entry.getKey(), entry.getValue()))
|
||||
.toList();
|
||||
|
||||
for (TransformSet<D> layer : layers) {
|
||||
batchLists.add(layer);
|
||||
}
|
||||
}
|
||||
|
||||
public Model getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public CPUInstancer<D> getInstancer() {
|
||||
return instancer;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
instancer.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.jozufozu.flywheel.api.RenderStage;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class BatchingDrawManager {
|
||||
|
||||
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
||||
private final List<CPUInstancer<?>> allInstancers = new ArrayList<>();
|
||||
public final Map<RenderStage, TransformSet> renderLists = new EnumMap<>(RenderStage.class);
|
||||
public final BatchDrawingTracker batchTracker = new BatchDrawingTracker();
|
||||
|
||||
public TransformSet get(RenderStage stage) {
|
||||
return renderLists.getOrDefault(stage, TransformSet.EMPTY);
|
||||
}
|
||||
|
||||
public void create(CPUInstancer<?> instancer, Model model) {
|
||||
uninitializedModels.add(new UninitializedModel(instancer, model));
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
for (var model : uninitializedModels) {
|
||||
add(model.instancer(), model.model());
|
||||
}
|
||||
uninitializedModels.clear();
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
allInstancers.forEach(CPUInstancer::delete);
|
||||
allInstancers.clear();
|
||||
}
|
||||
|
||||
public void clearInstancers() {
|
||||
allInstancers.forEach(CPUInstancer::clear);
|
||||
}
|
||||
|
||||
private void add(CPUInstancer<?> instancer, Model model) {
|
||||
var meshes = model.getMeshes();
|
||||
for (var entry : meshes.entrySet()) {
|
||||
TransformCall<?> transformCall = new TransformCall<>(instancer, entry.getKey(), entry.getValue());
|
||||
var material = transformCall.getMaterial();
|
||||
var renderType = material.getBatchingRenderType();
|
||||
|
||||
// renderLists.computeIfAbsent(material.getRenderStage(), TransformSet::new)
|
||||
renderLists.computeIfAbsent(RenderStage.AFTER_FINAL_END_BATCH, TransformSet::new)
|
||||
.put(renderType, transformCall);
|
||||
}
|
||||
allInstancers.add(instancer);
|
||||
}
|
||||
|
||||
public static class TransformSet implements Iterable<Map.Entry<RenderType, Collection<TransformCall<?>>>> {
|
||||
|
||||
public static final TransformSet EMPTY = new TransformSet(ImmutableListMultimap.of());
|
||||
|
||||
final ListMultimap<RenderType, TransformCall<?>> transformCalls;
|
||||
|
||||
public TransformSet(RenderStage renderStage) {
|
||||
transformCalls = ArrayListMultimap.create();
|
||||
}
|
||||
|
||||
public TransformSet(ListMultimap<RenderType, TransformCall<?>> transformCalls) {
|
||||
this.transformCalls = transformCalls;
|
||||
}
|
||||
|
||||
public void put(RenderType shaderState, TransformCall<?> transformCall) {
|
||||
transformCalls.put(shaderState, transformCall);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return transformCalls.isEmpty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<Map.Entry<RenderType, Collection<TransformCall<?>>>> iterator() {
|
||||
return transformCalls.asMap()
|
||||
.entrySet()
|
||||
.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
private record UninitializedModel(CPUInstancer<?> instancer, Model model) {
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.jozufozu.flywheel.api.RenderStage;
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
|
@ -23,36 +24,44 @@ import net.minecraft.world.phys.Vec3;
|
|||
|
||||
public class BatchingEngine implements Engine {
|
||||
|
||||
private final Map<StructType<?>, CPUInstancerFactory<?>> factories = new HashMap<>();
|
||||
private final BatchDrawingTracker batchTracker = new BatchDrawingTracker();
|
||||
|
||||
private final BatchLists batchLists = new BatchLists();
|
||||
|
||||
protected final List<BatchedModel<?>> uninitializedModels = new ArrayList<>();
|
||||
protected final BatchingDrawManager drawManager = new BatchingDrawManager();
|
||||
protected final Map<StructType<?>, CPUInstancerFactory<?>> factories = new HashMap<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
@Override
|
||||
public <D extends InstancedPart> CPUInstancerFactory<D> factory(StructType<D> type) {
|
||||
return (CPUInstancerFactory<D>) factories.computeIfAbsent(type, this::createFactory);
|
||||
}
|
||||
|
||||
public <D extends InstancedPart> CPUInstancerFactory<D> createFactory(StructType<D> type) {
|
||||
return new CPUInstancerFactory<>(type, uninitializedModels::add);
|
||||
@NotNull
|
||||
private <D extends InstancedPart> CPUInstancerFactory<D> createFactory(StructType<D> type) {
|
||||
return new CPUInstancerFactory<>(type, drawManager::create);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getOriginCoordinate() {
|
||||
return BlockPos.ZERO;
|
||||
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
|
||||
drawManager.flush();
|
||||
|
||||
Vec3 cameraPos = context.camera().getPosition();
|
||||
var stack = FlwUtil.copyPoseStack(context.stack());
|
||||
stack.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
|
||||
|
||||
submitTasks(taskEngine, stack, context.level());
|
||||
}
|
||||
|
||||
public void submitTasks(TaskEngine taskEngine, PoseStack stack, ClientLevel level) {
|
||||
batchLists.renderLists.asMap().forEach((renderType, renderList) -> {
|
||||
BatchingDrawManager.TransformSet drawSet = drawManager.get(RenderStage.AFTER_FINAL_END_BATCH);
|
||||
for (var entry : drawSet) {
|
||||
var renderType = entry.getKey();
|
||||
var renderList = entry.getValue();
|
||||
|
||||
int vertices = 0;
|
||||
for (var transformSet : renderList) {
|
||||
vertices += transformSet.getTotalVertexCount();
|
||||
}
|
||||
|
||||
DrawBuffer buffer = batchTracker.getBuffer(renderType);
|
||||
DrawBuffer buffer = drawManager.batchTracker.getBuffer(renderType);
|
||||
buffer.prepare(vertices);
|
||||
|
||||
int startVertex = 0;
|
||||
|
@ -60,7 +69,7 @@ public class BatchingEngine implements Engine {
|
|||
transformSet.submitTasks(taskEngine, buffer, startVertex, stack, level);
|
||||
startVertex += transformSet.getTotalVertexCount();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,11 +81,7 @@ public class BatchingEngine implements Engine {
|
|||
return;
|
||||
}
|
||||
|
||||
batchTracker.endBatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
drawManager.batchTracker.endBatch();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -86,23 +91,19 @@ public class BatchingEngine implements Engine {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
|
||||
for (var model : uninitializedModels) {
|
||||
model.init(batchLists);
|
||||
}
|
||||
|
||||
uninitializedModels.clear();
|
||||
|
||||
Vec3 cameraPos = context.camera().getPosition();
|
||||
var stack = FlwUtil.copyPoseStack(context.stack());
|
||||
stack.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
|
||||
|
||||
submitTasks(taskEngine, stack, context.level());
|
||||
public void attachManagers(InstanceManager<?>... listener) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachManagers(InstanceManager<?>... listener) {
|
||||
// noop
|
||||
public Vec3i getOriginCoordinate() {
|
||||
return BlockPos.ZERO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
factories.clear();
|
||||
drawManager.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.batching;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||
|
@ -12,34 +12,31 @@ import com.jozufozu.flywheel.core.model.Model;
|
|||
|
||||
public class CPUInstancerFactory<D extends InstancedPart> implements InstancerFactory<D> {
|
||||
|
||||
protected final Map<Model, BatchedModel<D>> models;
|
||||
private final StructType<D> type;
|
||||
private final Consumer<BatchedModel<D>> creationListener;
|
||||
protected final StructType<D> type;
|
||||
private final BiConsumer<CPUInstancer<?>, Model> creationListener;
|
||||
protected final Map<Model, CPUInstancer<D>> models = new HashMap<>();
|
||||
|
||||
public CPUInstancerFactory(StructType<D> type, Consumer<BatchedModel<D>> creationListener) {
|
||||
public CPUInstancerFactory(StructType<D> type, BiConsumer<CPUInstancer<?>, Model> creationListener) {
|
||||
this.type = type;
|
||||
|
||||
this.creationListener = creationListener;
|
||||
|
||||
this.models = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instancer<D> model(Model modelKey) {
|
||||
return models.computeIfAbsent(modelKey, this::createModel).getInstancer();
|
||||
return models.computeIfAbsent(modelKey, this::createInstancer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all instance data without freeing resources.
|
||||
*/
|
||||
public void clear() {
|
||||
models.values()
|
||||
.forEach(BatchedModel::clear);
|
||||
}
|
||||
// /**
|
||||
// * Clear all instance data without freeing resources.
|
||||
// */
|
||||
// public void clear() {
|
||||
// models.values()
|
||||
// .forEach(BatchedModel::clear);
|
||||
// }
|
||||
|
||||
private BatchedModel<D> createModel(Model k) {
|
||||
var out = new BatchedModel<>(type, k);
|
||||
creationListener.accept(out);
|
||||
return out;
|
||||
private CPUInstancer<D> createInstancer(Model model) {
|
||||
var instancer = new CPUInstancer<>(type);
|
||||
creationListener.accept(instancer, model);
|
||||
return instancer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@ import com.mojang.math.Vector4f;
|
|||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
||||
public class TransformSet<D extends InstancedPart> {
|
||||
public class TransformCall<D extends InstancedPart> {
|
||||
|
||||
private final CPUInstancer<D> instancer;
|
||||
private final Material material;
|
||||
private final Mesh mesh;
|
||||
|
||||
public TransformSet(CPUInstancer<D> instancer, Material material, Mesh mesh) {
|
||||
public TransformCall(CPUInstancer<D> instancer, Material material, Mesh mesh) {
|
||||
this.instancer = instancer;
|
||||
this.material = material;
|
||||
this.mesh = mesh;
|
||||
|
@ -51,19 +51,19 @@ public class TransformSet<D extends InstancedPart> {
|
|||
ReusableVertexList sub = buffer.slice(startVertex, vertexCount);
|
||||
startVertex += vertexCount;
|
||||
|
||||
pool.submit(() -> drawRange(sub, start, end, stack, level));
|
||||
pool.submit(() -> transformRange(sub, start, end, stack, level));
|
||||
}
|
||||
}
|
||||
|
||||
private void drawRange(ReusableVertexList vertexList, int from, int to, PoseStack stack, ClientLevel level) {
|
||||
drawList(vertexList, instancer.getRange(from, to), stack, level);
|
||||
private void transformRange(ReusableVertexList vertexList, int from, int to, PoseStack stack, ClientLevel level) {
|
||||
transformList(vertexList, instancer.getRange(from, to), stack, level);
|
||||
}
|
||||
|
||||
void drawAll(ReusableVertexList vertexList, PoseStack stack, ClientLevel level) {
|
||||
drawList(vertexList, instancer.getAll(), stack, level);
|
||||
void transformAll(ReusableVertexList vertexList, PoseStack stack, ClientLevel level) {
|
||||
transformList(vertexList, instancer.getAll(), stack, level);
|
||||
}
|
||||
|
||||
private void drawList(ReusableVertexList vertexList, List<D> list, PoseStack stack, ClientLevel level) {
|
||||
private void transformList(ReusableVertexList vertexList, List<D> parts, PoseStack stack, ClientLevel level) {
|
||||
long anchorPtr = vertexList.ptr();
|
||||
int totalVertexCount = vertexList.getVertexCount();
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class TransformSet<D extends InstancedPart> {
|
|||
|
||||
StructType.VertexTransformer<D> structVertexTransformer = instancer.type.getVertexTransformer();
|
||||
|
||||
for (D d : list) {
|
||||
for (D d : parts) {
|
||||
mesh.write(vertexList);
|
||||
|
||||
structVertexTransformer.transform(vertexList, d, level);
|
|
@ -16,9 +16,9 @@ import com.jozufozu.flywheel.core.model.Model;
|
|||
*/
|
||||
public class GPUInstancerFactory<D extends InstancedPart> implements InstancerFactory<D> {
|
||||
|
||||
protected final Map<Model, GPUInstancer<D>> models = new HashMap<>();
|
||||
protected final StructType<D> type;
|
||||
private final BiConsumer<GPUInstancer<?>, Model> creationListener;
|
||||
protected final Map<Model, GPUInstancer<D>> models = new HashMap<>();
|
||||
|
||||
public GPUInstancerFactory(StructType<D> type, BiConsumer<GPUInstancer<?>, Model> creationListener) {
|
||||
this.type = type;
|
||||
|
@ -32,7 +32,7 @@ public class GPUInstancerFactory<D extends InstancedPart> implements InstancerFa
|
|||
|
||||
private GPUInstancer<D> createInstancer(Model model) {
|
||||
var instancer = new GPUInstancer<>(type);
|
||||
this.creationListener.accept(instancer, model);
|
||||
creationListener.accept(instancer, model);
|
||||
return instancer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ public class InstancingDrawManager {
|
|||
return renderLists.getOrDefault(stage, DrawSet.EMPTY);
|
||||
}
|
||||
|
||||
public void create(GPUInstancer<?> gpuInstancer, Model model) {
|
||||
uninitializedModels.add(new UninitializedModel(gpuInstancer, model));
|
||||
public void create(GPUInstancer<?> instancer, Model model) {
|
||||
uninitializedModels.add(new UninitializedModel(instancer, model));
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
|
@ -67,12 +67,12 @@ public class InstancingDrawManager {
|
|||
private void add(GPUInstancer<?> instancer, Model model) {
|
||||
var meshes = model.getMeshes();
|
||||
for (var entry : meshes.entrySet()) {
|
||||
DrawCall layer = new DrawCall(instancer, entry.getKey(), alloc(entry.getValue()));
|
||||
var material = layer.getMaterial();
|
||||
var shaderState = new ShaderState(material, layer.getVertexType(), layer.instancer.type);
|
||||
DrawCall drawCall = new DrawCall(instancer, entry.getKey(), alloc(entry.getValue()));
|
||||
var material = drawCall.getMaterial();
|
||||
var shaderState = new ShaderState(material, drawCall.getVertexType(), drawCall.instancer.type);
|
||||
|
||||
renderLists.computeIfAbsent(material.getRenderStage(), DrawSet::new)
|
||||
.put(shaderState, layer);
|
||||
.put(shaderState, drawCall);
|
||||
}
|
||||
allInstancers.add(instancer);
|
||||
}
|
||||
|
@ -102,8 +102,8 @@ public class InstancingDrawManager {
|
|||
drawCalls.clear();
|
||||
}
|
||||
|
||||
public void put(ShaderState shaderState, DrawCall layer) {
|
||||
drawCalls.put(shaderState, layer);
|
||||
public void put(ShaderState shaderState, DrawCall drawCall) {
|
||||
drawCalls.put(shaderState, drawCall);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
@ -120,6 +120,5 @@ public class InstancingDrawManager {
|
|||
}
|
||||
|
||||
private record UninitializedModel(GPUInstancer<?> instancer, Model model) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.instancing;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -33,25 +34,22 @@ import net.minecraft.world.phys.Vec3;
|
|||
|
||||
public class InstancingEngine implements Engine {
|
||||
|
||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||
|
||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||
|
||||
protected final ContextShader context;
|
||||
|
||||
protected final Map<StructType<?>, GPUInstancerFactory<?>> factories = new HashMap<>();
|
||||
|
||||
protected final InstancingDrawManager drawManager = new InstancingDrawManager();
|
||||
protected final Map<StructType<?>, GPUInstancerFactory<?>> factories = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The set of instance managers that are attached to this engine.
|
||||
*/
|
||||
private final WeakHashSet<InstanceManager<?>> instanceManagers;
|
||||
private final WeakHashSet<InstanceManager<?>> instanceManagers = new WeakHashSet<>();
|
||||
|
||||
public InstancingEngine(ContextShader context) {
|
||||
protected final ContextShader context;
|
||||
protected final int sqrMaxOriginDistance;
|
||||
|
||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||
|
||||
public InstancingEngine(ContextShader context, int sqrMaxOriginDistance) {
|
||||
this.context = context;
|
||||
|
||||
this.instanceManagers = new WeakHashSet<>();
|
||||
this.sqrMaxOriginDistance = sqrMaxOriginDistance;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -66,6 +64,11 @@ public class InstancingEngine implements Engine {
|
|||
return new GPUInstancerFactory<>(type, drawManager::create);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
|
||||
drawManager.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
|
||||
var drawSet = drawManager.get(stage);
|
||||
|
@ -79,7 +82,7 @@ public class InstancingEngine implements Engine {
|
|||
render(drawSet);
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
protected void setup() {
|
||||
GlTextureUnit.T2.makeActive();
|
||||
Minecraft.getInstance().gameRenderer.lightTexture().turnOnLightLayer();
|
||||
|
||||
|
@ -91,10 +94,6 @@ public class InstancingEngine implements Engine {
|
|||
}
|
||||
|
||||
protected void render(InstancingDrawManager.DrawSet drawSet) {
|
||||
if (drawSet.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var entry : drawSet) {
|
||||
var shader = entry.getKey();
|
||||
var drawCalls = entry.getValue();
|
||||
|
@ -118,7 +117,6 @@ public class InstancingEngine implements Engine {
|
|||
}
|
||||
|
||||
protected void setup(ShaderState desc) {
|
||||
|
||||
VertexType vertexType = desc.vertex();
|
||||
FileResolution instanceShader = desc.instance()
|
||||
.getInstanceShader();
|
||||
|
@ -131,22 +129,6 @@ public class InstancingEngine implements Engine {
|
|||
UniformBuffer.getInstance().sync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
factories.clear();
|
||||
drawManager.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getOriginCoordinate() {
|
||||
return originCoordinate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachManagers(InstanceManager<?>... listener) {
|
||||
instanceManagers.addAll(List.of(listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean maintainOriginCoordinate(Camera camera) {
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
|
@ -155,18 +137,13 @@ public class InstancingEngine implements Engine {
|
|||
.subtract(cameraPos)
|
||||
.lengthSqr();
|
||||
|
||||
if (distanceSqr > MAX_ORIGIN_DISTANCE * MAX_ORIGIN_DISTANCE) {
|
||||
if (distanceSqr > sqrMaxOriginDistance) {
|
||||
shiftListeners(Mth.floor(cameraPos.x), Mth.floor(cameraPos.y), Mth.floor(cameraPos.z));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
|
||||
drawManager.flush();
|
||||
}
|
||||
|
||||
private void shiftListeners(int cX, int cY, int cZ) {
|
||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||
|
||||
|
@ -175,6 +152,22 @@ public class InstancingEngine implements Engine {
|
|||
instanceManagers.forEach(InstanceManager::onOriginShift);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachManagers(InstanceManager<?>... listener) {
|
||||
Collections.addAll(instanceManagers, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3i getOriginCoordinate() {
|
||||
return originCoordinate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
factories.clear();
|
||||
drawManager.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDebugInfo(List<String> info) {
|
||||
info.add("GL33 Instanced Arrays");
|
||||
|
|
|
@ -21,7 +21,6 @@ import com.jozufozu.flywheel.core.model.Mesh;
|
|||
|
||||
public class MeshPool {
|
||||
|
||||
|
||||
private final VertexType vertexType;
|
||||
private final Map<Mesh, BufferedMesh> meshes = new HashMap<>();
|
||||
private final List<BufferedMesh> allBuffered = new ArrayList<>();
|
||||
|
|
Loading…
Reference in a new issue