mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-13 15:56:07 +01:00
Material refactor pt 2
- Inline all the things - Now MaterialManager -> Material -> Instancer - ModelSuppliers store RenderType - Currently broken, it only renders chunk layers so vanilla instances are invisible
This commit is contained in:
parent
ec92fef445
commit
ccbce86a69
25 changed files with 264 additions and 311 deletions
|
@ -9,6 +9,7 @@ import com.jozufozu.flywheel.config.BackendTypeArgument;
|
|||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.core.Contexts;
|
||||
import com.jozufozu.flywheel.core.Models;
|
||||
import com.jozufozu.flywheel.core.PartialModel;
|
||||
import com.jozufozu.flywheel.core.StitchedSprite;
|
||||
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
||||
|
@ -70,6 +71,7 @@ public class Flywheel {
|
|||
|
||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||
forgeEventBus.<ReloadRenderersEvent>addListener(ProgramCompiler::invalidateAll);
|
||||
forgeEventBus.addListener(Models::onReload);
|
||||
|
||||
modEventBus.addListener(Contexts::flwInit);
|
||||
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
package com.jozufozu.flywheel.api;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.core.Models;
|
||||
import com.jozufozu.flywheel.core.PartialModel;
|
||||
import com.jozufozu.flywheel.core.model.ModelUtil;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
|
||||
public interface Material<D extends InstanceData> {
|
||||
|
||||
|
@ -20,19 +12,4 @@ public interface Material<D extends InstanceData> {
|
|||
*/
|
||||
Instancer<D> model(ModelSupplier modelKey);
|
||||
|
||||
default Instancer<D> getModel(PartialModel partial) {
|
||||
return model(Models.partial(partial));
|
||||
}
|
||||
|
||||
default Instancer<D> getModel(PartialModel partial, Direction dir) {
|
||||
return model(Models.partial(partial, dir, () -> ModelUtil.rotateToFace(dir)));
|
||||
}
|
||||
|
||||
default Instancer<D> getModel(PartialModel partial, Direction dir, Supplier<PoseStack> modelTransform) {
|
||||
return model(Models.partial(partial, dir, modelTransform));
|
||||
}
|
||||
|
||||
default Instancer<D> getModel(BlockState toRender) {
|
||||
return model(Models.block(toRender));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,15 @@
|
|||
package com.jozufozu.flywheel.api;
|
||||
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterial;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
||||
public interface MaterialManager {
|
||||
|
||||
/**
|
||||
* Get a material group that will render in the given layer with the given state.
|
||||
*
|
||||
* @param layer The {@link RenderLayer} you want to draw in.
|
||||
* @param type The {@link RenderType} you need to draw with.
|
||||
* @return A material group whose children will
|
||||
*/
|
||||
MaterialGroup state(RenderLayer layer, RenderType type);
|
||||
<D extends InstanceData> InstancedMaterial<D> material(StructType<D> type);
|
||||
|
||||
Vec3i getOriginCoordinate();
|
||||
|
||||
default MaterialGroup solid(RenderType state) {
|
||||
return state(RenderLayer.SOLID, state);
|
||||
}
|
||||
|
||||
default MaterialGroup cutout(RenderType state) {
|
||||
return state(RenderLayer.CUTOUT, state);
|
||||
}
|
||||
|
||||
default MaterialGroup transparent(RenderType state) {
|
||||
return state(RenderLayer.TRANSPARENT, state);
|
||||
}
|
||||
|
||||
default MaterialGroup defaultSolid() {
|
||||
return solid(RenderType.solid());
|
||||
}
|
||||
|
||||
default MaterialGroup defaultCutout() {
|
||||
return cutout(RenderType.cutout());
|
||||
}
|
||||
|
||||
default MaterialGroup defaultTransparent() {
|
||||
return transparent(RenderType.translucent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
package com.jozufozu.flywheel.api;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
|
||||
public interface ModelSupplier {
|
||||
|
||||
@Nonnull
|
||||
Model get();
|
||||
}
|
|
@ -6,17 +6,17 @@ import java.util.function.Supplier;
|
|||
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.Instancer;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
|
||||
public abstract class AbstractInstancer<D extends InstanceData> implements Instancer<D> {
|
||||
|
||||
protected final Supplier<D> factory;
|
||||
protected final Model modelData;
|
||||
protected final ModelSupplier modelData;
|
||||
protected final ArrayList<D> data = new ArrayList<>();
|
||||
|
||||
protected boolean anyToRemove;
|
||||
|
||||
protected AbstractInstancer(Supplier<D> factory, Model modelData) {
|
||||
protected AbstractInstancer(Supplier<D> factory, ModelSupplier modelData) {
|
||||
this.factory = factory;
|
||||
this.modelData = modelData;
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ public abstract class AbstractInstancer<D extends InstanceData> implements Insta
|
|||
}
|
||||
|
||||
public int getModelVertexCount() {
|
||||
return modelData.vertexCount();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getInstanceCount() {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package com.jozufozu.flywheel.backend.instancing;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Renderable {
|
||||
void draw();
|
||||
}
|
|
@ -2,14 +2,12 @@ package com.jozufozu.flywheel.backend.instancing.batching;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
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.ModelSupplier;
|
||||
import com.jozufozu.flywheel.api.struct.Batched;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
|
@ -26,7 +24,7 @@ public class BatchedMaterial<D extends InstanceData> implements Material<D> {
|
|||
|
||||
@Override
|
||||
public Instancer<D> model(ModelSupplier modelKey) {
|
||||
return models.computeIfAbsent(modelKey, k -> new CPUInstancer<>(type, k.get()));
|
||||
return models.computeIfAbsent(modelKey, k -> new CPUInstancer<>(type, k));
|
||||
}
|
||||
|
||||
public void setupAndRenderInto(PoseStack stack, VertexConsumer buffer) {
|
||||
|
|
|
@ -5,11 +5,13 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialGroup;
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.RenderLayer;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker;
|
||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterial;
|
||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
import com.mojang.blaze3d.platform.Lighting;
|
||||
|
@ -33,8 +35,8 @@ public class BatchingEngine implements Engine {
|
|||
}
|
||||
|
||||
@Override
|
||||
public MaterialGroup state(RenderLayer layer, RenderType type) {
|
||||
return layers.get(layer).computeIfAbsent(type, BatchedMaterialGroup::new);
|
||||
public <D extends InstanceData> InstancedMaterial<D> material(StructType<D> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,7 +5,7 @@ import com.jozufozu.flywheel.api.struct.Batched;
|
|||
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
|
||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||
import com.jozufozu.flywheel.backend.model.DirectVertexConsumer;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
@ -16,11 +16,11 @@ public class CPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
|
||||
final ModelTransformer sbb;
|
||||
|
||||
public CPUInstancer(Batched<D> type, Model modelData) {
|
||||
public CPUInstancer(Batched<D> type, ModelSupplier modelData) {
|
||||
super(type::create, modelData);
|
||||
batchingType = type;
|
||||
|
||||
sbb = new ModelTransformer(modelData);
|
||||
sbb = new ModelTransformer(modelData.get());
|
||||
}
|
||||
|
||||
void submitTasks(PoseStack stack, TaskEngine pool, DirectVertexConsumer consumer) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.blockentity;
|
|||
|
||||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.RenderLayer;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
|
@ -11,6 +12,7 @@ import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
|||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -77,11 +79,11 @@ public abstract class BlockEntityInstance<T extends BlockEntity> extends Abstrac
|
|||
}
|
||||
|
||||
protected Material<ModelData> getTransformMaterial() {
|
||||
return materialManager.defaultCutout().material(Materials.TRANSFORMED);
|
||||
return materialManager.material(Materials.TRANSFORMED);
|
||||
}
|
||||
|
||||
protected Material<OrientedData> getOrientedMaterial() {
|
||||
return materialManager.defaultCutout().material(Materials.ORIENTED);
|
||||
return materialManager.material(Materials.ORIENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.instancing;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
|
@ -12,10 +15,13 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
|||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
|
||||
import com.jozufozu.flywheel.backend.instancing.Renderable;
|
||||
import com.jozufozu.flywheel.backend.model.BufferedModel;
|
||||
import com.jozufozu.flywheel.backend.model.ModelAllocator;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
||||
|
||||
|
@ -31,7 +37,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
|
||||
protected boolean anyToUpdate;
|
||||
|
||||
public GPUInstancer(Instanced<D> type, Model model) {
|
||||
public GPUInstancer(Instanced<D> type, ModelSupplier model) {
|
||||
super(type::create, model);
|
||||
this.instanceFormat = type.getLayout();
|
||||
instancedType = type;
|
||||
|
@ -61,14 +67,17 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
return deleted || model == null;
|
||||
}
|
||||
|
||||
public void init(ModelAllocator modelAllocator) {
|
||||
if (isInitialized()) return;
|
||||
public Map<RenderType, Renderable> init(ModelAllocator modelAllocator) {
|
||||
if (isInitialized()) return ImmutableMap.of();
|
||||
|
||||
initialized = true;
|
||||
|
||||
instanceVBO = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER);
|
||||
instanceVBO.setGrowthMargin(instanceFormat.getStride() * 16);
|
||||
|
||||
vao = new GlVertexArray();
|
||||
|
||||
model = modelAllocator.alloc(modelData, arenaModel -> {
|
||||
model = modelAllocator.alloc(modelData.get(), arenaModel -> {
|
||||
vao.bind();
|
||||
|
||||
arenaModel.setupState(vao);
|
||||
|
@ -77,8 +86,7 @@ public class GPUInstancer<D extends InstanceData> extends AbstractInstancer<D> {
|
|||
vao.bind();
|
||||
vao.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount());
|
||||
|
||||
instanceVBO = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER);
|
||||
instanceVBO.setGrowthMargin(instanceFormat.getStride() * 16);
|
||||
return ImmutableMap.of(modelData.getRenderType(), this::render);
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
|
|
|
@ -5,14 +5,18 @@ import java.util.Collection;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.Instancer;
|
||||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.ModelSupplier;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
import com.jozufozu.flywheel.backend.instancing.Renderable;
|
||||
import com.jozufozu.flywheel.backend.model.ModelAllocator;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
/**
|
||||
* A collection of Instancers that all have the same format.
|
||||
|
@ -22,16 +26,24 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
|||
|
||||
protected final Map<ModelSupplier, GPUInstancer<D>> models = new HashMap<>();
|
||||
protected final Instanced<D> type;
|
||||
|
||||
public final Map<RenderType, List<Renderable>> renderables = new HashMap<>();
|
||||
|
||||
protected final List<GPUInstancer<D>> uninitialized = new ArrayList<>();
|
||||
|
||||
public InstancedMaterial(Instanced<D> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<Renderable> getRenderables(RenderType type) {
|
||||
return renderables.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instancer<D> model(ModelSupplier modelKey) {
|
||||
return models.computeIfAbsent(modelKey, k -> {
|
||||
GPUInstancer<D> instancer = new GPUInstancer<>(type, k.get());
|
||||
GPUInstancer<D> instancer = new GPUInstancer<>(type, modelKey);
|
||||
uninitialized.add(instancer);
|
||||
return instancer;
|
||||
});
|
||||
|
@ -67,4 +79,18 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
|||
public Collection<GPUInstancer<D>> getAllInstancers() {
|
||||
return models.values();
|
||||
}
|
||||
|
||||
void init(ModelAllocator allocator) {
|
||||
for (GPUInstancer<?> instancer : uninitialized) {
|
||||
|
||||
instancer.init(allocator)
|
||||
.forEach(this::addRenderable);
|
||||
}
|
||||
uninitialized.clear();
|
||||
}
|
||||
|
||||
private void addRenderable(RenderType type, Renderable renderable) {
|
||||
this.renderables.computeIfAbsent(type, k -> new ArrayList<>())
|
||||
.add(renderable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,127 +26,24 @@ import net.minecraft.client.renderer.RenderType;
|
|||
* The children of a material group will all be rendered at the same time.
|
||||
* No guarantees are made about the order of draw calls.
|
||||
*/
|
||||
public class InstancedMaterialGroup<P extends WorldProgram> implements MaterialGroup {
|
||||
public class InstancedMaterialGroup<P extends WorldProgram> {
|
||||
|
||||
protected final InstancingEngine<P> owner;
|
||||
protected final RenderType type;
|
||||
|
||||
private final Map<Instanced<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
|
||||
|
||||
private ModelAllocator allocator;
|
||||
private int vertexCount;
|
||||
private int instanceCount;
|
||||
|
||||
public InstancedMaterialGroup(InstancingEngine<P> owner, RenderType type) {
|
||||
this.owner = owner;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of instances drawn last frame.
|
||||
* @return The instance count.
|
||||
*/
|
||||
public int getInstanceCount() {
|
||||
return instanceCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of vertices drawn last frame.
|
||||
* @return The vertex count.
|
||||
*/
|
||||
public int getVertexCount() {
|
||||
return vertexCount;
|
||||
}
|
||||
|
||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ, RenderLayer layer) {
|
||||
type.setupRenderState();
|
||||
Textures.bindActiveTextures();
|
||||
renderAll(viewProjection, camX, camY, camZ, layer);
|
||||
//renderAll(viewProjection, camX, camY, camZ, layer);
|
||||
type.clearRenderState();
|
||||
}
|
||||
|
||||
protected void renderAll(Matrix4f viewProjection, double camX, double camY, double camZ, RenderLayer layer) {
|
||||
initializeInstancers();
|
||||
|
||||
vertexCount = 0;
|
||||
instanceCount = 0;
|
||||
|
||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||
InstancedMaterial<?> material = entry.getValue();
|
||||
if (material.nothingToRender()) continue;
|
||||
|
||||
P program = owner.context.getProgram(ProgramContext.create(entry.getKey()
|
||||
.getProgramSpec(), Formats.POS_TEX_NORMAL, layer));
|
||||
|
||||
program.bind();
|
||||
program.uploadViewProjection(viewProjection);
|
||||
program.uploadCameraPos(camX, camY, camZ);
|
||||
|
||||
setup(program);
|
||||
|
||||
for (GPUInstancer<?> instancer : material.getAllInstancers()) {
|
||||
instancer.render();
|
||||
vertexCount += instancer.getVertexCount();
|
||||
instanceCount += instancer.getInstanceCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
materials.values().forEach(InstancedMaterial::clear);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
materials.values()
|
||||
.forEach(InstancedMaterial::delete);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.instancing;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialGroup;
|
||||
import com.jozufozu.flywheel.api.RenderLayer;
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||
import com.jozufozu.flywheel.backend.instancing.Renderable;
|
||||
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
|
||||
import com.jozufozu.flywheel.backend.model.FallbackAllocator;
|
||||
import com.jozufozu.flywheel.backend.model.ModelAllocator;
|
||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
||||
import com.jozufozu.flywheel.core.compile.ProgramContext;
|
||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||
import com.jozufozu.flywheel.util.FlwUtil;
|
||||
import com.jozufozu.flywheel.util.Textures;
|
||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||
import com.mojang.math.Matrix4f;
|
||||
|
||||
|
@ -34,10 +40,13 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
protected final ProgramCompiler<P> context;
|
||||
protected final GroupFactory<P> groupFactory;
|
||||
protected final boolean ignoreOriginCoordinate;
|
||||
private ModelAllocator allocator;
|
||||
|
||||
protected final Map<RenderLayer, Map<RenderType, InstancedMaterialGroup<P>>> layers;
|
||||
private final Map<Instanced<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
|
||||
|
||||
private final WeakHashSet<OriginShiftListener> listeners;
|
||||
private int vertexCount;
|
||||
private int instanceCount;
|
||||
|
||||
public static <P extends WorldProgram> Builder<P> builder(ProgramCompiler<P> context) {
|
||||
return new Builder<>(context);
|
||||
|
@ -49,30 +58,24 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
|
||||
this.listeners = new WeakHashSet<>();
|
||||
this.groupFactory = groupFactory;
|
||||
}
|
||||
|
||||
this.layers = new EnumMap<>(RenderLayer.class);
|
||||
for (RenderLayer value : RenderLayer.values()) {
|
||||
layers.put(value, new HashMap<>());
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nonnull
|
||||
@Override
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a material group that will render in the given layer with the given type.
|
||||
*
|
||||
* @param layer
|
||||
* @param type The {@link RenderType} you need to draw with.
|
||||
* @return A material group whose children will
|
||||
*/
|
||||
@Override
|
||||
public MaterialGroup state(RenderLayer layer, RenderType type) {
|
||||
return layers.get(layer).computeIfAbsent(type, t -> groupFactory.create(this, t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render every model for every material.
|
||||
*/
|
||||
@Override
|
||||
public void render(TaskEngine taskEngine, RenderLayerEvent event) {
|
||||
|
||||
RenderType type = event.getType();
|
||||
|
||||
double camX;
|
||||
double camY;
|
||||
double camZ;
|
||||
|
@ -91,28 +94,46 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
viewProjection = event.viewProjection;
|
||||
}
|
||||
|
||||
getGroupsToRender(event.getLayer()).forEach(group -> group.render(viewProjection, camX, camY, camZ, event.getLayer()));
|
||||
vertexCount = 0;
|
||||
instanceCount = 0;
|
||||
|
||||
type.setupRenderState();
|
||||
Textures.bindActiveTextures();
|
||||
|
||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||
List<Renderable> renderables = entry.getValue()
|
||||
.getRenderables(type);
|
||||
|
||||
if (renderables == null || renderables.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
P program = context.getProgram(ProgramContext.create(entry.getKey()
|
||||
.getProgramSpec(), Formats.POS_TEX_NORMAL, event.layer));
|
||||
|
||||
program.bind();
|
||||
program.uploadViewProjection(viewProjection);
|
||||
program.uploadCameraPos(camX, camY, camZ);
|
||||
|
||||
//setup(program);
|
||||
for (Renderable renderable : renderables) {
|
||||
renderable.draw();
|
||||
}
|
||||
}
|
||||
|
||||
type.clearRenderState();
|
||||
}
|
||||
|
||||
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()
|
||||
.stream();
|
||||
} else {
|
||||
return layers.values()
|
||||
.stream()
|
||||
.flatMap(FlwUtil::mapValues);
|
||||
}
|
||||
public void clearAll() {
|
||||
materials.values().forEach(InstancedMaterial::clear);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
for (Map<RenderType, InstancedMaterialGroup<P>> groups : layers.values()) {
|
||||
materials.values()
|
||||
.forEach(InstancedMaterial::delete);
|
||||
|
||||
groups.values().forEach(InstancedMaterialGroup::delete);
|
||||
}
|
||||
materials.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -143,22 +164,48 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
|
||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||
|
||||
for (Map<RenderType, InstancedMaterialGroup<P>> groups : layers.values()) {
|
||||
groups.values().forEach(InstancedMaterialGroup::clear);
|
||||
}
|
||||
materials.values().forEach(InstancedMaterial::clear);
|
||||
|
||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||
}
|
||||
|
||||
ModelAllocator allocator = getModelAllocator();
|
||||
|
||||
for (InstancedMaterial<?> material : materials.values()) {
|
||||
material.init(allocator);
|
||||
}
|
||||
|
||||
if (allocator instanceof ModelPool pool) {
|
||||
// ...and then flush the model arena in case anything was marked for upload
|
||||
pool.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDebugInfo(List<String> info) {
|
||||
info.add("GL33 Instanced Arrays");
|
||||
info.add("Instances: " + getGroupsToRender(null).mapToInt(InstancedMaterialGroup::getInstanceCount).sum());
|
||||
info.add("Vertices: " + getGroupsToRender(null).mapToInt(InstancedMaterialGroup::getVertexCount).sum());
|
||||
info.add("Instances: " + instanceCount);
|
||||
info.add("Vertices: " + vertexCount);
|
||||
info.add("Origin: " + originCoordinate.getX() + ", " + originCoordinate.getY() + ", " + originCoordinate.getZ());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface OriginShiftListener {
|
||||
void onOriginShift();
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL32;
|
||||
import org.lwjgl.opengl.GL43;
|
||||
|
||||
import com.jozufozu.flywheel.Flywheel;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
|
|
44
src/main/java/com/jozufozu/flywheel/core/ModelSupplier.java
Normal file
44
src/main/java/com/jozufozu/flywheel/core/ModelSupplier.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package com.jozufozu.flywheel.core;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
import com.jozufozu.flywheel.util.Lazy;
|
||||
import com.jozufozu.flywheel.util.NonNullSupplier;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class ModelSupplier {
|
||||
|
||||
private final Lazy<Model> supplier;
|
||||
|
||||
private RenderType renderType;
|
||||
|
||||
public ModelSupplier(NonNullSupplier<Model> supplier) {
|
||||
this(supplier, RenderType.solid());
|
||||
}
|
||||
|
||||
public ModelSupplier(NonNullSupplier<Model> supplier, RenderType renderType) {
|
||||
this.supplier = Lazy.of(supplier);
|
||||
this.renderType = renderType;
|
||||
}
|
||||
|
||||
public ModelSupplier setCutout() {
|
||||
return setRenderType(RenderType.cutoutMipped());
|
||||
}
|
||||
|
||||
public ModelSupplier setRenderType(@Nonnull RenderType renderType) {
|
||||
this.renderType = renderType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Model get() {
|
||||
return supplier.get();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public RenderType getRenderType() {
|
||||
return renderType;
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ package com.jozufozu.flywheel.core;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.api.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.model.BlockModel;
|
||||
import com.jozufozu.flywheel.core.model.ModelUtil;
|
||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.util.Pair;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
|
@ -19,19 +19,29 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
public class Models {
|
||||
|
||||
public static ModelSupplier block(BlockState state) {
|
||||
return BLOCK_STATE.apply(state);
|
||||
return BLOCK_STATE.computeIfAbsent(state, it -> new ModelSupplier(() -> new BlockModel(it)));
|
||||
}
|
||||
|
||||
public static ModelSupplier partial(PartialModel partial) {
|
||||
return PARTIAL.apply(partial);
|
||||
return PARTIAL.computeIfAbsent(partial, it -> new ModelSupplier(() -> new BlockModel(it.get(), Blocks.AIR.defaultBlockState())));
|
||||
}
|
||||
|
||||
public static ModelSupplier partial(PartialModel partial, Direction dir) {
|
||||
return partial(partial, dir, () -> ModelUtil.rotateToFace(dir));
|
||||
}
|
||||
|
||||
public static ModelSupplier partial(PartialModel partial, Direction dir, Supplier<PoseStack> modelTransform) {
|
||||
return PARTIAL_DIR.computeIfAbsent(Pair.of(dir, partial), $ -> new SimpleModelSupplier(() -> new BlockModel(partial.get(), Blocks.AIR.defaultBlockState(), modelTransform.get())));
|
||||
return PARTIAL_DIR.computeIfAbsent(Pair.of(dir, partial), $ -> new ModelSupplier(() -> new BlockModel(partial.get(), Blocks.AIR.defaultBlockState(), modelTransform.get())));
|
||||
}
|
||||
|
||||
private static final Function<BlockState, ModelSupplier> BLOCK_STATE = Util.memoize(it -> new SimpleModelSupplier(() -> new BlockModel(it)));
|
||||
private static final Function<PartialModel, ModelSupplier> PARTIAL = Util.memoize(it -> new SimpleModelSupplier(() -> new BlockModel(it.get(), Blocks.AIR.defaultBlockState())));
|
||||
public static void onReload(ReloadRenderersEvent ignored) {
|
||||
BLOCK_STATE.clear();
|
||||
PARTIAL.clear();
|
||||
PARTIAL_DIR.clear();
|
||||
}
|
||||
|
||||
private static final Map<BlockState, ModelSupplier> BLOCK_STATE = new HashMap<>();
|
||||
private static final Map<PartialModel, ModelSupplier> PARTIAL = new HashMap<>();
|
||||
private static final Map<Pair<Direction, PartialModel>, ModelSupplier> PARTIAL_DIR = new HashMap<>();
|
||||
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
package com.jozufozu.flywheel.core;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.jozufozu.flywheel.api.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
import com.jozufozu.flywheel.util.Lazy;
|
||||
import com.jozufozu.flywheel.util.NonNullSupplier;
|
||||
|
||||
public class SimpleModelSupplier implements ModelSupplier {
|
||||
|
||||
private final Lazy<Model> supplier;
|
||||
|
||||
public SimpleModelSupplier(NonNullSupplier<Model> supplier) {
|
||||
this.supplier = Lazy.of(supplier);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Model get() {
|
||||
return supplier.get();
|
||||
}
|
||||
}
|
|
@ -75,7 +75,7 @@ public class ProgramCompiler<P extends GlProgram> extends Memoizer<ProgramContex
|
|||
value.delete();
|
||||
}
|
||||
|
||||
public static void invalidateAll(ReloadRenderersEvent event) {
|
||||
public static void invalidateAll(ReloadRenderersEvent ignored) {
|
||||
ALL_COMPILERS.forEach(ProgramCompiler::invalidate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ public class CrumblingGroup<P extends CrumblingProgram> extends InstancedMateria
|
|||
RenderSystem.setShaderTexture(4, breakingTex);
|
||||
|
||||
Textures.bindActiveTextures();
|
||||
renderAll(viewProjection, camX, camY, camZ, layer);
|
||||
//renderAll(viewProjection, camX, camY, camZ, layer);
|
||||
|
||||
CrumblingRenderer._currentLayer.clearRenderState();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.jozufozu.flywheel.util;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -24,6 +25,10 @@ public class Lazy<T> implements Supplier<T> {
|
|||
return value;
|
||||
}
|
||||
|
||||
public <Q> Lazy<Q> map(Function<T, Q> func) {
|
||||
return new Lazy<>(() -> func.apply(get()));
|
||||
}
|
||||
|
||||
public static <T> Lazy<T> of(NonNullSupplier<T> factory) {
|
||||
return new Lazy<>(factory);
|
||||
}
|
||||
|
|
|
@ -3,24 +3,24 @@ package com.jozufozu.flywheel.vanilla;
|
|||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.ModelSupplier;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.SimpleModelSupplier;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||
import com.mojang.math.Quaternion;
|
||||
import com.mojang.math.Vector3f;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.blockentity.BellRenderer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.entity.BellBlockEntity;
|
||||
|
||||
public class BellInstance extends BlockEntityInstance<BellBlockEntity> implements DynamicInstance {
|
||||
|
||||
private static final ModelSupplier MODEL = new SimpleModelSupplier(BellInstance::createBellModel);
|
||||
private static final ModelSupplier MODEL = new ModelSupplier(BellInstance::createBellModel, RenderType.cutoutMipped());
|
||||
|
||||
private final OrientedData bell;
|
||||
|
||||
|
@ -63,8 +63,7 @@ public class BellInstance extends BlockEntityInstance<BellBlockEntity> implement
|
|||
}
|
||||
|
||||
private OrientedData createBellInstance() {
|
||||
return materialManager.defaultCutout()
|
||||
.material(Materials.ORIENTED)
|
||||
return materialManager.material(Materials.ORIENTED)
|
||||
.model(MODEL)
|
||||
.createInstance();
|
||||
}
|
||||
|
|
|
@ -6,11 +6,10 @@ import java.util.function.BiFunction;
|
|||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.ModelSupplier;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.SimpleModelSupplier;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||
|
@ -35,8 +34,8 @@ import net.minecraft.world.level.block.state.properties.ChestType;
|
|||
|
||||
public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends BlockEntityInstance<T> implements DynamicInstance {
|
||||
|
||||
private static final BiFunction<ChestType, TextureAtlasSprite, ModelSupplier> LID = Util.memoize((type, sprite) -> new SimpleModelSupplier(() -> createLidModel(type, sprite)));
|
||||
private static final BiFunction<ChestType, TextureAtlasSprite, ModelSupplier> BASE = Util.memoize((type, sprite) -> new SimpleModelSupplier(() -> createBaseModel(type, sprite)));
|
||||
private static final BiFunction<ChestType, Material, ModelSupplier> LID = Util.memoize((type, mat) -> new ModelSupplier(() -> createLidModel(type, mat.sprite()), RenderType.entitySolid(mat.atlasLocation())));
|
||||
private static final BiFunction<ChestType, Material, ModelSupplier> BASE = Util.memoize((type, mat) -> new ModelSupplier(() -> createBaseModel(type, mat.sprite()), RenderType.entitySolid(mat.atlasLocation())));
|
||||
|
||||
private final OrientedData body;
|
||||
private final ModelData lid;
|
||||
|
@ -117,17 +116,15 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
|||
|
||||
private OrientedData baseInstance() {
|
||||
|
||||
return materialManager.solid(RenderType.entitySolid(renderMaterial.atlasLocation()))
|
||||
.material(Materials.ORIENTED)
|
||||
.model(BASE.apply(chestType, renderMaterial.sprite()))
|
||||
return materialManager.material(Materials.ORIENTED)
|
||||
.model(BASE.apply(chestType, renderMaterial))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private ModelData lidInstance() {
|
||||
|
||||
return materialManager.solid(RenderType.entitySolid(renderMaterial.atlasLocation()))
|
||||
.material(Materials.TRANSFORMED)
|
||||
.model(LID.apply(chestType, renderMaterial.sprite()))
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
.model(LID.apply(chestType, renderMaterial))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,14 @@ package com.jozufozu.flywheel.vanilla;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.ModelSupplier;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.SimpleModelSupplier;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.Models;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.model.Model;
|
||||
|
@ -29,7 +30,7 @@ import net.minecraft.world.phys.Vec3;
|
|||
public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance<T> implements DynamicInstance, TickableInstance {
|
||||
|
||||
private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png");
|
||||
private static final ModelSupplier MODEL = new SimpleModelSupplier(MinecartInstance::getBodyModel);
|
||||
private static final ModelSupplier MODEL = new ModelSupplier(MinecartInstance::getBodyModel, RenderType.entitySolid(MINECART_LOCATION));
|
||||
|
||||
private final PoseStack stack = new PoseStack();
|
||||
|
||||
|
@ -147,15 +148,13 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
|
|||
if (blockstate.getRenderShape() == RenderShape.INVISIBLE)
|
||||
return null;
|
||||
|
||||
return materialManager.defaultSolid()
|
||||
.material(Materials.TRANSFORMED)
|
||||
.getModel(blockstate)
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
.model(Models.block(blockstate))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private ModelData getBody() {
|
||||
return materialManager.solid(RenderType.entitySolid(MINECART_LOCATION))
|
||||
.material(Materials.TRANSFORMED)
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
.model(MODEL)
|
||||
.createInstance();
|
||||
}
|
||||
|
|
|
@ -3,11 +3,10 @@ package com.jozufozu.flywheel.vanilla;
|
|||
import java.util.function.Function;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.ModelSupplier;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
import com.jozufozu.flywheel.core.SimpleModelSupplier;
|
||||
import com.jozufozu.flywheel.core.ModelSupplier;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||
|
@ -27,8 +26,8 @@ import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
|||
|
||||
public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntity> implements DynamicInstance {
|
||||
|
||||
private static final Function<TextureAtlasSprite, ModelSupplier> BASE = Util.memoize(it -> new SimpleModelSupplier(() -> makeBaseModel(it)));
|
||||
private static final Function<TextureAtlasSprite, ModelSupplier> LID = Util.memoize(it -> new SimpleModelSupplier(() -> makeLidModel(it)));
|
||||
private static final Function<TextureAtlasSprite, ModelSupplier> BASE = Util.memoize(it -> new ModelSupplier(() -> makeBaseModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET)));
|
||||
private static final Function<TextureAtlasSprite, ModelSupplier> LID = Util.memoize(it -> new ModelSupplier(() -> makeLidModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET)));
|
||||
|
||||
private final TextureAtlasSprite texture;
|
||||
|
||||
|
@ -74,9 +73,8 @@ public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntit
|
|||
|
||||
Quaternion spin = Vector3f.YP.rotationDegrees(270.0F * progress);
|
||||
|
||||
TransformStack tstack = TransformStack.cast(stack);
|
||||
|
||||
tstack.pushPose()
|
||||
TransformStack.cast(stack)
|
||||
.pushPose()
|
||||
.centre()
|
||||
.multiply(spin)
|
||||
.unCentre()
|
||||
|
@ -99,15 +97,13 @@ public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntit
|
|||
}
|
||||
|
||||
private ModelData makeBaseInstance() {
|
||||
return materialManager.cutout(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET))
|
||||
.material(Materials.TRANSFORMED)
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
.model(BASE.apply(texture))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private ModelData makeLidInstance() {
|
||||
return materialManager.cutout(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET))
|
||||
.material(Materials.TRANSFORMED)
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
.model(LID.apply(texture))
|
||||
.createInstance();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue