mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-07 12:56:31 +01:00
Remove InstancerFactory
This commit is contained in:
parent
79464361d2
commit
bbcf019bc2
18 changed files with 84 additions and 191 deletions
|
@ -1,15 +0,0 @@
|
||||||
package com.jozufozu.flywheel.api.instancer;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
|
||||||
|
|
||||||
public interface InstancerFactory<D extends InstancedPart> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an instancer for the given model. Calling this method twice with the same key will return the same instancer.
|
|
||||||
*
|
|
||||||
* @param modelKey An object that uniquely identifies and provides the model.
|
|
||||||
* @return An instancer for the given model, capable of rendering many copies for little cost.
|
|
||||||
*/
|
|
||||||
Instancer<D> model(Model modelKey);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,12 +1,18 @@
|
||||||
package com.jozufozu.flywheel.api.instancer;
|
package com.jozufozu.flywheel.api.instancer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
|
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
|
|
||||||
public interface InstancerManager {
|
public interface InstancerManager {
|
||||||
|
|
||||||
<D extends InstancedPart> InstancerFactory<D> factory(StructType<D> type);
|
/**
|
||||||
|
* Get an instancer for the given struct type and model. Calling this method twice with the same arguments will return the same instancer.
|
||||||
|
*
|
||||||
|
* @return An instancer for the given struct type and model.
|
||||||
|
*/
|
||||||
|
<D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model);
|
||||||
|
|
||||||
Vec3i getOriginCoordinate();
|
Vec3i getOriginCoordinate();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
|
|
||||||
|
public record InstancerKey<D extends InstancedPart>(StructType<D> type, Model model) {
|
||||||
|
}
|
|
@ -1,18 +1,16 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.batching;
|
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.RenderStage;
|
import com.jozufozu.flywheel.api.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||||
import com.jozufozu.flywheel.core.RenderContext;
|
import com.jozufozu.flywheel.core.RenderContext;
|
||||||
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
|
@ -25,18 +23,10 @@ import net.minecraft.world.phys.Vec3;
|
||||||
public class BatchingEngine implements Engine {
|
public class BatchingEngine implements Engine {
|
||||||
protected final BatchingTransformManager transformManager = new BatchingTransformManager();
|
protected final BatchingTransformManager transformManager = new BatchingTransformManager();
|
||||||
protected final BatchingDrawTracker drawTracker = new BatchingDrawTracker();
|
protected final BatchingDrawTracker drawTracker = new BatchingDrawTracker();
|
||||||
protected final Map<StructType<?>, CPUInstancerFactory<?>> factories = new HashMap<>();
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstancedPart> CPUInstancerFactory<D> factory(StructType<D> type) {
|
public <D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model) {
|
||||||
return (CPUInstancerFactory<D>) factories.computeIfAbsent(type, this::createFactory);
|
return transformManager.getInstancer(type, model);
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private <D extends InstancedPart> CPUInstancerFactory<D> createFactory(StructType<D> type) {
|
|
||||||
return new CPUInstancerFactory<>(type, transformManager::create);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,7 +95,6 @@ public class BatchingEngine implements Engine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
factories.clear();
|
|
||||||
transformManager.delete();
|
transformManager.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,10 @@ import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.ImmutableListMultimap;
|
import com.google.common.collect.ImmutableListMultimap;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.jozufozu.flywheel.api.RenderStage;
|
import com.jozufozu.flywheel.api.RenderStage;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancerKey;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
@ -22,6 +26,7 @@ import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
||||||
public class BatchingTransformManager {
|
public class BatchingTransformManager {
|
||||||
|
private final Map<InstancerKey<?>, CPUInstancer<?>> instancers = new HashMap<>();
|
||||||
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
||||||
private final List<CPUInstancer<?>> allInstancers = new ArrayList<>();
|
private final List<CPUInstancer<?>> allInstancers = new ArrayList<>();
|
||||||
private final Map<RenderStage, TransformSet> transformSets = new EnumMap<>(RenderStage.class);
|
private final Map<RenderStage, TransformSet> transformSets = new EnumMap<>(RenderStage.class);
|
||||||
|
@ -36,8 +41,16 @@ public class BatchingTransformManager {
|
||||||
return transformSetsView;
|
return transformSetsView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(CPUInstancer<?> instancer, Model model) {
|
@SuppressWarnings("unchecked")
|
||||||
uninitializedModels.add(new UninitializedModel(instancer, model));
|
public <D extends InstancedPart> Instancer<D> getInstancer(StructType<D> type, Model model) {
|
||||||
|
InstancerKey<D> key = new InstancerKey<>(type, model);
|
||||||
|
CPUInstancer<D> instancer = (CPUInstancer<D>) instancers.get(key);
|
||||||
|
if (instancer == null) {
|
||||||
|
instancer = new CPUInstancer<>(type);
|
||||||
|
instancers.put(key, instancer);
|
||||||
|
uninitializedModels.add(new UninitializedModel(instancer, model));
|
||||||
|
}
|
||||||
|
return instancer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
@ -52,6 +65,8 @@ public class BatchingTransformManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
instancers.clear();
|
||||||
|
|
||||||
meshPools.values()
|
meshPools.values()
|
||||||
.forEach(BatchedMeshPool::delete);
|
.forEach(BatchedMeshPool::delete);
|
||||||
meshPools.clear();
|
meshPools.clear();
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.batching;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
|
||||||
|
|
||||||
public class CPUInstancerFactory<D extends InstancedPart> implements InstancerFactory<D> {
|
|
||||||
|
|
||||||
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, BiConsumer<CPUInstancer<?>, Model> creationListener) {
|
|
||||||
this.type = type;
|
|
||||||
this.creationListener = creationListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Instancer<D> model(Model modelKey) {
|
|
||||||
return models.computeIfAbsent(modelKey, this::createInstancer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CPUInstancer<D> createInstancer(Model model) {
|
|
||||||
var instancer = new CPUInstancer<>(type);
|
|
||||||
creationListener.accept(instancer, model);
|
|
||||||
return instancer;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,12 +6,8 @@ import java.util.List;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.core.structs.StructTypes;
|
|
||||||
import com.jozufozu.flywheel.core.structs.oriented.OrientedPart;
|
|
||||||
import com.jozufozu.flywheel.core.structs.transformed.TransformedPart;
|
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
||||||
import com.jozufozu.flywheel.util.joml.FrustumIntersection;
|
import com.jozufozu.flywheel.util.joml.FrustumIntersection;
|
||||||
|
|
|
@ -6,19 +6,30 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancerKey;
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.jozufozu.flywheel.util.Pair;
|
import com.jozufozu.flywheel.util.Pair;
|
||||||
|
|
||||||
public class IndirectDrawManager {
|
public class IndirectDrawManager {
|
||||||
|
|
||||||
|
private final Map<InstancerKey<?>, IndirectInstancer<?>> instancers = new HashMap<>();
|
||||||
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
||||||
private final List<IndirectInstancer<?>> allInstancers = new ArrayList<>();
|
private final List<IndirectInstancer<?>> allInstancers = new ArrayList<>();
|
||||||
public final Map<Pair<StructType<?>, VertexType>, IndirectCullingGroup<?>> renderLists = new HashMap<>();
|
public final Map<Pair<StructType<?>, VertexType>, IndirectCullingGroup<?>> renderLists = new HashMap<>();
|
||||||
|
|
||||||
public void create(IndirectInstancer<?> instancer, Model model) {
|
@SuppressWarnings("unchecked")
|
||||||
uninitializedModels.add(new UninitializedModel(instancer, model));
|
public <D extends InstancedPart> Instancer<D> getInstancer(StructType<D> type, Model model) {
|
||||||
|
InstancerKey<D> key = new InstancerKey<>(type, model);
|
||||||
|
IndirectInstancer<D> instancer = (IndirectInstancer<D>) instancers.get(key);
|
||||||
|
if (instancer == null) {
|
||||||
|
instancer = new IndirectInstancer<>(type);
|
||||||
|
instancers.put(key, instancer);
|
||||||
|
uninitializedModels.add(new UninitializedModel(instancer, model));
|
||||||
|
}
|
||||||
|
return instancer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
@ -33,6 +44,8 @@ public class IndirectDrawManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
instancers.clear();
|
||||||
|
|
||||||
renderLists.values()
|
renderLists.values()
|
||||||
.forEach(IndirectCullingGroup::delete);
|
.forEach(IndirectCullingGroup::delete);
|
||||||
renderLists.clear();
|
renderLists.clear();
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.indirect;
|
package com.jozufozu.flywheel.backend.instancing.indirect;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.RenderStage;
|
import com.jozufozu.flywheel.api.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.context.ContextShader;
|
import com.jozufozu.flywheel.api.context.ContextShader;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
|
@ -18,6 +16,7 @@ import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||||
import com.jozufozu.flywheel.core.RenderContext;
|
import com.jozufozu.flywheel.core.RenderContext;
|
||||||
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
@ -31,7 +30,6 @@ import net.minecraft.world.phys.Vec3;
|
||||||
public class IndirectEngine implements Engine {
|
public class IndirectEngine implements Engine {
|
||||||
|
|
||||||
protected final IndirectDrawManager drawManager = new IndirectDrawManager();
|
protected final IndirectDrawManager drawManager = new IndirectDrawManager();
|
||||||
protected final Map<StructType<?>, IndirectInstancerFactory<?>> factories = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set of instance managers that are attached to this engine.
|
* The set of instance managers that are attached to this engine.
|
||||||
|
@ -48,16 +46,9 @@ public class IndirectEngine implements Engine {
|
||||||
this.sqrMaxOriginDistance = sqrMaxOriginDistance;
|
this.sqrMaxOriginDistance = sqrMaxOriginDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstancedPart> IndirectInstancerFactory<D> factory(StructType<D> type) {
|
public <D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model) {
|
||||||
return (IndirectInstancerFactory<D>) factories.computeIfAbsent(type, this::createFactory);
|
return drawManager.getInstancer(type, model);
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private <D extends InstancedPart> IndirectInstancerFactory<D> createFactory(StructType<D> type) {
|
|
||||||
return new IndirectInstancerFactory<>(type, drawManager::create);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,7 +115,6 @@ public class IndirectEngine implements Engine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
factories.clear();
|
|
||||||
drawManager.delete();
|
drawManager.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.indirect;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
|
||||||
|
|
||||||
public class IndirectInstancerFactory<D extends InstancedPart> implements InstancerFactory<D> {
|
|
||||||
|
|
||||||
protected final StructType<D> type;
|
|
||||||
private final BiConsumer<IndirectInstancer<?>, Model> creationListener;
|
|
||||||
protected final Map<Model, IndirectInstancer<D>> models = new HashMap<>();
|
|
||||||
|
|
||||||
public IndirectInstancerFactory(StructType<D> type, BiConsumer<IndirectInstancer<?>, Model> creationListener) {
|
|
||||||
this.type = type;
|
|
||||||
this.creationListener = creationListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Instancer<D> model(Model modelKey) {
|
|
||||||
return models.computeIfAbsent(modelKey, this::createInstancer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IndirectInstancer<D> createInstancer(Model model) {
|
|
||||||
var instancer = new IndirectInstancer<>(type);
|
|
||||||
creationListener.accept(instancer, model);
|
|
||||||
return instancer;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.instancing;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A collection of Instancers that all have the same format.
|
|
||||||
* @param <D>
|
|
||||||
*/
|
|
||||||
public class GPUInstancerFactory<D extends InstancedPart> implements InstancerFactory<D> {
|
|
||||||
|
|
||||||
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;
|
|
||||||
this.creationListener = creationListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Instancer<D> model(Model modelKey) {
|
|
||||||
return models.computeIfAbsent(modelKey, this::createInstancer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private GPUInstancer<D> createInstancer(Model model) {
|
|
||||||
var instancer = new GPUInstancer<>(type);
|
|
||||||
creationListener.accept(instancer, model);
|
|
||||||
return instancer;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,12 +14,17 @@ import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.ImmutableListMultimap;
|
import com.google.common.collect.ImmutableListMultimap;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.jozufozu.flywheel.api.RenderStage;
|
import com.jozufozu.flywheel.api.RenderStage;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstancerKey;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
|
|
||||||
public class InstancingDrawManager {
|
public class InstancingDrawManager {
|
||||||
|
|
||||||
|
private final Map<InstancerKey<?>, GPUInstancer<?>> instancers = new HashMap<>();
|
||||||
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
private final List<UninitializedModel> uninitializedModels = new ArrayList<>();
|
||||||
private final List<GPUInstancer<?>> allInstancers = new ArrayList<>();
|
private final List<GPUInstancer<?>> allInstancers = new ArrayList<>();
|
||||||
private final Map<RenderStage, DrawSet> renderLists = new EnumMap<>(RenderStage.class);
|
private final Map<RenderStage, DrawSet> renderLists = new EnumMap<>(RenderStage.class);
|
||||||
|
@ -29,8 +34,16 @@ public class InstancingDrawManager {
|
||||||
return renderLists.getOrDefault(stage, DrawSet.EMPTY);
|
return renderLists.getOrDefault(stage, DrawSet.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(GPUInstancer<?> instancer, Model model) {
|
@SuppressWarnings("unchecked")
|
||||||
uninitializedModels.add(new UninitializedModel(instancer, model));
|
public <D extends InstancedPart> Instancer<D> getInstancer(StructType<D> type, Model model) {
|
||||||
|
InstancerKey<D> key = new InstancerKey<>(type, model);
|
||||||
|
GPUInstancer<D> instancer = (GPUInstancer<D>) instancers.get(key);
|
||||||
|
if (instancer == null) {
|
||||||
|
instancer = new GPUInstancer<>(type);
|
||||||
|
instancers.put(key, instancer);
|
||||||
|
uninitializedModels.add(new UninitializedModel(instancer, model));
|
||||||
|
}
|
||||||
|
return instancer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
@ -48,6 +61,8 @@ public class InstancingDrawManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
instancers.clear();
|
||||||
|
|
||||||
meshPools.values()
|
meshPools.values()
|
||||||
.forEach(InstancedMeshPool::delete);
|
.forEach(InstancedMeshPool::delete);
|
||||||
meshPools.clear();
|
meshPools.clear();
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.instancing;
|
package com.jozufozu.flywheel.backend.instancing.instancing;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.RenderStage;
|
import com.jozufozu.flywheel.api.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.context.ContextShader;
|
import com.jozufozu.flywheel.api.context.ContextShader;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
|
@ -20,6 +18,7 @@ import com.jozufozu.flywheel.backend.instancing.PipelineCompiler;
|
||||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||||
import com.jozufozu.flywheel.core.Components;
|
import com.jozufozu.flywheel.core.Components;
|
||||||
import com.jozufozu.flywheel.core.RenderContext;
|
import com.jozufozu.flywheel.core.RenderContext;
|
||||||
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
import com.jozufozu.flywheel.core.uniform.UniformBuffer;
|
import com.jozufozu.flywheel.core.uniform.UniformBuffer;
|
||||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
@ -34,7 +33,6 @@ import net.minecraft.world.phys.Vec3;
|
||||||
public class InstancingEngine implements Engine {
|
public class InstancingEngine implements Engine {
|
||||||
|
|
||||||
protected final InstancingDrawManager drawManager = new InstancingDrawManager();
|
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.
|
* The set of instance managers that are attached to this engine.
|
||||||
|
@ -51,16 +49,9 @@ public class InstancingEngine implements Engine {
|
||||||
this.sqrMaxOriginDistance = sqrMaxOriginDistance;
|
this.sqrMaxOriginDistance = sqrMaxOriginDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstancedPart> GPUInstancerFactory<D> factory(StructType<D> type) {
|
public <D extends InstancedPart> Instancer<D> instancer(StructType<D> type, Model model) {
|
||||||
return (GPUInstancerFactory<D>) factories.computeIfAbsent(type, this::createFactory);
|
return drawManager.getInstancer(type, model);
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private <D extends InstancedPart> GPUInstancerFactory<D> createFactory(StructType<D> type) {
|
|
||||||
return new GPUInstancerFactory<>(type, drawManager::create);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -167,7 +158,6 @@ public class InstancingEngine implements Engine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
factories.clear();
|
|
||||||
drawManager.delete();
|
drawManager.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,7 @@ public class BellInstance extends BlockEntityInstance<BellBlockEntity> implement
|
||||||
}
|
}
|
||||||
|
|
||||||
private OrientedPart createBellInstance() {
|
private OrientedPart createBellInstance() {
|
||||||
return instancerManager.factory(StructTypes.ORIENTED)
|
return instancerManager.instancer(StructTypes.ORIENTED, MODEL)
|
||||||
.model(MODEL)
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,15 +123,13 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
||||||
|
|
||||||
private OrientedPart baseInstance() {
|
private OrientedPart baseInstance() {
|
||||||
|
|
||||||
return instancerManager.factory(StructTypes.ORIENTED)
|
return instancerManager.instancer(StructTypes.ORIENTED, BASE.apply(chestType, sprite))
|
||||||
.model(BASE.apply(chestType, sprite))
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransformedPart lidInstance() {
|
private TransformedPart lidInstance() {
|
||||||
|
|
||||||
return instancerManager.factory(StructTypes.TRANSFORMED)
|
return instancerManager.instancer(StructTypes.TRANSFORMED, LID.apply(chestType, sprite))
|
||||||
.model(LID.apply(chestType, sprite))
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,14 +167,12 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
|
||||||
if (shape == RenderShape.INVISIBLE)
|
if (shape == RenderShape.INVISIBLE)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return instancerManager.factory(StructTypes.TRANSFORMED)
|
return instancerManager.instancer(StructTypes.TRANSFORMED, Models.block(blockState))
|
||||||
.model(Models.block(blockState))
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransformedPart getBody() {
|
private TransformedPart getBody() {
|
||||||
return instancerManager.factory(StructTypes.TRANSFORMED)
|
return instancerManager.instancer(StructTypes.TRANSFORMED, MODEL)
|
||||||
.model(MODEL)
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,14 +105,12 @@ public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntit
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransformedPart makeBaseInstance() {
|
private TransformedPart makeBaseInstance() {
|
||||||
return instancerManager.factory(StructTypes.TRANSFORMED)
|
return instancerManager.instancer(StructTypes.TRANSFORMED, BASE.apply(texture))
|
||||||
.model(BASE.apply(texture))
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransformedPart makeLidInstance() {
|
private TransformedPart makeLidInstance() {
|
||||||
return instancerManager.factory(StructTypes.TRANSFORMED)
|
return instancerManager.instancer(StructTypes.TRANSFORMED, LID.apply(texture))
|
||||||
.model(LID.apply(texture))
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -247,8 +247,7 @@ public class ExampleEffect implements Effect {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
instance = instancerManager.factory(StructTypes.TRANSFORMED)
|
instance = instancerManager.instancer(StructTypes.TRANSFORMED, Models.block(Blocks.SHROOMLIGHT.defaultBlockState()))
|
||||||
.model(Models.block(Blocks.SHROOMLIGHT.defaultBlockState()))
|
|
||||||
.createInstance();
|
.createInstance();
|
||||||
|
|
||||||
instance.setBlockLight(15)
|
instance.setBlockLight(15)
|
||||||
|
|
Loading…
Reference in a new issue