mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
Model allocators are passed on init instead of stored
This commit is contained in:
parent
ec8b831917
commit
eb5d3c4b25
4 changed files with 42 additions and 31 deletions
|
@ -19,7 +19,6 @@ import com.jozufozu.flywheel.core.model.Model;
|
||||||
|
|
||||||
public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
||||||
|
|
||||||
private final ModelAllocator modelAllocator;
|
|
||||||
private final BufferLayout instanceFormat;
|
private final BufferLayout instanceFormat;
|
||||||
private final Instanced<D> instancedType;
|
private final Instanced<D> instancedType;
|
||||||
|
|
||||||
|
@ -32,9 +31,8 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
||||||
|
|
||||||
protected boolean anyToUpdate;
|
protected boolean anyToUpdate;
|
||||||
|
|
||||||
public GPUInstancer(Instanced<D> type, Model model, ModelAllocator modelAllocator) {
|
public GPUInstancer(Instanced<D> type, Model model) {
|
||||||
super(type::create, model);
|
super(type::create, model);
|
||||||
this.modelAllocator = modelAllocator;
|
|
||||||
this.instanceFormat = type.getLayout();
|
this.instanceFormat = type.getLayout();
|
||||||
instancedType = type;
|
instancedType = type;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +61,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
||||||
return deleted || model == null;
|
return deleted || model == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init(ModelAllocator modelAllocator) {
|
||||||
if (isInitialized()) return;
|
if (isInitialized()) return;
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
|
@ -11,7 +11,6 @@ import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.api.Instancer;
|
import com.jozufozu.flywheel.api.Instancer;
|
||||||
import com.jozufozu.flywheel.api.Material;
|
import com.jozufozu.flywheel.api.Material;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
import com.jozufozu.flywheel.backend.model.ModelAllocator;
|
|
||||||
import com.jozufozu.flywheel.core.model.Model;
|
import com.jozufozu.flywheel.core.model.Model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,14 +19,12 @@ import com.jozufozu.flywheel.core.model.Model;
|
||||||
*/
|
*/
|
||||||
public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||||
|
|
||||||
protected final ModelAllocator allocator;
|
|
||||||
protected final Map<Object, GPUInstancer<D>> models = new HashMap<>();
|
protected final Map<Object, GPUInstancer<D>> models = new HashMap<>();
|
||||||
protected final Instanced<D> type;
|
protected final Instanced<D> type;
|
||||||
protected final List<GPUInstancer<D>> uninitialized = new ArrayList<>();
|
protected final List<GPUInstancer<D>> uninitialized = new ArrayList<>();
|
||||||
|
|
||||||
public InstancedMaterial(Instanced<D> type, ModelAllocator allocator) {
|
public InstancedMaterial(Instanced<D> type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.allocator = allocator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,7 +37,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||||
@Override
|
@Override
|
||||||
public Instancer<D> model(Object key, Supplier<Model> modelSupplier) {
|
public Instancer<D> model(Object key, Supplier<Model> modelSupplier) {
|
||||||
return models.computeIfAbsent(key, $ -> {
|
return models.computeIfAbsent(key, $ -> {
|
||||||
GPUInstancer<D> instancer = new GPUInstancer<>(type, modelSupplier.get(), allocator);
|
GPUInstancer<D> instancer = new GPUInstancer<>(type, modelSupplier.get());
|
||||||
uninitialized.add(instancer);
|
uninitialized.add(instancer);
|
||||||
return instancer;
|
return instancer;
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,27 +32,21 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
||||||
protected final RenderType type;
|
protected final RenderType type;
|
||||||
|
|
||||||
private final Map<Instanced<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
|
private final Map<Instanced<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
|
||||||
private final ModelAllocator allocator;
|
|
||||||
|
|
||||||
|
private ModelAllocator allocator;
|
||||||
private int vertexCount;
|
private int vertexCount;
|
||||||
private int instanceCount;
|
private int instanceCount;
|
||||||
|
|
||||||
public InstancedMaterialGroup(InstancingEngine<P> owner, RenderType type) {
|
public InstancedMaterialGroup(InstancingEngine<P> owner, RenderType type) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
if (GlCompat.getInstance()
|
|
||||||
.onAMDWindows()) {
|
|
||||||
this.allocator = FallbackAllocator.INSTANCE;
|
|
||||||
} else {
|
|
||||||
this.allocator = new ModelPool(Formats.POS_TEX_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstanceData> InstancedMaterial<D> material(StructType<D> type) {
|
public <D extends InstanceData> InstancedMaterial<D> material(StructType<D> type) {
|
||||||
if (type instanceof Instanced<D> instanced) {
|
if (type instanceof Instanced<D> instanced) {
|
||||||
return (InstancedMaterial<D>) materials.computeIfAbsent(instanced, t -> new InstancedMaterial<>(t, allocator));
|
return (InstancedMaterial<D>) materials.computeIfAbsent(instanced, InstancedMaterial::new);
|
||||||
} else {
|
} else {
|
||||||
throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing.");
|
throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing.");
|
||||||
}
|
}
|
||||||
|
@ -82,18 +76,7 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderAll(Matrix4f viewProjection, double camX, double camY, double camZ, RenderLayer layer) {
|
protected void renderAll(Matrix4f viewProjection, double camX, double camY, double camZ, RenderLayer layer) {
|
||||||
// initialize all uninitialized instancers...
|
initializeInstancers();
|
||||||
for (InstancedMaterial<?> material : materials.values()) {
|
|
||||||
for (GPUInstancer<?> instancer : material.uninitialized) {
|
|
||||||
instancer.init();
|
|
||||||
}
|
|
||||||
material.uninitialized.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allocator instanceof ModelPool pool) {
|
|
||||||
// ...and then flush the model arena in case anything was marked for upload
|
|
||||||
pool.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
vertexCount = 0;
|
vertexCount = 0;
|
||||||
instanceCount = 0;
|
instanceCount = 0;
|
||||||
|
@ -119,7 +102,24 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setup(P program) {
|
private void initializeInstancers() {
|
||||||
|
ModelAllocator allocator = getModelAllocator();
|
||||||
|
|
||||||
|
// initialize all uninitialized instancers...
|
||||||
|
for (InstancedMaterial<?> material : materials.values()) {
|
||||||
|
for (GPUInstancer<?> instancer : material.uninitialized) {
|
||||||
|
instancer.init(allocator);
|
||||||
|
}
|
||||||
|
material.uninitialized.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allocator instanceof ModelPool pool) {
|
||||||
|
// ...and then flush the model arena in case anything was marked for upload
|
||||||
|
pool.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setup(P program) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,4 +133,20 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
||||||
|
|
||||||
materials.clear();
|
materials.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ModelAllocator getModelAllocator() {
|
||||||
|
if (allocator == null) {
|
||||||
|
allocator = createAllocator();
|
||||||
|
}
|
||||||
|
return this.allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ModelAllocator createAllocator() {
|
||||||
|
if (GlCompat.getInstance()
|
||||||
|
.onAMDWindows()) {
|
||||||
|
return FallbackAllocator.INSTANCE;
|
||||||
|
} else {
|
||||||
|
return new ModelPool(Formats.POS_TEX_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class CrumblingGroup<P extends CrumblingProgram> extends InstancedMateria
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(P p) {
|
protected void setup(P p) {
|
||||||
p.setAtlasSize(width, height);
|
p.setAtlasSize(width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue