mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-28 16:06:28 +01:00
StructType doesn't need #asBatched and #asInstanced
- More organized this way - BatchingTransformer function moved into Batched
This commit is contained in:
parent
a43fe2bc9a
commit
4908abc9e0
17 changed files with 70 additions and 79 deletions
|
@ -1,11 +1,8 @@
|
|||
package com.jozufozu.flywheel.api.struct;
|
||||
|
||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||
|
||||
public interface Batched<S> extends StructType<S> {
|
||||
|
||||
BatchingTransformer<S> getTransformer();
|
||||
|
||||
@Override
|
||||
default Batched<S> asBatched() {
|
||||
return this;
|
||||
}
|
||||
void transform(S d, ModelTransformer.Params b);
|
||||
}
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.struct;
|
||||
|
||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface BatchingTransformer<S> {
|
||||
|
||||
void transform(S s, ModelTransformer.Params b);
|
||||
}
|
|
@ -14,8 +14,4 @@ public interface Instanced<S> extends StructType<S> {
|
|||
|
||||
ResourceLocation getProgramSpec();
|
||||
|
||||
@Override
|
||||
default Instanced<S> asInstanced() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,4 @@ public interface StructType<S> {
|
|||
*/
|
||||
VertexFormat format();
|
||||
|
||||
Instanced<S> asInstanced();
|
||||
|
||||
Batched<S> asBatched();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.Instancer;
|
||||
|
@ -10,13 +11,13 @@ import com.jozufozu.flywheel.core.model.Model;
|
|||
|
||||
public abstract class AbstractInstancer<D extends InstanceData> implements Instancer<D> {
|
||||
|
||||
protected final StructType<D> type;
|
||||
protected final Supplier<D> type;
|
||||
protected final Model modelData;
|
||||
protected final ArrayList<D> data = new ArrayList<>();
|
||||
|
||||
protected boolean anyToRemove;
|
||||
|
||||
protected AbstractInstancer(StructType<D> type, Model modelData) {
|
||||
protected AbstractInstancer(Supplier<D> type, Model modelData) {
|
||||
this.type = type;
|
||||
this.modelData = modelData;
|
||||
}
|
||||
|
@ -26,7 +27,7 @@ public abstract class AbstractInstancer<D extends InstanceData> implements Insta
|
|||
*/
|
||||
@Override
|
||||
public D createInstance() {
|
||||
return _add(type.create());
|
||||
return _add(type.get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,7 @@ import java.util.function.Supplier;
|
|||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.Instancer;
|
||||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.struct.Batched;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
@ -15,9 +15,9 @@ import com.mojang.blaze3d.vertex.VertexConsumer;
|
|||
public class BatchedMaterial<D extends InstanceData> implements Material<D> {
|
||||
|
||||
protected final Map<Object, CPUInstancer<D>> models;
|
||||
private final StructType<D> type;
|
||||
private final Batched<D> type;
|
||||
|
||||
public BatchedMaterial(StructType<D> type) {
|
||||
public BatchedMaterial(Batched<D> type) {
|
||||
this.type = type;
|
||||
|
||||
this.models = new HashMap<>();
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Map;
|
|||
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.MaterialGroup;
|
||||
import com.jozufozu.flywheel.api.struct.Batched;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||
import com.jozufozu.flywheel.backend.model.DirectBufferBuilder;
|
||||
|
@ -19,7 +20,7 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
|||
|
||||
protected final RenderType state;
|
||||
|
||||
private final Map<StructType<? extends InstanceData>, BatchedMaterial<?>> materials = new HashMap<>();
|
||||
private final Map<Batched<? extends InstanceData>, BatchedMaterial<?>> materials = new HashMap<>();
|
||||
|
||||
public BatchedMaterialGroup(RenderType state) {
|
||||
this.state = state;
|
||||
|
@ -27,8 +28,12 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <D extends InstanceData> BatchedMaterial<D> material(StructType<D> spec) {
|
||||
return (BatchedMaterial<D>) materials.computeIfAbsent(spec, BatchedMaterial::new);
|
||||
public <D extends InstanceData> BatchedMaterial<D> material(StructType<D> type) {
|
||||
if (type instanceof Batched<D> batched) {
|
||||
return (BatchedMaterial<D>) materials.computeIfAbsent(batched, BatchedMaterial::new);
|
||||
} else {
|
||||
throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing.");
|
||||
}
|
||||
}
|
||||
|
||||
public void render(PoseStack stack, MultiBufferSource source, TaskEngine pool) {
|
||||
|
|
|
@ -49,9 +49,7 @@ public class BatchingEngine implements Engine {
|
|||
|
||||
stack.translate(-event.camX, -event.camY, -event.camZ);
|
||||
|
||||
for (Map.Entry<RenderType, BatchedMaterialGroup> entry : layers.get(event.getLayer()).entrySet()) {
|
||||
BatchedMaterialGroup group = entry.getValue();
|
||||
|
||||
for (BatchedMaterialGroup group : layers.get(event.getLayer()).values()) {
|
||||
group.render(stack, buffers, taskEngine);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.batching;
|
||||
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.struct.BatchingTransformer;
|
||||
import com.jozufozu.flywheel.api.struct.Batched;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
|
||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||
|
@ -13,22 +13,17 @@ import com.mojang.blaze3d.vertex.VertexConsumer;
|
|||
|
||||
public class CPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
||||
|
||||
private final BatchingTransformer<D> transform;
|
||||
private final Batched<D> batchingType;
|
||||
|
||||
private final ModelTransformer sbb;
|
||||
private final ModelTransformer.Params defaultParams;
|
||||
|
||||
public CPUInstancer(StructType<D> type, Model modelData) {
|
||||
super(type, modelData);
|
||||
public CPUInstancer(Batched<D> type, Model modelData) {
|
||||
super(type::create, modelData);
|
||||
batchingType = type;
|
||||
|
||||
sbb = new ModelTransformer(modelData);
|
||||
defaultParams = ModelTransformer.Params.defaultParams();
|
||||
transform = type.asBatched()
|
||||
.getTransformer();
|
||||
|
||||
if (transform == null) {
|
||||
throw new NullPointerException("Cannot batch " + type.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void submitTasks(PoseStack stack, TaskEngine pool, DirectVertexConsumer consumer) {
|
||||
|
@ -56,7 +51,7 @@ public class CPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
ModelTransformer.Params params = defaultParams.copy();
|
||||
|
||||
for (D d : data.subList(from, to)) {
|
||||
transform.transform(d, params);
|
||||
batchingType.transform(d, params);
|
||||
|
||||
sbb.renderInto(params, stack, buffer);
|
||||
|
||||
|
@ -67,7 +62,7 @@ public class CPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
void drawAll(PoseStack stack, VertexConsumer buffer) {
|
||||
ModelTransformer.Params params = defaultParams.copy();
|
||||
for (D d : data) {
|
||||
transform.transform(d, params);
|
||||
batchingType.transform(d, params);
|
||||
|
||||
sbb.renderInto(params, stack, buffer);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.BitSet;
|
|||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
|
@ -23,6 +24,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
|
||||
private final ModelAllocator modelAllocator;
|
||||
private final VertexFormat instanceFormat;
|
||||
private final Instanced<D> instancedType;
|
||||
|
||||
private IBufferedModel model;
|
||||
private GlVertexArray vao;
|
||||
|
@ -34,10 +36,11 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
|
||||
protected boolean anyToUpdate;
|
||||
|
||||
public GPUInstancer(StructType<D> type, Model model, ModelAllocator modelAllocator) {
|
||||
super(type, model);
|
||||
public GPUInstancer(Instanced<D> type, Model model, ModelAllocator modelAllocator) {
|
||||
super(type::create, model);
|
||||
this.modelAllocator = modelAllocator;
|
||||
this.instanceFormat = type.format();
|
||||
instancedType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,8 +155,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
|
||||
try (MappedBuffer mapped = instanceVBO.getBuffer(0, glBufferSize)) {
|
||||
|
||||
final StructWriter<D> writer = type.asInstanced()
|
||||
.getWriter(mapped);
|
||||
final StructWriter<D> writer = instancedType.getWriter(mapped);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
final D element = data.get(i);
|
||||
|
@ -176,8 +178,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
instanceVBO.alloc(glBufferSize);
|
||||
|
||||
try (MappedBuffer buffer = instanceVBO.getBuffer(0, glBufferSize)) {
|
||||
StructWriter<D> writer = type.asInstanced()
|
||||
.getWriter(buffer);
|
||||
StructWriter<D> writer = instancedType.getWriter(buffer);
|
||||
for (D datum : data) {
|
||||
writer.write(datum);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.Instancer;
|
||||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.RenderWork;
|
||||
import com.jozufozu.flywheel.backend.model.ImmediateAllocator;
|
||||
|
@ -25,10 +25,10 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
|||
|
||||
final ModelAllocator allocator;
|
||||
protected final Cache<Object, GPUInstancer<D>> models;
|
||||
protected final StructType<D> type;
|
||||
protected final Instanced<D> type;
|
||||
|
||||
public InstancedMaterial(StructType<D> spec) {
|
||||
this.type = spec;
|
||||
public InstancedMaterial(Instanced<D> type) {
|
||||
this.type = type;
|
||||
|
||||
if (Backend.getInstance().compat.onAMDWindows()) {
|
||||
allocator = ImmediateAllocator.INSTANCE;
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Map;
|
|||
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.MaterialGroup;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
|
@ -25,7 +26,7 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
|||
protected final InstancingEngine<P> owner;
|
||||
protected final RenderType type;
|
||||
|
||||
private final Map<StructType<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
|
||||
private final Map<Instanced<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
|
||||
|
||||
public InstancedMaterialGroup(InstancingEngine<P> owner, RenderType type) {
|
||||
this.owner = owner;
|
||||
|
@ -34,8 +35,12 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <D extends InstanceData> InstancedMaterial<D> material(StructType<D> spec) {
|
||||
return (InstancedMaterial<D>) materials.computeIfAbsent(spec, InstancedMaterial::new);
|
||||
public <D extends InstanceData> InstancedMaterial<D> material(StructType<D> type) {
|
||||
if (type instanceof Instanced<D> instanced) {
|
||||
return (InstancedMaterial<D>) materials.computeIfAbsent(instanced, InstancedMaterial::new);
|
||||
} else {
|
||||
throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing.");
|
||||
}
|
||||
}
|
||||
|
||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||
|
@ -46,7 +51,7 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
|||
}
|
||||
|
||||
protected void renderAll(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||
for (Map.Entry<StructType<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||
InstancedMaterial<?> material = entry.getValue();
|
||||
if (material.nothingToRender()) continue;
|
||||
|
||||
|
@ -61,7 +66,6 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
|
|||
}
|
||||
|
||||
P program = owner.getProgram(entry.getKey()
|
||||
.asInstanced()
|
||||
.getProgramSpec()).get();
|
||||
|
||||
program.bind();
|
||||
|
|
|
@ -109,6 +109,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
}
|
||||
|
||||
private Stream<InstancedMaterialGroup<P>> getGroupsToRender(@Nullable RenderLayer layer) {
|
||||
// layer is null when this is called from CrumblingRenderer
|
||||
if (layer != null) {
|
||||
return layers.get(layer)
|
||||
.values()
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.backend.struct;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
|
@ -2,9 +2,11 @@ package com.jozufozu.flywheel.core;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.ShaderContext;
|
||||
import com.jozufozu.flywheel.backend.pipeline.ShaderPipeline;
|
||||
|
@ -87,8 +89,9 @@ public class WorldContext<P extends WorldProgram> implements ShaderContext<P> {
|
|||
if (specStream == null) {
|
||||
specStream = () -> backend.allMaterials()
|
||||
.stream()
|
||||
.map(type -> type.asInstanced()
|
||||
.getProgramSpec());
|
||||
.map(t -> t instanceof Instanced<?> i ? i : null)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Instanced::getProgramSpec);
|
||||
}
|
||||
return new WorldContext<>(backend, name, specStream, pipeline);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package com.jozufozu.flywheel.core.materials.model;
|
||||
|
||||
import com.jozufozu.flywheel.api.struct.Batched;
|
||||
import com.jozufozu.flywheel.api.struct.BatchingTransformer;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.core.Programs;
|
||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
|
@ -34,11 +34,9 @@ public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BatchingTransformer<ModelData> getTransformer() {
|
||||
return (d, b) -> {
|
||||
b.transform(d.model, d.normal)
|
||||
.color(d.r, d.g, d.b, d.a)
|
||||
.light(d.getPackedLight());
|
||||
};
|
||||
public void transform(ModelData d, ModelTransformer.Params b) {
|
||||
b.transform(d.model, d.normal)
|
||||
.color(d.r, d.g, d.b, d.a)
|
||||
.light(d.getPackedLight());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package com.jozufozu.flywheel.core.materials.oriented;
|
||||
|
||||
import com.jozufozu.flywheel.api.struct.Batched;
|
||||
import com.jozufozu.flywheel.api.struct.BatchingTransformer;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||
import com.jozufozu.flywheel.backend.gl.attrib.VertexFormat;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.core.Programs;
|
||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||
import com.mojang.math.Quaternion;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -35,13 +35,11 @@ public class OrientedType implements Instanced<OrientedData>, Batched<OrientedDa
|
|||
}
|
||||
|
||||
@Override
|
||||
public BatchingTransformer<OrientedData> getTransformer() {
|
||||
return (d, sbb) -> {
|
||||
sbb.light(d.getPackedLight())
|
||||
.color(d.r, d.g, d.b, d.a)
|
||||
.translate(d.posX + d.pivotX, d.posY + d.pivotY, d.posZ + d.pivotZ)
|
||||
.multiply(new Quaternion(d.qX, d.qY, d.qZ, d.qW))
|
||||
.translate(-d.pivotX, -d.pivotY, -d.pivotZ);
|
||||
};
|
||||
public void transform(OrientedData d, ModelTransformer.Params b) {
|
||||
b.light(d.getPackedLight())
|
||||
.color(d.r, d.g, d.b, d.a)
|
||||
.translate(d.posX + d.pivotX, d.posY + d.pivotY, d.posZ + d.pivotZ)
|
||||
.multiply(new Quaternion(d.qX, d.qY, d.qZ, d.qW))
|
||||
.translate(-d.pivotX, -d.pivotY, -d.pivotZ);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue