mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-16 16:10:58 +01:00
Interfaces and less log lines
- MateralManager, MaterialGroup, and InstanceMaterial are all interfaces - Separate (T)EI facing API from implementation - Comment out debug log in ModelPool
This commit is contained in:
parent
2137f9e46d
commit
7cb81256a1
28 changed files with 450 additions and 400 deletions
|
@ -17,15 +17,15 @@ public abstract class GlObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void checkHandle() {
|
protected final void checkHandle() {
|
||||||
if (!this.isHandleValid()) {
|
if (this.isInvalid()) {
|
||||||
String descriptor = getDescriptor();
|
String descriptor = getDescriptor();
|
||||||
String message = (descriptor == null ? "" : (descriptor + " ")) + "handle is not valid.";
|
String message = (descriptor == null ? "" : (descriptor + " ")) + "handle is not valid.";
|
||||||
throw new IllegalStateException(message);
|
throw new IllegalStateException(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final boolean isHandleValid() {
|
protected final boolean isInvalid() {
|
||||||
return this.handle != INVALID_HANDLE;
|
return this.handle == INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final void invalidateHandle() {
|
protected final void invalidateHandle() {
|
||||||
|
@ -33,7 +33,7 @@ public abstract class GlObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
if (!isHandleValid()) {
|
if (isInvalid()) {
|
||||||
String descriptor = getDescriptor();
|
String descriptor = getDescriptor();
|
||||||
String message = (descriptor == null ? "" : (descriptor + " ")) + "handle already deleted.";
|
String message = (descriptor == null ? "" : (descriptor + " ")) + "handle already deleted.";
|
||||||
throw new IllegalStateException(message);
|
throw new IllegalStateException(message);
|
||||||
|
|
|
@ -1,33 +1,26 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing;
|
package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet;
|
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.vector.Vector3f;
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
|
||||||
public abstract class InstanceManager<T> implements MaterialManager.OriginShiftListener {
|
public abstract class InstanceManager<T> implements MaterialManagerImpl.OriginShiftListener {
|
||||||
|
|
||||||
public final MaterialManager<?> materialManager;
|
public final MaterialManager materialManager;
|
||||||
|
|
||||||
private final Set<T> queuedAdditions;
|
private final Set<T> queuedAdditions;
|
||||||
private final Set<T> queuedUpdates;
|
private final Set<T> queuedUpdates;
|
||||||
|
@ -39,7 +32,7 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
||||||
protected int frame;
|
protected int frame;
|
||||||
protected int tick;
|
protected int tick;
|
||||||
|
|
||||||
public InstanceManager(MaterialManager<?> materialManager) {
|
public InstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||||
this.materialManager = materialManager;
|
this.materialManager = materialManager;
|
||||||
this.queuedUpdates = new HashSet<>(64);
|
this.queuedUpdates = new HashSet<>(64);
|
||||||
this.queuedAdditions = new HashSet<>(64);
|
this.queuedAdditions = new HashSet<>(64);
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.backend.instancing;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
|
@ -13,8 +13,6 @@ import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.world.IWorld;
|
|
||||||
import net.minecraftforge.event.TickEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A manager class for a single world where instancing is supported.
|
* A manager class for a single world where instancing is supported.
|
||||||
|
@ -23,19 +21,19 @@ import net.minecraftforge.event.TickEvent;
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class InstanceWorld {
|
public class InstanceWorld {
|
||||||
protected final MaterialManager<WorldProgram> materialManager;
|
protected final MaterialManagerImpl<WorldProgram> materialManager;
|
||||||
protected final InstanceManager<Entity> entityInstanceManager;
|
protected final InstanceManager<Entity> entityInstanceManager;
|
||||||
protected final InstanceManager<TileEntity> tileEntityInstanceManager;
|
protected final InstanceManager<TileEntity> tileEntityInstanceManager;
|
||||||
|
|
||||||
public InstanceWorld() {
|
public InstanceWorld() {
|
||||||
|
|
||||||
materialManager = MaterialManager.builder(Contexts.WORLD)
|
materialManager = MaterialManagerImpl.builder(Contexts.WORLD)
|
||||||
.build();
|
.build();
|
||||||
entityInstanceManager = new EntityInstanceManager(materialManager);
|
entityInstanceManager = new EntityInstanceManager(materialManager);
|
||||||
tileEntityInstanceManager = new TileInstanceManager(materialManager);
|
tileEntityInstanceManager = new TileInstanceManager(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialManager<WorldProgram> getMaterialManager() {
|
public MaterialManager getMaterialManager() {
|
||||||
return materialManager;
|
return materialManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +70,7 @@ public class InstanceWorld {
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void beginFrame(BeginFrameEvent event) {
|
public void beginFrame(BeginFrameEvent event) {
|
||||||
materialManager.checkAndShiftOrigin(event.getInfo());
|
materialManager.beginFrame(event.getInfo());
|
||||||
|
|
||||||
tileEntityInstanceManager.beginFrame(event.getInfo());
|
tileEntityInstanceManager.beginFrame(event.getInfo());
|
||||||
entityInstanceManager.beginFrame(event.getInfo());
|
entityInstanceManager.beginFrame(event.getInfo());
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class InstancedRenderRegistry {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends TileEntity> TileEntityInstance<? super T> create(MaterialManager<?> manager, T tile) {
|
public <T extends TileEntity> TileEntityInstance<? super T> create(MaterialManager manager, T tile) {
|
||||||
TileEntityType<?> type = tile.getType();
|
TileEntityType<?> type = tile.getType();
|
||||||
ITileInstanceFactory<? super T> factory = (ITileInstanceFactory<? super T>) this.tiles.get(type);
|
ITileInstanceFactory<? super T> factory = (ITileInstanceFactory<? super T>) this.tiles.get(type);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public class InstancedRenderRegistry {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T extends Entity> EntityInstance<? super T> create(MaterialManager<?> manager, T tile) {
|
public <T extends Entity> EntityInstance<? super T> create(MaterialManager manager, T tile) {
|
||||||
EntityType<?> type = tile.getType();
|
EntityType<?> type = tile.getType();
|
||||||
IEntityInstanceFactory<? super T> factory = (IEntityInstanceFactory<? super T>) this.entities.get(type);
|
IEntityInstanceFactory<? super T> factory = (IEntityInstanceFactory<? super T>) this.entities.get(type);
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
import com.jozufozu.flywheel.backend.material.MaterialSpec;
|
||||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
import com.jozufozu.flywheel.backend.model.ModelAllocator;
|
||||||
import com.jozufozu.flywheel.backend.model.IBufferedModel;
|
import com.jozufozu.flywheel.backend.model.IBufferedModel;
|
||||||
import com.jozufozu.flywheel.core.model.IModel;
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
import com.jozufozu.flywheel.util.AttribUtil;
|
import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
|
@ -35,7 +35,7 @@ import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
*/
|
*/
|
||||||
public class Instancer<D extends InstanceData> {
|
public class Instancer<D extends InstanceData> {
|
||||||
|
|
||||||
private final ModelPool modelAllocator;
|
private final ModelAllocator modelAllocator;
|
||||||
private final IModel modelData;
|
private final IModel modelData;
|
||||||
private final VertexFormat instanceFormat;
|
private final VertexFormat instanceFormat;
|
||||||
private final IInstanceFactory<D> factory;
|
private final IInstanceFactory<D> factory;
|
||||||
|
@ -53,11 +53,11 @@ public class Instancer<D extends InstanceData> {
|
||||||
boolean anyToRemove;
|
boolean anyToRemove;
|
||||||
boolean anyToUpdate;
|
boolean anyToUpdate;
|
||||||
|
|
||||||
public Instancer(ModelPool modelAllocator, IModel model, MaterialSpec<D> spec) {
|
public Instancer(ModelAllocator modelAllocator, IModel model, IInstanceFactory<D> factory, VertexFormat instanceFormat) {
|
||||||
this.modelAllocator = modelAllocator;
|
this.modelAllocator = modelAllocator;
|
||||||
this.modelData = model;
|
this.modelData = model;
|
||||||
this.factory = spec.getInstanceFactory();
|
this.factory = factory;
|
||||||
this.instanceFormat = spec.getInstanceFormat();
|
this.instanceFormat = instanceFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,14 +105,13 @@ public class Instancer<D extends InstanceData> {
|
||||||
|
|
||||||
vao = new GlVertexArray();
|
vao = new GlVertexArray();
|
||||||
|
|
||||||
model = modelAllocator.alloc(modelData)
|
model = modelAllocator.alloc(modelData, arenaModel -> {
|
||||||
.setReallocCallback(arenaModel -> {
|
vao.bind();
|
||||||
vao.bind();
|
|
||||||
|
|
||||||
model.setupState();
|
model.setupState();
|
||||||
|
|
||||||
vao.unbind();
|
vao.unbind();
|
||||||
});
|
});
|
||||||
|
|
||||||
vao.bind();
|
vao.bind();
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,11 @@ import net.minecraft.world.World;
|
||||||
*/
|
*/
|
||||||
public abstract class EntityInstance<E extends Entity> implements IInstance {
|
public abstract class EntityInstance<E extends Entity> implements IInstance {
|
||||||
|
|
||||||
protected final MaterialManager<?> materialManager;
|
protected final MaterialManager materialManager;
|
||||||
protected final E entity;
|
protected final E entity;
|
||||||
protected final World world;
|
protected final World world;
|
||||||
|
|
||||||
public EntityInstance(MaterialManager<?> materialManager, E entity) {
|
public EntityInstance(MaterialManager materialManager, E entity) {
|
||||||
this.materialManager = materialManager;
|
this.materialManager = materialManager;
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.world = entity.level;
|
this.world = entity.level;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public class EntityInstanceManager extends InstanceManager<Entity> {
|
public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||||
|
|
||||||
public EntityInstanceManager(MaterialManager<?> materialManager) {
|
public EntityInstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||||
super(materialManager);
|
super(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,5 +6,5 @@ import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface IEntityInstanceFactory<E extends Entity> {
|
public interface IEntityInstanceFactory<E extends Entity> {
|
||||||
EntityInstance<? super E> create(MaterialManager<?> manager, E te);
|
EntityInstance<? super E> create(MaterialManager manager, E te);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,5 +6,5 @@ import net.minecraft.tileentity.TileEntity;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ITileInstanceFactory<T extends TileEntity> {
|
public interface ITileInstanceFactory<T extends TileEntity> {
|
||||||
TileEntityInstance<? super T> create(MaterialManager<?> manager, T te);
|
TileEntityInstance<? super T> create(MaterialManager manager, T te);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.jozufozu.flywheel.backend.instancing.IInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
import com.jozufozu.flywheel.backend.instancing.ITickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.material.InstanceMaterial;
|
import com.jozufozu.flywheel.backend.material.InstanceMaterial;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
import com.jozufozu.flywheel.core.Materials;
|
||||||
import com.jozufozu.flywheel.core.materials.IFlatLight;
|
import com.jozufozu.flywheel.core.materials.IFlatLight;
|
||||||
import com.jozufozu.flywheel.core.materials.ModelData;
|
import com.jozufozu.flywheel.core.materials.ModelData;
|
||||||
|
@ -38,14 +39,14 @@ import net.minecraft.world.World;
|
||||||
*/
|
*/
|
||||||
public abstract class TileEntityInstance<T extends TileEntity> implements IInstance {
|
public abstract class TileEntityInstance<T extends TileEntity> implements IInstance {
|
||||||
|
|
||||||
protected final MaterialManager<?> materialManager;
|
protected final MaterialManager materialManager;
|
||||||
protected final T tile;
|
protected final T tile;
|
||||||
protected final World world;
|
protected final World world;
|
||||||
protected final BlockPos pos;
|
protected final BlockPos pos;
|
||||||
protected final BlockPos instancePos;
|
protected final BlockPos instancePos;
|
||||||
protected final BlockState blockState;
|
protected final BlockState blockState;
|
||||||
|
|
||||||
public TileEntityInstance(MaterialManager<?> materialManager, T tile) {
|
public TileEntityInstance(MaterialManager materialManager, T tile) {
|
||||||
this.materialManager = materialManager;
|
this.materialManager = materialManager;
|
||||||
this.tile = tile;
|
this.tile = tile;
|
||||||
this.world = tile.getLevel();
|
this.world = tile.getLevel();
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
import com.jozufozu.flywheel.backend.instancing.IInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -13,7 +13,7 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public class TileInstanceManager extends InstanceManager<TileEntity> {
|
public class TileInstanceManager extends InstanceManager<TileEntity> {
|
||||||
|
|
||||||
public TileInstanceManager(MaterialManager<?> materialManager) {
|
public TileInstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||||
super(materialManager);
|
super(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
package com.jozufozu.flywheel.backend.material;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.jozufozu.flywheel.backend.RenderWork;
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||||
import com.jozufozu.flywheel.backend.model.ModelPool;
|
import com.jozufozu.flywheel.core.Formats;
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
import com.jozufozu.flywheel.core.model.BlockModel;
|
import com.jozufozu.flywheel.core.model.BlockModel;
|
||||||
import com.jozufozu.flywheel.core.model.IModel;
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
|
@ -19,78 +15,29 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
|
||||||
/**
|
public interface InstanceMaterial<D extends InstanceData> {
|
||||||
* A collection of Instancers that all have the same format.
|
|
||||||
* @param <D>
|
|
||||||
*/
|
|
||||||
public class InstanceMaterial<D extends InstanceData> {
|
|
||||||
|
|
||||||
final ModelPool modelPool;
|
|
||||||
protected final Cache<Object, Instancer<D>> models;
|
|
||||||
protected final MaterialSpec<D> spec;
|
|
||||||
|
|
||||||
public InstanceMaterial(MaterialSpec<D> spec) {
|
|
||||||
this.spec = spec;
|
|
||||||
|
|
||||||
modelPool = new ModelPool(spec.getModelFormat(), spec.getModelFormat().getStride() * 64);
|
|
||||||
this.models = CacheBuilder.newBuilder()
|
|
||||||
.removalListener(notification -> {
|
|
||||||
Instancer<?> instancer = (Instancer<?>) notification.getValue();
|
|
||||||
RenderWork.enqueue(instancer::delete);
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an instancer for the given model. Calling this method twice with the same key will return the same instancer.
|
* Get an instancer for the given model. Calling this method twice with the same key will return the same instancer.
|
||||||
*
|
*
|
||||||
* @param key An object that uniquely identifies the model.
|
* @param key An object that uniquely identifies the model.
|
||||||
* @param modelSupplier A factory that creates the IModel that you want to render.
|
* @param modelSupplier A factory that creates the IModel that you want to render.
|
||||||
* @return An instancer for the given model, capable of rendering many copies for little cost.
|
* @return An instancer for the given model, capable of rendering many copies for little cost.
|
||||||
*/
|
*/
|
||||||
public Instancer<D> model(Object key, Supplier<IModel> modelSupplier) {
|
Instancer<D> model(Object key, Supplier<IModel> modelSupplier);
|
||||||
try {
|
|
||||||
return models.get(key, () -> new Instancer<>(modelPool, modelSupplier.get(), spec));
|
default Instancer<D> getModel(PartialModel partial, BlockState referenceState) {
|
||||||
} catch (ExecutionException e) {
|
return model(partial, () -> new BlockModel(Formats.UNLIT_MODEL, partial.get(), referenceState));
|
||||||
throw new RuntimeException("error creating instancer", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState) {
|
default Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir) {
|
||||||
return model(partial, () -> new BlockModel(spec.getModelFormat(), partial.get(), referenceState));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir) {
|
|
||||||
return getModel(partial, referenceState, dir, RenderUtil.rotateToFace(dir));
|
return getModel(partial, referenceState, dir, RenderUtil.rotateToFace(dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
default Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
||||||
return model(Pair.of(dir, partial), () -> new BlockModel(spec.getModelFormat(), partial.get(), referenceState, modelTransform.get()));
|
return model(Pair.of(dir, partial), () -> new BlockModel(Formats.UNLIT_MODEL, partial.get(), referenceState, modelTransform.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instancer<D> getModel(BlockState toRender) {
|
default Instancer<D> getModel(BlockState toRender) {
|
||||||
return model(toRender, () -> new BlockModel(spec.getModelFormat(), toRender));
|
return model(toRender, () -> new BlockModel(Formats.UNLIT_MODEL, toRender));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean nothingToRender() {
|
|
||||||
return models.size() > 0 && models.asMap()
|
|
||||||
.values()
|
|
||||||
.stream()
|
|
||||||
.allMatch(Instancer::isEmpty);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
models.invalidateAll();
|
|
||||||
modelPool.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear all instance data without freeing resources.
|
|
||||||
*/
|
|
||||||
public void clear() {
|
|
||||||
models.asMap()
|
|
||||||
.values()
|
|
||||||
.forEach(Instancer::clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.jozufozu.flywheel.backend.RenderWork;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.Instancer;
|
||||||
|
import com.jozufozu.flywheel.backend.model.ModelPool;
|
||||||
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of Instancers that all have the same format.
|
||||||
|
* @param <D>
|
||||||
|
*/
|
||||||
|
public class InstanceMaterialImpl<D extends InstanceData> implements InstanceMaterial<D> {
|
||||||
|
|
||||||
|
final ModelPool modelPool;
|
||||||
|
protected final Cache<Object, Instancer<D>> models;
|
||||||
|
protected final MaterialSpec<D> spec;
|
||||||
|
|
||||||
|
public InstanceMaterialImpl(MaterialSpec<D> spec) {
|
||||||
|
this.spec = spec;
|
||||||
|
|
||||||
|
modelPool = new ModelPool(spec.getModelFormat(), spec.getModelFormat().getStride() * 64);
|
||||||
|
this.models = CacheBuilder.newBuilder()
|
||||||
|
.removalListener(notification -> {
|
||||||
|
Instancer<?> instancer = (Instancer<?>) notification.getValue();
|
||||||
|
RenderWork.enqueue(instancer::delete);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an instancer for the given model. Calling this method twice with the same key will return the same instancer.
|
||||||
|
*
|
||||||
|
* @param key An object that uniquely identifies the model.
|
||||||
|
* @param modelSupplier A factory that creates the IModel that you want to render.
|
||||||
|
* @return An instancer for the given model, capable of rendering many copies for little cost.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Instancer<D> model(Object key, Supplier<IModel> modelSupplier) {
|
||||||
|
try {
|
||||||
|
return models.get(key, () -> new Instancer<>(modelPool, modelSupplier.get(), spec.getInstanceFactory(), spec.getInstanceFormat()));
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw new RuntimeException("error creating instancer", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean nothingToRender() {
|
||||||
|
return models.size() > 0 && models.asMap()
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.allMatch(Instancer::isEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
models.invalidateAll();
|
||||||
|
modelPool.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all instance data without freeing resources.
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
models.asMap()
|
||||||
|
.values()
|
||||||
|
.forEach(Instancer::clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,73 +1,14 @@
|
||||||
package com.jozufozu.flywheel.backend.material;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
|
||||||
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A group of materials all rendered with the same GL state.
|
|
||||||
*
|
|
||||||
* 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 MaterialGroup<P extends WorldProgram> {
|
|
||||||
|
|
||||||
protected final MaterialManager<P> owner;
|
|
||||||
protected final IRenderState state;
|
|
||||||
|
|
||||||
private final ArrayList<MaterialRenderer<P>> renderers = new ArrayList<>();
|
|
||||||
|
|
||||||
private final Map<MaterialSpec<?>, InstanceMaterial<?>> materials = new HashMap<>();
|
|
||||||
|
|
||||||
public MaterialGroup(MaterialManager<P> owner, IRenderState state) {
|
|
||||||
this.owner = owner;
|
|
||||||
this.state = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public interface MaterialGroup {
|
||||||
/**
|
/**
|
||||||
* Get the material as defined by the given {@link MaterialSpec spec}.
|
* Get the material as defined by the given {@link MaterialSpec spec}.
|
||||||
|
*
|
||||||
* @param spec The material you want to create instances with.
|
* @param spec The material you want to create instances with.
|
||||||
* @param <D> The type representing the per instance data.
|
* @param <D> The type representing the per instance data.
|
||||||
* @return A
|
* @return A material you can use to render models.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
<D extends InstanceData> InstanceMaterial<D> material(MaterialSpec<D> spec);
|
||||||
public <D extends InstanceData> InstanceMaterial<D> material(MaterialSpec<D> spec) {
|
|
||||||
return (InstanceMaterial<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
|
||||||
for (MaterialRenderer<P> renderer : renderers) {
|
|
||||||
renderer.render(viewProjection, camX, camY, camZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setup(P program) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
|
||||||
materials.values().forEach(InstanceMaterial::clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
materials.values()
|
|
||||||
.forEach(InstanceMaterial::delete);
|
|
||||||
|
|
||||||
materials.clear();
|
|
||||||
renderers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private InstanceMaterial<?> createInstanceMaterial(MaterialSpec<?> type) {
|
|
||||||
InstanceMaterial<?> material = new InstanceMaterial<>(type);
|
|
||||||
|
|
||||||
this.renderers.add(new MaterialRenderer<>(owner.getProgram(type.getProgramName()), material, this::setup));
|
|
||||||
|
|
||||||
return material;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||||
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A group of materials all rendered with the same GL state.
|
||||||
|
*
|
||||||
|
* 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 MaterialGroupImpl<P extends WorldProgram> implements MaterialGroup {
|
||||||
|
|
||||||
|
protected final MaterialManagerImpl<P> owner;
|
||||||
|
protected final IRenderState state;
|
||||||
|
|
||||||
|
private final ArrayList<MaterialRenderer<P>> renderers = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Map<MaterialSpec<?>, InstanceMaterialImpl<?>> materials = new HashMap<>();
|
||||||
|
|
||||||
|
public MaterialGroupImpl(MaterialManagerImpl<P> owner, IRenderState state) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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> InstanceMaterialImpl<D> material(MaterialSpec<D> spec) {
|
||||||
|
return (InstanceMaterialImpl<D>) materials.computeIfAbsent(spec, this::createInstanceMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
|
for (MaterialRenderer<P> renderer : renderers) {
|
||||||
|
renderer.render(viewProjection, camX, camY, camZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setup(P program) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
materials.values().forEach(InstanceMaterialImpl::clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
materials.values()
|
||||||
|
.forEach(InstanceMaterialImpl::delete);
|
||||||
|
|
||||||
|
materials.clear();
|
||||||
|
renderers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private InstanceMaterialImpl<?> createInstanceMaterial(MaterialSpec<?> type) {
|
||||||
|
InstanceMaterialImpl<?> material = new InstanceMaterialImpl<>(type);
|
||||||
|
|
||||||
|
this.renderers.add(new MaterialRenderer<>(owner.getProgram(type.getProgramName()), material, this::setup));
|
||||||
|
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,63 +1,13 @@
|
||||||
package com.jozufozu.flywheel.backend.material;
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||||
import com.jozufozu.flywheel.backend.state.TextureRenderState;
|
import com.jozufozu.flywheel.backend.state.TextureRenderState;
|
||||||
import com.jozufozu.flywheel.core.Materials;
|
|
||||||
import com.jozufozu.flywheel.core.WorldContext;
|
|
||||||
import com.jozufozu.flywheel.core.materials.ModelData;
|
|
||||||
import com.jozufozu.flywheel.core.materials.OrientedData;
|
|
||||||
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
|
||||||
import com.jozufozu.flywheel.util.WeakHashSet;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
|
||||||
import net.minecraft.inventory.container.PlayerContainer;
|
import net.minecraft.inventory.container.PlayerContainer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
|
||||||
import net.minecraft.util.math.vector.Vector3i;
|
import net.minecraft.util.math.vector.Vector3i;
|
||||||
|
|
||||||
public class MaterialManager<P extends WorldProgram> {
|
public interface MaterialManager {
|
||||||
|
|
||||||
public static int MAX_ORIGIN_DISTANCE = 100;
|
|
||||||
|
|
||||||
protected BlockPos originCoordinate = BlockPos.ZERO;
|
|
||||||
|
|
||||||
protected final WorldContext<P> context;
|
|
||||||
protected final GroupFactory<P> groupFactory;
|
|
||||||
protected final boolean ignoreOriginCoordinate;
|
|
||||||
|
|
||||||
protected final Map<RenderLayer, Map<IRenderState, MaterialGroup<P>>> layers;
|
|
||||||
|
|
||||||
private final WeakHashSet<OriginShiftListener> listeners;
|
|
||||||
|
|
||||||
public MaterialManager(WorldContext<P> context) {
|
|
||||||
this(context, MaterialGroup::new, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <P extends WorldProgram> Builder<P> builder(WorldContext<P> context) {
|
|
||||||
return new Builder<>(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MaterialManager(WorldContext<P> context, GroupFactory<P> groupFactory, boolean ignoreOriginCoordinate) {
|
|
||||||
this.context = context;
|
|
||||||
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
|
||||||
|
|
||||||
this.listeners = new WeakHashSet<>();
|
|
||||||
this.groupFactory = groupFactory;
|
|
||||||
|
|
||||||
this.layers = new EnumMap<>(RenderLayer.class);
|
|
||||||
for (RenderLayer value : RenderLayer.values()) {
|
|
||||||
layers.put(value, new HashMap<>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a material group that will render in the given layer with the given state.
|
* Get a material group that will render in the given layer with the given state.
|
||||||
|
@ -66,162 +16,31 @@ public class MaterialManager<P extends WorldProgram> {
|
||||||
* @param state The {@link IRenderState} you need to draw with.
|
* @param state The {@link IRenderState} you need to draw with.
|
||||||
* @return A material group whose children will
|
* @return A material group whose children will
|
||||||
*/
|
*/
|
||||||
public MaterialGroup<P> state(RenderLayer layer, IRenderState state) {
|
MaterialGroup state(RenderLayer layer, IRenderState state);
|
||||||
return layers.get(layer).computeIfAbsent(state, this::createGroup);
|
|
||||||
|
Vector3i getOriginCoordinate();
|
||||||
|
|
||||||
|
default MaterialGroup solid(IRenderState state) {
|
||||||
|
return state(RenderLayer.SOLID, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialGroup<P> solid(IRenderState state) {
|
default MaterialGroup cutout(IRenderState state) {
|
||||||
return layers.get(RenderLayer.SOLID).computeIfAbsent(state, this::createGroup);
|
return state(RenderLayer.CUTOUT, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialGroup<P> cutout(IRenderState state) {
|
default MaterialGroup transparent(IRenderState state) {
|
||||||
return layers.get(RenderLayer.CUTOUT).computeIfAbsent(state, this::createGroup);
|
return state(RenderLayer.TRANSPARENT, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialGroup<P> transparent(IRenderState state) {
|
default MaterialGroup defaultSolid() {
|
||||||
return layers.get(RenderLayer.TRANSPARENT).computeIfAbsent(state, this::createGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MaterialGroup<P> defaultSolid() {
|
|
||||||
return solid(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
return solid(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialGroup<P> defaultCutout() {
|
default MaterialGroup defaultCutout() {
|
||||||
return cutout(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
return cutout(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MaterialGroup<P> defaultTransparent() {
|
default MaterialGroup defaultTransparent() {
|
||||||
return transparent(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
return transparent(TextureRenderState.get(PlayerContainer.BLOCK_ATLAS));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Render every model for every material.
|
|
||||||
* @param layer Which of the 3 {@link RenderLayer render layers} is being drawn?
|
|
||||||
* @param viewProjection How do we get from camera space to clip space?
|
|
||||||
*/
|
|
||||||
public void render(RenderLayer layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
|
||||||
if (!ignoreOriginCoordinate) {
|
|
||||||
camX -= originCoordinate.getX();
|
|
||||||
camY -= originCoordinate.getY();
|
|
||||||
camZ -= originCoordinate.getZ();
|
|
||||||
|
|
||||||
Matrix4f translate = Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ);
|
|
||||||
|
|
||||||
translate.multiplyBackward(viewProjection);
|
|
||||||
|
|
||||||
viewProjection = translate;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<IRenderState, MaterialGroup<P>> entry : layers.get(layer).entrySet()) {
|
|
||||||
IRenderState state = entry.getKey();
|
|
||||||
MaterialGroup<P> group = entry.getValue();
|
|
||||||
|
|
||||||
state.bind();
|
|
||||||
group.render(viewProjection, camX, camY, camZ);
|
|
||||||
state.unbind();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
for (Map<IRenderState, MaterialGroup<P>> groups : layers.values()) {
|
|
||||||
|
|
||||||
groups.values().forEach(MaterialGroup::delete);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType) {
|
|
||||||
return defaultCutout().material(materialType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public <D extends InstanceData> InstanceMaterial<D> getMaterial(MaterialSpec<D> materialType, ResourceLocation texture) {
|
|
||||||
return cutout(TextureRenderState.get(texture)).material(materialType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public InstanceMaterial<ModelData> getTransformMaterial() {
|
|
||||||
return defaultCutout().material(Materials.TRANSFORMED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public InstanceMaterial<OrientedData> getOrientedMaterial() {
|
|
||||||
return defaultCutout().material(Materials.ORIENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Supplier<P> getProgram(ResourceLocation name) {
|
|
||||||
return context.getProgramSupplier(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector3i getOriginCoordinate() {
|
|
||||||
return originCoordinate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addListener(OriginShiftListener listener) {
|
|
||||||
listeners.add(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maintain the integer origin coordinate to be within a certain distance from the camera in all directions.
|
|
||||||
*
|
|
||||||
* This prevents floating point precision issues at high coordinates.
|
|
||||||
*/
|
|
||||||
public void checkAndShiftOrigin(ActiveRenderInfo info) {
|
|
||||||
int cX = MathHelper.floor(info.getPosition().x);
|
|
||||||
int cY = MathHelper.floor(info.getPosition().y);
|
|
||||||
int cZ = MathHelper.floor(info.getPosition().z);
|
|
||||||
|
|
||||||
int dX = cX - originCoordinate.getX();
|
|
||||||
int dY = cY - originCoordinate.getY();
|
|
||||||
int dZ = cZ - originCoordinate.getZ();
|
|
||||||
|
|
||||||
if (Math.abs(dX) > MAX_ORIGIN_DISTANCE || Math.abs(dY) > MAX_ORIGIN_DISTANCE || Math.abs(dZ) > MAX_ORIGIN_DISTANCE) {
|
|
||||||
|
|
||||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
|
||||||
|
|
||||||
for (Map<IRenderState, MaterialGroup<P>> groups : layers.values()) {
|
|
||||||
groups.values().forEach(MaterialGroup::clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private MaterialGroup<P> createGroup(IRenderState state) {
|
|
||||||
return groupFactory.create(this, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface OriginShiftListener {
|
|
||||||
void onOriginShift();
|
|
||||||
}
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface GroupFactory<P extends WorldProgram> {
|
|
||||||
MaterialGroup<P> create(MaterialManager<P> materialManager, IRenderState state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder<P extends WorldProgram> {
|
|
||||||
protected final WorldContext<P> context;
|
|
||||||
protected GroupFactory<P> groupFactory = MaterialGroup::new;
|
|
||||||
protected boolean ignoreOriginCoordinate;
|
|
||||||
|
|
||||||
public Builder(WorldContext<P> context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<P> setGroupFactory(GroupFactory<P> groupFactory) {
|
|
||||||
this.groupFactory = groupFactory;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<P> setIgnoreOriginCoordinate(boolean ignoreOriginCoordinate) {
|
|
||||||
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MaterialManager<P> build() {
|
|
||||||
return new MaterialManager<>(context, groupFactory, ignoreOriginCoordinate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
package com.jozufozu.flywheel.backend.material;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
|
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||||
|
import com.jozufozu.flywheel.core.WorldContext;
|
||||||
|
import com.jozufozu.flywheel.core.shader.WorldProgram;
|
||||||
|
import com.jozufozu.flywheel.util.WeakHashSet;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
import net.minecraft.util.math.vector.Vector3i;
|
||||||
|
|
||||||
|
public class MaterialManagerImpl<P extends WorldProgram> implements MaterialManager {
|
||||||
|
|
||||||
|
public static int MAX_ORIGIN_DISTANCE = 100;
|
||||||
|
|
||||||
|
protected BlockPos originCoordinate = BlockPos.ZERO;
|
||||||
|
|
||||||
|
protected final WorldContext<P> context;
|
||||||
|
protected final GroupFactory<P> groupFactory;
|
||||||
|
protected final boolean ignoreOriginCoordinate;
|
||||||
|
|
||||||
|
protected final Map<RenderLayer, Map<IRenderState, MaterialGroupImpl<P>>> layers;
|
||||||
|
|
||||||
|
private final WeakHashSet<OriginShiftListener> listeners;
|
||||||
|
|
||||||
|
public MaterialManagerImpl(WorldContext<P> context) {
|
||||||
|
this(context, MaterialGroupImpl::new, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <P extends WorldProgram> Builder<P> builder(WorldContext<P> context) {
|
||||||
|
return new Builder<>(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialManagerImpl(WorldContext<P> context, GroupFactory<P> groupFactory, boolean ignoreOriginCoordinate) {
|
||||||
|
this.context = context;
|
||||||
|
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
||||||
|
|
||||||
|
this.listeners = new WeakHashSet<>();
|
||||||
|
this.groupFactory = groupFactory;
|
||||||
|
|
||||||
|
this.layers = new EnumMap<>(RenderLayer.class);
|
||||||
|
for (RenderLayer value : RenderLayer.values()) {
|
||||||
|
layers.put(value, new HashMap<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 state The {@link IRenderState} you need to draw with.
|
||||||
|
* @return A material group whose children will
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public MaterialGroup state(RenderLayer layer, IRenderState state) {
|
||||||
|
return layers.get(layer).computeIfAbsent(state, this::createGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render every model for every material.
|
||||||
|
* @param layer Which of the 3 {@link RenderLayer render layers} is being drawn?
|
||||||
|
* @param viewProjection How do we get from camera space to clip space?
|
||||||
|
*/
|
||||||
|
public void render(RenderLayer layer, Matrix4f viewProjection, double camX, double camY, double camZ) {
|
||||||
|
if (!ignoreOriginCoordinate) {
|
||||||
|
camX -= originCoordinate.getX();
|
||||||
|
camY -= originCoordinate.getY();
|
||||||
|
camZ -= originCoordinate.getZ();
|
||||||
|
|
||||||
|
Matrix4f translate = Matrix4f.createTranslateMatrix((float) -camX, (float) -camY, (float) -camZ);
|
||||||
|
|
||||||
|
translate.multiplyBackward(viewProjection);
|
||||||
|
|
||||||
|
viewProjection = translate;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<IRenderState, MaterialGroupImpl<P>> entry : layers.get(layer).entrySet()) {
|
||||||
|
IRenderState state = entry.getKey();
|
||||||
|
MaterialGroupImpl<P> group = entry.getValue();
|
||||||
|
|
||||||
|
state.bind();
|
||||||
|
group.render(viewProjection, camX, camY, camZ);
|
||||||
|
state.unbind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
for (Map<IRenderState, MaterialGroupImpl<P>> groups : layers.values()) {
|
||||||
|
|
||||||
|
groups.values().forEach(MaterialGroupImpl::delete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Supplier<P> getProgram(ResourceLocation name) {
|
||||||
|
return context.getProgramSupplier(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3i getOriginCoordinate() {
|
||||||
|
return originCoordinate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addListener(OriginShiftListener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maintain the integer origin coordinate to be within a certain distance from the camera in all directions.
|
||||||
|
*
|
||||||
|
* This prevents floating point precision issues at high coordinates.
|
||||||
|
*/
|
||||||
|
public void beginFrame(ActiveRenderInfo info) {
|
||||||
|
int cX = MathHelper.floor(info.getPosition().x);
|
||||||
|
int cY = MathHelper.floor(info.getPosition().y);
|
||||||
|
int cZ = MathHelper.floor(info.getPosition().z);
|
||||||
|
|
||||||
|
int dX = cX - originCoordinate.getX();
|
||||||
|
int dY = cY - originCoordinate.getY();
|
||||||
|
int dZ = cZ - originCoordinate.getZ();
|
||||||
|
|
||||||
|
if (Math.abs(dX) > MAX_ORIGIN_DISTANCE || Math.abs(dY) > MAX_ORIGIN_DISTANCE || Math.abs(dZ) > MAX_ORIGIN_DISTANCE) {
|
||||||
|
|
||||||
|
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||||
|
|
||||||
|
for (Map<IRenderState, MaterialGroupImpl<P>> groups : layers.values()) {
|
||||||
|
groups.values().forEach(MaterialGroupImpl::clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MaterialGroupImpl<P> createGroup(IRenderState state) {
|
||||||
|
return groupFactory.create(this, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OriginShiftListener {
|
||||||
|
void onOriginShift();
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface GroupFactory<P extends WorldProgram> {
|
||||||
|
MaterialGroupImpl<P> create(MaterialManagerImpl<P> materialManager, IRenderState state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder<P extends WorldProgram> {
|
||||||
|
protected final WorldContext<P> context;
|
||||||
|
protected GroupFactory<P> groupFactory = MaterialGroupImpl::new;
|
||||||
|
protected boolean ignoreOriginCoordinate;
|
||||||
|
|
||||||
|
public Builder(WorldContext<P> context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<P> setGroupFactory(GroupFactory<P> groupFactory) {
|
||||||
|
this.groupFactory = groupFactory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<P> setIgnoreOriginCoordinate(boolean ignoreOriginCoordinate) {
|
||||||
|
this.ignoreOriginCoordinate = ignoreOriginCoordinate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MaterialManagerImpl<P> build() {
|
||||||
|
return new MaterialManagerImpl<>(context, groupFactory, ignoreOriginCoordinate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,11 +12,11 @@ import net.minecraft.util.math.vector.Matrix4f;
|
||||||
public class MaterialRenderer<P extends WorldProgram> {
|
public class MaterialRenderer<P extends WorldProgram> {
|
||||||
|
|
||||||
protected final Supplier<P> program;
|
protected final Supplier<P> program;
|
||||||
protected final InstanceMaterial<?> material;
|
protected final InstanceMaterialImpl<?> material;
|
||||||
|
|
||||||
protected final Consumer<P> setupFunc;
|
protected final Consumer<P> setupFunc;
|
||||||
|
|
||||||
public MaterialRenderer(Supplier<P> programSupplier, InstanceMaterial<?> material, Consumer<P> setupFunc) {
|
public MaterialRenderer(Supplier<P> programSupplier, InstanceMaterialImpl<?> material, Consumer<P> setupFunc) {
|
||||||
this.program = programSupplier;
|
this.program = programSupplier;
|
||||||
this.material = material;
|
this.material = material;
|
||||||
this.setupFunc = setupFunc;
|
this.setupFunc = setupFunc;
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.jozufozu.flywheel.backend.model;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
|
|
||||||
|
public class ImmediateAllocator implements ModelAllocator {
|
||||||
|
|
||||||
|
public static final ImmediateAllocator INSTANCE = new ImmediateAllocator();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBufferedModel alloc(IModel model, Callback allocationCallback) {
|
||||||
|
IndexedModel out = new IndexedModel(model);
|
||||||
|
allocationCallback.onAlloc(out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.jozufozu.flywheel.backend.model;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
|
|
||||||
|
public interface ModelAllocator {
|
||||||
|
/**
|
||||||
|
* Allocate a model.
|
||||||
|
*
|
||||||
|
* @param model The model to allocate.
|
||||||
|
* @return A handle to the allocated model.
|
||||||
|
*/
|
||||||
|
IBufferedModel alloc(IModel model, Callback allocationCallback);
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
interface Callback {
|
||||||
|
void onAlloc(IBufferedModel arenaModel);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,9 +12,8 @@ import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer;
|
||||||
import com.jozufozu.flywheel.core.model.IModel;
|
import com.jozufozu.flywheel.core.model.IModel;
|
||||||
import com.jozufozu.flywheel.util.AttribUtil;
|
import com.jozufozu.flywheel.util.AttribUtil;
|
||||||
import com.jozufozu.flywheel.util.StringUtil;
|
|
||||||
|
|
||||||
public class ModelPool {
|
public class ModelPool implements ModelAllocator {
|
||||||
|
|
||||||
protected final VertexFormat format;
|
protected final VertexFormat format;
|
||||||
|
|
||||||
|
@ -47,8 +46,10 @@ public class ModelPool {
|
||||||
* @param model The model to allocate.
|
* @param model The model to allocate.
|
||||||
* @return A handle to the allocated model.
|
* @return A handle to the allocated model.
|
||||||
*/
|
*/
|
||||||
public PooledModel alloc(IModel model) {
|
@Override
|
||||||
|
public PooledModel alloc(IModel model, Callback callback) {
|
||||||
PooledModel bufferedModel = new PooledModel(model, vertices);
|
PooledModel bufferedModel = new PooledModel(model, vertices);
|
||||||
|
bufferedModel.callback = callback;
|
||||||
vertices += model.vertexCount();
|
vertices += model.vertexCount();
|
||||||
models.add(bufferedModel);
|
models.add(bufferedModel);
|
||||||
pendingUpload.add(bufferedModel);
|
pendingUpload.add(bufferedModel);
|
||||||
|
@ -117,7 +118,7 @@ public class ModelPool {
|
||||||
for (PooledModel model : models) {
|
for (PooledModel model : models) {
|
||||||
model.model.buffer(buffer);
|
model.model.buffer(buffer);
|
||||||
if (model.callback != null)
|
if (model.callback != null)
|
||||||
model.callback.invoke(model);
|
model.callback.onAlloc(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.flush();
|
buffer.flush();
|
||||||
|
@ -132,7 +133,7 @@ public class ModelPool {
|
||||||
buffer.position(pos);
|
buffer.position(pos);
|
||||||
model.model.buffer(buffer);
|
model.model.buffer(buffer);
|
||||||
if (model.callback != null)
|
if (model.callback != null)
|
||||||
model.callback.invoke(model);
|
model.callback.onAlloc(model);
|
||||||
}
|
}
|
||||||
pendingUpload.clear();
|
pendingUpload.clear();
|
||||||
|
|
||||||
|
@ -199,7 +200,7 @@ public class ModelPool {
|
||||||
|
|
||||||
ebo.bind();
|
ebo.bind();
|
||||||
|
|
||||||
Backend.log.info(StringUtil.args("drawElementsInstancedBaseVertex", GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first));
|
//Backend.log.info(StringUtil.args("drawElementsInstancedBaseVertex", GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first));
|
||||||
|
|
||||||
Backend.getInstance().compat.baseVertex.drawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first);
|
Backend.getInstance().compat.baseVertex.drawElementsInstancedBaseVertex(GlPrimitive.TRIANGLES, ebo.elementCount, ebo.eboIndexType, 0, instanceCount, first);
|
||||||
}
|
}
|
||||||
|
@ -215,15 +216,6 @@ public class ModelPool {
|
||||||
anyToRemove = true;
|
anyToRemove = true;
|
||||||
remove = true;
|
remove = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledModel setReallocCallback(Callback callback) {
|
|
||||||
this.callback = callback;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface Callback {
|
|
||||||
void invoke(PooledModel arenaModel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ public class QuadConverter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void free() {
|
public void delete() {
|
||||||
ebos.values()
|
ebos.values()
|
||||||
.forEach(GlBuffer::delete);
|
.forEach(GlBuffer::delete);
|
||||||
ebos.clear();
|
ebos.clear();
|
||||||
|
@ -172,6 +172,6 @@ public class QuadConverter {
|
||||||
// make sure this gets reset first so it has a chance to repopulate
|
// make sure this gets reset first so it has a chance to repopulate
|
||||||
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
@SubscribeEvent(priority = EventPriority.HIGHEST)
|
||||||
public static void onRendererReload(ReloadRenderersEvent event) {
|
public static void onRendererReload(ReloadRenderersEvent event) {
|
||||||
if (INSTANCE != null) INSTANCE.free();
|
if (INSTANCE != null) INSTANCE.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialGroup;
|
import com.jozufozu.flywheel.backend.material.MaterialGroupImpl;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
import com.jozufozu.flywheel.backend.state.IRenderState;
|
import com.jozufozu.flywheel.backend.state.IRenderState;
|
||||||
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
import com.jozufozu.flywheel.core.atlas.AtlasInfo;
|
||||||
import com.jozufozu.flywheel.core.atlas.SheetData;
|
import com.jozufozu.flywheel.core.atlas.SheetData;
|
||||||
|
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroup<P> {
|
public class CrumblingGroup<P extends CrumblingProgram> extends MaterialGroupImpl<P> {
|
||||||
|
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
public CrumblingGroup(MaterialManager<P> owner, IRenderState state) {
|
public CrumblingGroup(MaterialManagerImpl<P> owner, IRenderState state) {
|
||||||
super(owner, state);
|
super(owner, state);
|
||||||
|
|
||||||
ResourceLocation texture = state.getTexture(GlTextureUnit.T0);
|
ResourceLocation texture = state.getTexture(GlTextureUnit.T0);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class CrumblingInstanceManager extends TileInstanceManager {
|
public class CrumblingInstanceManager extends TileInstanceManager {
|
||||||
|
|
||||||
public CrumblingInstanceManager(MaterialManager<?> materialManager) {
|
public CrumblingInstanceManager(MaterialManagerImpl<?> materialManager) {
|
||||||
super(materialManager);
|
super(materialManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
import com.jozufozu.flywheel.backend.material.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.backend.material.MaterialManagerImpl;
|
||||||
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
import com.jozufozu.flywheel.backend.state.RenderLayer;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
|
@ -69,7 +70,7 @@ public class CrumblingRenderer {
|
||||||
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
TextureManager textureManager = Minecraft.getInstance().textureManager;
|
||||||
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getMainCamera();
|
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
|
|
||||||
MaterialManager<CrumblingProgram> materials = state.materialManager;
|
MaterialManagerImpl<CrumblingProgram> materials = state.materialManager;
|
||||||
layer.setupRenderState();
|
layer.setupRenderState();
|
||||||
|
|
||||||
for (Int2ObjectMap.Entry<List<TileEntity>> stage : activeStages.int2ObjectEntrySet()) {
|
for (Int2ObjectMap.Entry<List<TileEntity>> stage : activeStages.int2ObjectEntrySet()) {
|
||||||
|
@ -140,11 +141,11 @@ public class CrumblingRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class State {
|
private static class State {
|
||||||
private final MaterialManager<CrumblingProgram> materialManager;
|
private final MaterialManagerImpl<CrumblingProgram> materialManager;
|
||||||
private final InstanceManager<TileEntity> instanceManager;
|
private final InstanceManager<TileEntity> instanceManager;
|
||||||
|
|
||||||
private State() {
|
private State() {
|
||||||
materialManager = MaterialManager.builder(Contexts.CRUMBLING)
|
materialManager = MaterialManagerImpl.builder(Contexts.CRUMBLING)
|
||||||
.setGroupFactory(CrumblingGroup::new)
|
.setGroupFactory(CrumblingGroup::new)
|
||||||
.build();
|
.build();
|
||||||
instanceManager = new CrumblingInstanceManager(materialManager);
|
instanceManager = new CrumblingInstanceManager(materialManager);
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class BellInstance extends TileEntityInstance<BellTileEntity> implements
|
||||||
|
|
||||||
private float lastRingTime = Float.NaN;
|
private float lastRingTime = Float.NaN;
|
||||||
|
|
||||||
public BellInstance(MaterialManager<?> materialManager, BellTileEntity tile) {
|
public BellInstance(MaterialManager materialManager, BellTileEntity tile) {
|
||||||
super(materialManager, tile);
|
super(materialManager, tile);
|
||||||
|
|
||||||
bell = createBellInstance()
|
bell = createBellInstance()
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityI
|
||||||
|
|
||||||
private float lastProgress = Float.NaN;
|
private float lastProgress = Float.NaN;
|
||||||
|
|
||||||
public ChestInstance(MaterialManager<?> materialManager, T tile) {
|
public ChestInstance(MaterialManager materialManager, T tile) {
|
||||||
super(materialManager, tile);
|
super(materialManager, tile);
|
||||||
|
|
||||||
Block block = blockState.getBlock();
|
Block block = blockState.getBlock();
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class ShulkerBoxInstance extends TileEntityInstance<ShulkerBoxTileEntity>
|
||||||
|
|
||||||
private float lastProgress = Float.NaN;
|
private float lastProgress = Float.NaN;
|
||||||
|
|
||||||
public ShulkerBoxInstance(MaterialManager<?> materialManager, ShulkerBoxTileEntity tile) {
|
public ShulkerBoxInstance(MaterialManager materialManager, ShulkerBoxTileEntity tile) {
|
||||||
super(materialManager, tile);
|
super(materialManager, tile);
|
||||||
|
|
||||||
DyeColor color = tile.getColor();
|
DyeColor color = tile.getColor();
|
||||||
|
|
Loading…
Reference in a new issue