No need for InstancedMaterialRenderer

- Here's to premature abstraction
This commit is contained in:
Jozufozu 2021-12-13 21:27:15 -08:00
parent d9fd668bbb
commit 64a7443dde
4 changed files with 34 additions and 81 deletions

View file

@ -22,12 +22,6 @@ public class BatchedMaterialGroup implements MaterialGroup {
this.state = state;
}
/**
* Get the material as defined by the given {@link StructType type}.
* @param spec The material you want to create instances with.
* @param <D> The type representing the per instance data.
* @return A
*/
@SuppressWarnings("unchecked")
@Override
public <D extends InstanceData> BatchedMaterial<D> material(StructType<D> spec) {

View file

@ -1,12 +1,13 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.jozufozu.flywheel.api.InstanceData;
import com.jozufozu.flywheel.api.MaterialGroup;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.model.ModelPool;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.util.TextureBinder;
import com.mojang.math.Matrix4f;
@ -24,8 +25,6 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
protected final InstancingEngine<P> owner;
protected final RenderType type;
protected final ArrayList<InstancedMaterialRenderer<P>> renderers = new ArrayList<>();
private final Map<StructType<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
public InstancedMaterialGroup(InstancingEngine<P> owner, RenderType type) {
@ -33,27 +32,48 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
this.type = type;
}
/**
* Get the material as defined by the given {@link MaterialSpec spec}.
* @param spec The material you want to create instances with.
* @param <D> The type representing the per instance data.
* @return A
*/
@SuppressWarnings("unchecked")
@Override
public <D extends InstanceData> InstancedMaterial<D> material(StructType<D> spec) {
return (InstancedMaterial<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
return (InstancedMaterial<D>) materials.computeIfAbsent(spec, InstancedMaterial::new);
}
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
type.setupRenderState();
TextureBinder.bindActiveTextures();
for (InstancedMaterialRenderer<P> renderer : renderers) {
renderer.render(viewProjection, camX, camY, camZ);
}
renderAll(viewProjection, camX, camY, camZ);
type.clearRenderState();
}
protected void renderAll(Matrix4f viewProjection, double camX, double camY, double camZ) {
for (Map.Entry<StructType<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
InstancedMaterial<?> material = entry.getValue();
if (material.nothingToRender()) continue;
Collection<? extends GPUInstancer<?>> instancers = material.models.asMap()
.values();
// initialize all uninitialized instancers...
instancers.forEach(GPUInstancer::init);
if (material.allocator instanceof ModelPool pool) {
// ...and then flush the model arena in case anything was marked for upload
pool.flush();
}
P program = owner.getProgram(entry.getKey()
.asInstanced()
.getProgramSpec()).get();
program.bind();
program.uploadViewProjection(viewProjection);
program.uploadCameraPos(camX, camY, camZ);
setup(program);
instancers.forEach(GPUInstancer::render);
}
}
public void setup(P program) {
}
@ -67,15 +87,5 @@ public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialG
.forEach(InstancedMaterial::delete);
materials.clear();
renderers.clear();
}
private InstancedMaterial<?> createInstanceMaterial(StructType<? extends InstanceData> type) {
InstancedMaterial<?> material = new InstancedMaterial<>(type);
this.renderers.add(new InstancedMaterialRenderer<>(owner.getProgram(type.asInstanced()
.getProgramSpec()), material, this::setup));
return material;
}
}

View file

@ -1,48 +0,0 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Supplier;
import com.jozufozu.flywheel.backend.model.ModelPool;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.mojang.math.Matrix4f;
public class InstancedMaterialRenderer<P extends WorldProgram> {
protected final Supplier<P> program;
protected final InstancedMaterial<?> material;
protected final Consumer<P> setupFunc;
public InstancedMaterialRenderer(Supplier<P> programSupplier, InstancedMaterial<?> material, Consumer<P> setupFunc) {
this.program = programSupplier;
this.material = material;
this.setupFunc = setupFunc;
}
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
if (material.nothingToRender()) return;
Collection<? extends GPUInstancer<?>> instancers = material.models.asMap()
.values();
// initialize all uninitialized instancers...
instancers.forEach(GPUInstancer::init);
if (material.allocator instanceof ModelPool pool) {
// ...and then flush the model arena in case anything was marked for upload
pool.flush();
}
P program = this.program.get();
program.bind();
program.uploadViewProjection(viewProjection);
program.uploadCameraPos(camX, camY, camZ);
setupFunc.accept(program);
instancers.forEach(GPUInstancer::render);
}
}

View file

@ -2,7 +2,6 @@ package com.jozufozu.flywheel.core.crumbling;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterialGroup;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterialRenderer;
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
import com.jozufozu.flywheel.core.atlas.SheetData;
import com.jozufozu.flywheel.util.RenderTextures;
@ -39,9 +38,7 @@ public class CrumblingGroup<P extends CrumblingProgram> extends InstancedMateria
RenderSystem.setShaderTexture(4, breakingTex);
TextureBinder.bindActiveTextures();
for (InstancedMaterialRenderer<P> renderer : renderers) {
renderer.render(viewProjection, camX, camY, camZ);
}
renderAll(viewProjection, camX, camY, camZ);
CrumblingRenderer._currentLayer.clearRenderState();
}