mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-27 21:37:56 +01:00
Shaded shader
- Rename MaterialManager -> InstancerManager and Material -> InstancerFactory - Create Material class consisting of RenderType and shader files - Make ModelSuppliers use Materials as keys instead of RenderTypes - Move diffuse calculation from context shaders to material/shaded.vert - Merge used templates directly into compilers and remove template classes
This commit is contained in:
parent
15f41e7b9c
commit
a7a716b469
66 changed files with 599 additions and 601 deletions
|
@ -13,7 +13,8 @@ import com.jozufozu.flywheel.core.Models;
|
||||||
import com.jozufozu.flywheel.core.PartialModel;
|
import com.jozufozu.flywheel.core.PartialModel;
|
||||||
import com.jozufozu.flywheel.core.StitchedSprite;
|
import com.jozufozu.flywheel.core.StitchedSprite;
|
||||||
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
|
||||||
import com.jozufozu.flywheel.core.materials.InstanceShaders;
|
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||||
|
import com.jozufozu.flywheel.core.structs.InstanceShaders;
|
||||||
import com.jozufozu.flywheel.core.vertex.LayoutShaders;
|
import com.jozufozu.flywheel.core.vertex.LayoutShaders;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
||||||
|
@ -77,6 +78,7 @@ public class Flywheel {
|
||||||
|
|
||||||
modEventBus.addListener(LayoutShaders::flwInit);
|
modEventBus.addListener(LayoutShaders::flwInit);
|
||||||
modEventBus.addListener(InstanceShaders::flwInit);
|
modEventBus.addListener(InstanceShaders::flwInit);
|
||||||
|
modEventBus.addListener(MaterialShaders::flwInit);
|
||||||
modEventBus.addListener(Contexts::flwInit);
|
modEventBus.addListener(Contexts::flwInit);
|
||||||
modEventBus.addListener(PartialModel::onModelRegistry);
|
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||||
modEventBus.addListener(PartialModel::onModelBake);
|
modEventBus.addListener(PartialModel::onModelBake);
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.api;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
||||||
|
|
||||||
public interface Material<D extends InstanceData> {
|
public interface InstancerFactory<D extends InstanceData> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
|
@ -4,9 +4,9 @@ import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
|
|
||||||
public interface MaterialManager {
|
public interface InstancerManager {
|
||||||
|
|
||||||
<D extends InstanceData> Material<D> material(StructType<D> type);
|
<D extends InstanceData> InstancerFactory<D> factory(StructType<D> type);
|
||||||
|
|
||||||
Vec3i getOriginCoordinate();
|
Vec3i getOriginCoordinate();
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.api;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public interface MaterialGroup {
|
public interface MaterialGroup {
|
||||||
/**
|
/**
|
||||||
* Get the material as defined by the given {@link StructType type}.
|
* Get the material as defined by the given {@link StructType type}.
|
||||||
|
@ -10,5 +11,5 @@ public interface MaterialGroup {
|
||||||
* @param <D> The type representing the per instance data.
|
* @param <D> The type representing the per instance data.
|
||||||
* @return A material you can use to render models.
|
* @return A material you can use to render models.
|
||||||
*/
|
*/
|
||||||
<D extends InstanceData> Material<D> material(StructType<D> spec);
|
<D extends InstanceData> InstancerFactory<D> material(StructType<D> spec);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.jozufozu.flywheel.api.material;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
||||||
|
public class Material {
|
||||||
|
protected final RenderType renderType;
|
||||||
|
protected final Supplier<FileResolution> vertexShader;
|
||||||
|
protected final Supplier<FileResolution> fragmentShader;
|
||||||
|
|
||||||
|
public Material(RenderType renderType, Supplier<FileResolution> vertexShader, Supplier<FileResolution> fragmentShader) {
|
||||||
|
this.renderType = renderType;
|
||||||
|
this.vertexShader = vertexShader;
|
||||||
|
this.fragmentShader = fragmentShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RenderType getRenderType() {
|
||||||
|
return renderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileResolution getVertexShader() {
|
||||||
|
return vertexShader.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileResolution getFragmentShader() {
|
||||||
|
return fragmentShader.get();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,12 +3,12 @@ package com.jozufozu.flywheel.backend.instancing;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.core.materials.FlatLit;
|
import com.jozufozu.flywheel.core.structs.FlatLit;
|
||||||
import com.jozufozu.flywheel.light.LightListener;
|
import com.jozufozu.flywheel.light.LightListener;
|
||||||
import com.jozufozu.flywheel.light.LightProvider;
|
import com.jozufozu.flywheel.light.LightProvider;
|
||||||
import com.jozufozu.flywheel.light.ListenerStatus;
|
import com.jozufozu.flywheel.light.ListenerStatus;
|
||||||
|
@ -24,12 +24,12 @@ import net.minecraft.world.level.LightLayer;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractInstance implements Instance, LightListener {
|
public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
|
|
||||||
protected final MaterialManager materialManager;
|
protected final InstancerManager instancerManager;
|
||||||
public final Level world;
|
public final Level level;
|
||||||
|
|
||||||
public AbstractInstance(MaterialManager materialManager, Level world) {
|
public AbstractInstance(InstancerManager instancerManager, Level level) {
|
||||||
this.materialManager = materialManager;
|
this.instancerManager = instancerManager;
|
||||||
this.world = world;
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,11 +88,11 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void relight(BlockPos pos, FlatLit<?>... models) {
|
protected void relight(BlockPos pos, FlatLit<?>... models) {
|
||||||
relight(world.getBrightness(LightLayer.BLOCK, pos), world.getBrightness(LightLayer.SKY, pos), models);
|
relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), models);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <L extends FlatLit<?>> void relight(BlockPos pos, Stream<L> models) {
|
protected <L extends FlatLit<?>> void relight(BlockPos pos, Stream<L> models) {
|
||||||
relight(world.getBrightness(LightLayer.BLOCK, pos), world.getBrightness(LightLayer.SKY, pos), models);
|
relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), models);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void relight(int block, int sky, FlatLit<?>... models) {
|
protected void relight(int block, int sky, FlatLit<?>... models) {
|
||||||
|
|
|
@ -2,8 +2,8 @@ package com.jozufozu.flywheel.backend.instancing;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
|
|
||||||
public interface Engine extends RenderDispatcher, MaterialManager {
|
public interface Engine extends RenderDispatcher, InstancerManager {
|
||||||
void addDebugInfo(List<String> info);
|
void addDebugInfo(List<String> info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
@ -27,7 +27,7 @@ import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
public abstract class InstanceManager<T> implements InstancingEngine.OriginShiftListener {
|
public abstract class InstanceManager<T> implements InstancingEngine.OriginShiftListener {
|
||||||
|
|
||||||
public final MaterialManager materialManager;
|
public final InstancerManager instancerManager;
|
||||||
|
|
||||||
private final Set<T> queuedAdditions;
|
private final Set<T> queuedAdditions;
|
||||||
private final Set<T> queuedUpdates;
|
private final Set<T> queuedUpdates;
|
||||||
|
@ -39,8 +39,8 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
protected DistanceUpdateLimiter frame;
|
protected DistanceUpdateLimiter frame;
|
||||||
protected DistanceUpdateLimiter tick;
|
protected DistanceUpdateLimiter tick;
|
||||||
|
|
||||||
public InstanceManager(MaterialManager materialManager) {
|
public InstanceManager(InstancerManager instancerManager) {
|
||||||
this.materialManager = materialManager;
|
this.instancerManager = instancerManager;
|
||||||
this.queuedUpdates = new HashSet<>(64);
|
this.queuedUpdates = new HashSet<>(64);
|
||||||
this.queuedAdditions = new HashSet<>(64);
|
this.queuedAdditions = new HashSet<>(64);
|
||||||
this.instances = new HashMap<>();
|
this.instances = new HashMap<>();
|
||||||
|
@ -318,7 +318,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
instances.remove(obj);
|
instances.remove(obj);
|
||||||
dynamicInstances.remove(obj);
|
dynamicInstances.remove(obj);
|
||||||
tickableInstances.remove(obj);
|
tickableInstances.remove(obj);
|
||||||
LightUpdater.get(instance.world)
|
LightUpdater.get(instance.level)
|
||||||
.removeListener(instance);
|
.removeListener(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
renderer.init();
|
renderer.init();
|
||||||
renderer.updateLight();
|
renderer.updateLight();
|
||||||
LightUpdater.get(renderer.world)
|
LightUpdater.get(renderer.level)
|
||||||
.addListener(renderer);
|
.addListener(renderer);
|
||||||
instances.put(obj, renderer);
|
instances.put(obj, renderer);
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
|
|
||||||
public void detachLightListeners() {
|
public void detachLightListeners() {
|
||||||
for (AbstractInstance value : instances.values()) {
|
for (AbstractInstance value : instances.values()) {
|
||||||
LightUpdater.get(value.world).removeListener(value);
|
LightUpdater.get(value.level).removeListener(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
/**
|
/**
|
||||||
* A manager class for a single world where instancing is supported.
|
* A manager class for a single world where instancing is supported.
|
||||||
* <p>
|
* <p>
|
||||||
* The material manager is shared between the different instance managers.
|
* The instancer manager is shared between the different instance managers.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class InstanceWorld {
|
public class InstanceWorld {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstancingController;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityTypeExtension;
|
||||||
|
@ -48,34 +48,34 @@ public class InstancedRenderRegistry {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance for the given block entity, if possible.
|
* Creates an instance for the given block entity, if possible.
|
||||||
* @param materialManager The material manager to use.
|
* @param instancerManager The instancer manager to use.
|
||||||
* @param blockEntity The block entity to create an instance of.
|
* @param blockEntity The block entity to create an instance of.
|
||||||
* @param <T> The type of the block entity.
|
* @param <T> The type of the block entity.
|
||||||
* @return An instance of the block entity, or {@code null} if the block entity cannot be instanced.
|
* @return An instance of the block entity, or {@code null} if the block entity cannot be instanced.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends BlockEntity> BlockEntityInstance<? super T> createInstance(MaterialManager materialManager, T blockEntity) {
|
public static <T extends BlockEntity> BlockEntityInstance<? super T> createInstance(InstancerManager instancerManager, T blockEntity) {
|
||||||
BlockEntityInstancingController<? super T> controller = getController(getType(blockEntity));
|
BlockEntityInstancingController<? super T> controller = getController(getType(blockEntity));
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return controller.createInstance(materialManager, blockEntity);
|
return controller.createInstance(instancerManager, blockEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance for the given entity, if possible.
|
* Creates an instance for the given entity, if possible.
|
||||||
* @param materialManager The material manager to use.
|
* @param instancerManager The instancer manager to use.
|
||||||
* @param entity The entity to create an instance of.
|
* @param entity The entity to create an instance of.
|
||||||
* @param <T> The type of the entity.
|
* @param <T> The type of the entity.
|
||||||
* @return An instance of the entity, or {@code null} if the entity cannot be instanced.
|
* @return An instance of the entity, or {@code null} if the entity cannot be instanced.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends Entity> EntityInstance<? super T> createInstance(MaterialManager materialManager, T entity) {
|
public static <T extends Entity> EntityInstance<? super T> createInstance(InstancerManager instancerManager, T entity) {
|
||||||
EntityInstancingController<? super T> controller = getController(getType(entity));
|
EntityInstancingController<? super T> controller = getController(getType(entity));
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return controller.createInstance(materialManager, entity);
|
return controller.createInstance(instancerManager, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,7 +194,7 @@ public class InstancedRenderRegistry {
|
||||||
*/
|
*/
|
||||||
public static class BlockEntityConfig<T extends BlockEntity> {
|
public static class BlockEntityConfig<T extends BlockEntity> {
|
||||||
protected BlockEntityType<T> type;
|
protected BlockEntityType<T> type;
|
||||||
protected BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
protected BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||||
protected Predicate<T> skipRender;
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
public BlockEntityConfig(BlockEntityType<T> type) {
|
public BlockEntityConfig(BlockEntityType<T> type) {
|
||||||
|
@ -206,7 +206,7 @@ public class InstancedRenderRegistry {
|
||||||
* @param instanceFactory The instance factory.
|
* @param instanceFactory The instance factory.
|
||||||
* @return {@code this}
|
* @return {@code this}
|
||||||
*/
|
*/
|
||||||
public BlockEntityConfig<T> factory(BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory) {
|
public BlockEntityConfig<T> factory(BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory) {
|
||||||
this.instanceFactory = instanceFactory;
|
this.instanceFactory = instanceFactory;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ public class InstancedRenderRegistry {
|
||||||
*/
|
*/
|
||||||
public static class EntityConfig<T extends Entity> {
|
public static class EntityConfig<T extends Entity> {
|
||||||
protected EntityType<T> type;
|
protected EntityType<T> type;
|
||||||
protected BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory;
|
protected BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory;
|
||||||
protected Predicate<T> skipRender;
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
public EntityConfig(EntityType<T> type) {
|
public EntityConfig(EntityType<T> type) {
|
||||||
|
@ -263,7 +263,7 @@ public class InstancedRenderRegistry {
|
||||||
* @param instanceFactory The instance factory.
|
* @param instanceFactory The instance factory.
|
||||||
* @return {@code this}
|
* @return {@code this}
|
||||||
*/
|
*/
|
||||||
public EntityConfig<T> factory(BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory) {
|
public EntityConfig<T> factory(BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory) {
|
||||||
this.instanceFactory = instanceFactory;
|
this.instanceFactory = instanceFactory;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
||||||
|
|
||||||
protected final RenderType state;
|
protected final RenderType state;
|
||||||
|
|
||||||
private final Map<Batched<? extends InstanceData>, BatchedMaterial<?>> materials = new HashMap<>();
|
private final Map<Batched<? extends InstanceData>, CPUInstancerFactory<?>> materials = new HashMap<>();
|
||||||
private int vertexCount;
|
private int vertexCount;
|
||||||
private int instanceCount;
|
private int instanceCount;
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstanceData> BatchedMaterial<D> material(StructType<D> type) {
|
public <D extends InstanceData> CPUInstancerFactory<D> material(StructType<D> type) {
|
||||||
if (type instanceof Batched<D> batched) {
|
if (type instanceof Batched<D> batched) {
|
||||||
return (BatchedMaterial<D>) materials.computeIfAbsent(batched, BatchedMaterial::new);
|
return (CPUInstancerFactory<D>) materials.computeIfAbsent(batched, CPUInstancerFactory::new);
|
||||||
} else {
|
} else {
|
||||||
throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing.");
|
throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing.");
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
materials.values().forEach(BatchedMaterial::clear);
|
materials.values().forEach(CPUInstancerFactory::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
|
|
@ -21,16 +21,16 @@ import net.minecraft.core.Vec3i;
|
||||||
|
|
||||||
public class BatchingEngine implements Engine {
|
public class BatchingEngine implements Engine {
|
||||||
|
|
||||||
private final Map<Batched<? extends InstanceData>, BatchedMaterial<?>> materials = new HashMap<>();
|
private final Map<Batched<? extends InstanceData>, CPUInstancerFactory<?>> factories = new HashMap<>();
|
||||||
private final BatchDrawingTracker batchTracker = new BatchDrawingTracker();
|
private final BatchDrawingTracker batchTracker = new BatchDrawingTracker();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstanceData> BatchedMaterial<D> material(StructType<D> type) {
|
public <D extends InstanceData> CPUInstancerFactory<D> factory(StructType<D> type) {
|
||||||
if (type instanceof Batched<D> batched) {
|
if (type instanceof Batched<D> batched) {
|
||||||
return (BatchedMaterial<D>) materials.computeIfAbsent(batched, BatchedMaterial::new);
|
return (CPUInstancerFactory<D>) factories.computeIfAbsent(batched, CPUInstancerFactory::new);
|
||||||
} else {
|
} else {
|
||||||
throw new ClassCastException("Cannot use type '" + type + "' with batching.");
|
throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ public class BatchingEngine implements Engine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) {
|
public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) {
|
||||||
|
|
||||||
// vertexCount = 0;
|
// vertexCount = 0;
|
||||||
// instanceCount = 0;
|
// instanceCount = 0;
|
||||||
// for (BatchedMaterial<?> material : materials.values()) {
|
// for (BatchedMaterial<?> material : materials.values()) {
|
||||||
|
|
|
@ -5,18 +5,18 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.api.Instancer;
|
import com.jozufozu.flywheel.api.Instancer;
|
||||||
import com.jozufozu.flywheel.api.Material;
|
import com.jozufozu.flywheel.api.InstancerFactory;
|
||||||
import com.jozufozu.flywheel.api.struct.Batched;
|
import com.jozufozu.flywheel.api.struct.Batched;
|
||||||
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
|
|
||||||
public class BatchedMaterial<D extends InstanceData> implements Material<D> {
|
public class CPUInstancerFactory<D extends InstanceData> implements InstancerFactory<D> {
|
||||||
|
|
||||||
protected final Map<ModelSupplier, CPUInstancer<D>> models;
|
protected final Map<ModelSupplier, CPUInstancer<D>> models;
|
||||||
private final Batched<D> type;
|
private final Batched<D> type;
|
||||||
|
|
||||||
public BatchedMaterial(Batched<D> type) {
|
public CPUInstancerFactory(Batched<D> type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
|
||||||
this.models = new HashMap<>();
|
this.models = new HashMap<>();
|
|
@ -1,13 +1,13 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.Material;
|
import com.jozufozu.flywheel.api.InstancerFactory;
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.core.materials.Materials;
|
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.structs.model.ModelData;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.structs.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ public abstract class BlockEntityInstance<T extends BlockEntity> extends Abstrac
|
||||||
protected final BlockPos instancePos;
|
protected final BlockPos instancePos;
|
||||||
protected final BlockState blockState;
|
protected final BlockState blockState;
|
||||||
|
|
||||||
public BlockEntityInstance(MaterialManager materialManager, T blockEntity) {
|
public BlockEntityInstance(InstancerManager instancerManager, T blockEntity) {
|
||||||
super(materialManager, blockEntity.getLevel());
|
super(instancerManager, blockEntity.getLevel());
|
||||||
this.blockEntity = blockEntity;
|
this.blockEntity = blockEntity;
|
||||||
this.pos = blockEntity.getBlockPos();
|
this.pos = blockEntity.getBlockPos();
|
||||||
this.blockState = blockEntity.getBlockState();
|
this.blockState = blockEntity.getBlockState();
|
||||||
this.instancePos = pos.subtract(materialManager.getOriginCoordinate());
|
this.instancePos = pos.subtract(instancerManager.getOriginCoordinate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +68,7 @@ public abstract class BlockEntityInstance<T extends BlockEntity> extends Abstrac
|
||||||
* represents should be rendered at to appear in the correct location.
|
* represents should be rendered at to appear in the correct location.
|
||||||
*/
|
*/
|
||||||
public BlockPos getInstancePosition() {
|
public BlockPos getInstancePosition() {
|
||||||
return pos.subtract(materialManager.getOriginCoordinate());
|
return pos.subtract(instancerManager.getOriginCoordinate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,12 +76,12 @@ public abstract class BlockEntityInstance<T extends BlockEntity> extends Abstrac
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Material<ModelData> getTransformMaterial() {
|
protected InstancerFactory<ModelData> getTransformFactory() {
|
||||||
return materialManager.material(Materials.TRANSFORMED);
|
return instancerManager.factory(StructTypes.MODEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Material<OrientedData> getOrientedMaterial() {
|
protected InstancerFactory<OrientedData> getOrientedFactory() {
|
||||||
return materialManager.material(Materials.ORIENTED);
|
return instancerManager.factory(StructTypes.ORIENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
|
@ -13,8 +13,8 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
||||||
|
|
||||||
public BlockEntityInstanceManager(MaterialManager materialManager) {
|
public BlockEntityInstanceManager(InstancerManager instancerManager) {
|
||||||
super(materialManager);
|
super(instancerManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,7 +24,7 @@ public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractInstance createRaw(BlockEntity obj) {
|
protected AbstractInstance createRaw(BlockEntity obj) {
|
||||||
return InstancedRenderRegistry.createInstance(materialManager, obj);
|
return InstancedRenderRegistry.createInstance(instancerManager, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
|
@ -10,12 +10,12 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
*/
|
*/
|
||||||
public interface BlockEntityInstancingController<T extends BlockEntity> {
|
public interface BlockEntityInstancingController<T extends BlockEntity> {
|
||||||
/**
|
/**
|
||||||
* Given a block entity and a material manager, constructs an instance for the block entity.
|
* Given a block entity and an instancer manager, constructs an instance for the block entity.
|
||||||
* @param materialManager The material manager to use.
|
* @param instancerManager The instancer manager to use.
|
||||||
* @param blockEntity The block entity to construct an instance for.
|
* @param blockEntity The block entity to construct an instance for.
|
||||||
* @return The instance.
|
* @return The instance.
|
||||||
*/
|
*/
|
||||||
BlockEntityInstance<? super T> createInstance(MaterialManager materialManager, T blockEntity);
|
BlockEntityInstance<? super T> createInstance(InstancerManager instancerManager, T blockEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the given block entity should not be rendered normally.
|
* Checks if the given block entity should not be rendered normally.
|
||||||
|
|
|
@ -3,22 +3,22 @@ package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
public class SimpleBlockEntityInstancingController<T extends BlockEntity> implements BlockEntityInstancingController<T> {
|
public class SimpleBlockEntityInstancingController<T extends BlockEntity> implements BlockEntityInstancingController<T> {
|
||||||
protected BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
protected BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||||
protected Predicate<T> skipRender;
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
public SimpleBlockEntityInstancingController(BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
public SimpleBlockEntityInstancingController(BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||||
this.instanceFactory = instanceFactory;
|
this.instanceFactory = instanceFactory;
|
||||||
this.skipRender = skipRender;
|
this.skipRender = skipRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockEntityInstance<? super T> createInstance(MaterialManager materialManager, T blockEntity) {
|
public BlockEntityInstance<? super T> createInstance(InstancerManager instancerManager, T blockEntity) {
|
||||||
return instanceFactory.apply(materialManager, blockEntity);
|
return instanceFactory.apply(instancerManager, blockEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.entity;
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
|
@ -39,8 +39,8 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
||||||
protected final E entity;
|
protected final E entity;
|
||||||
protected final GridAlignedBB bounds;
|
protected final GridAlignedBB bounds;
|
||||||
|
|
||||||
public EntityInstance(MaterialManager materialManager, E entity) {
|
public EntityInstance(InstancerManager instancerManager, E entity) {
|
||||||
super(materialManager, entity.level);
|
super(instancerManager, entity.level);
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
bounds = GridAlignedBB.from(entity.getBoundingBox());
|
bounds = GridAlignedBB.from(entity.getBoundingBox());
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
||||||
*/
|
*/
|
||||||
public Vector3f getInstancePosition() {
|
public Vector3f getInstancePosition() {
|
||||||
Vec3 pos = entity.position();
|
Vec3 pos = entity.position();
|
||||||
Vec3i origin = materialManager.getOriginCoordinate();
|
Vec3i origin = instancerManager.getOriginCoordinate();
|
||||||
return new Vector3f((float) (pos.x - origin.getX()), (float) (pos.y - origin.getY()), (float) (pos.z - origin.getZ()));
|
return new Vector3f((float) (pos.x - origin.getX()), (float) (pos.y - origin.getY()), (float) (pos.z - origin.getZ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
||||||
*/
|
*/
|
||||||
public Vector3f getInstancePosition(float partialTicks) {
|
public Vector3f getInstancePosition(float partialTicks) {
|
||||||
Vec3 pos = entity.position();
|
Vec3 pos = entity.position();
|
||||||
Vec3i origin = materialManager.getOriginCoordinate();
|
Vec3i origin = instancerManager.getOriginCoordinate();
|
||||||
return new Vector3f(
|
return new Vector3f(
|
||||||
(float) (Mth.lerp(partialTicks, entity.xOld, pos.x) - origin.getX()),
|
(float) (Mth.lerp(partialTicks, entity.xOld, pos.x) - origin.getX()),
|
||||||
(float) (Mth.lerp(partialTicks, entity.yOld, pos.y) - origin.getY()),
|
(float) (Mth.lerp(partialTicks, entity.yOld, pos.y) - origin.getY()),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.entity;
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
|
@ -13,8 +13,8 @@ import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
public class EntityInstanceManager extends InstanceManager<Entity> {
|
public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||||
|
|
||||||
public EntityInstanceManager(MaterialManager materialManager) {
|
public EntityInstanceManager(InstancerManager instancerManager) {
|
||||||
super(materialManager);
|
super(instancerManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,7 +24,7 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected AbstractInstance createRaw(Entity obj) {
|
protected AbstractInstance createRaw(Entity obj) {
|
||||||
return InstancedRenderRegistry.createInstance(materialManager, obj);
|
return InstancedRenderRegistry.createInstance(instancerManager, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.backend.instancing.entity;
|
package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
@ -10,12 +10,12 @@ import net.minecraft.world.entity.Entity;
|
||||||
*/
|
*/
|
||||||
public interface EntityInstancingController<T extends Entity> {
|
public interface EntityInstancingController<T extends Entity> {
|
||||||
/**
|
/**
|
||||||
* Given an entity and a material manager, constructs an instance for the entity.
|
* Given an entity and an instancer manager, constructs an instance for the entity.
|
||||||
* @param materialManager The material manager to use.
|
* @param instancerManager The instancer manager to use.
|
||||||
* @param entity The entity to construct an instance for.
|
* @param entity The entity to construct an instance for.
|
||||||
* @return The instance.
|
* @return The instance.
|
||||||
*/
|
*/
|
||||||
EntityInstance<? super T> createInstance(MaterialManager materialManager, T entity);
|
EntityInstance<? super T> createInstance(InstancerManager instancerManager, T entity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the given entity should not render normally.
|
* Checks if the given entity should not render normally.
|
||||||
|
|
|
@ -3,22 +3,22 @@ package com.jozufozu.flywheel.backend.instancing.entity;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
public class SimpleEntityInstancingController<T extends Entity> implements EntityInstancingController<T> {
|
public class SimpleEntityInstancingController<T extends Entity> implements EntityInstancingController<T> {
|
||||||
protected BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory;
|
protected BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory;
|
||||||
protected Predicate<T> skipRender;
|
protected Predicate<T> skipRender;
|
||||||
|
|
||||||
public SimpleEntityInstancingController(BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
public SimpleEntityInstancingController(BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory, Predicate<T> skipRender) {
|
||||||
this.instanceFactory = instanceFactory;
|
this.instanceFactory = instanceFactory;
|
||||||
this.skipRender = skipRender;
|
this.skipRender = skipRender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EntityInstance<? super T> createInstance(MaterialManager materialManager, T entity) {
|
public EntityInstance<? super T> createInstance(InstancerManager instancerManager, T entity) {
|
||||||
return instanceFactory.apply(materialManager, entity);
|
return instanceFactory.apply(instancerManager, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,10 +6,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.api.Instancer;
|
import com.jozufozu.flywheel.api.Instancer;
|
||||||
import com.jozufozu.flywheel.api.Material;
|
import com.jozufozu.flywheel.api.InstancerFactory;
|
||||||
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
import com.jozufozu.flywheel.backend.model.MeshPool;
|
import com.jozufozu.flywheel.backend.model.MeshPool;
|
||||||
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
||||||
|
@ -20,16 +22,17 @@ import net.minecraft.client.renderer.RenderType;
|
||||||
* A collection of Instancers that all have the same format.
|
* A collection of Instancers that all have the same format.
|
||||||
* @param <D>
|
* @param <D>
|
||||||
*/
|
*/
|
||||||
public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
public class GPUInstancerFactory<D extends InstanceData> implements InstancerFactory<D> {
|
||||||
|
|
||||||
protected final Map<ModelSupplier, InstancedModel<D>> models = new HashMap<>();
|
protected final Map<ModelSupplier, InstancedModel<D>> models = new HashMap<>();
|
||||||
protected final Instanced<D> type;
|
protected final Instanced<D> type;
|
||||||
|
|
||||||
protected final List<InstancedModel<D>> uninitialized = new ArrayList<>();
|
protected final List<InstancedModel<D>> uninitialized = new ArrayList<>();
|
||||||
|
|
||||||
protected final Multimap<RenderType, Renderable> renderables = ArrayListMultimap.create();
|
protected final Multimap<RenderType, Material> materials = HashMultimap.create();
|
||||||
|
protected final Multimap<Material, Renderable> renderables = ArrayListMultimap.create();
|
||||||
|
|
||||||
public InstancedMaterial(Instanced<D> type) {
|
public GPUInstancerFactory(Instanced<D> type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +59,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||||
public void delete() {
|
public void delete() {
|
||||||
models.values().forEach(InstancedModel::delete);
|
models.values().forEach(InstancedModel::delete);
|
||||||
models.clear();
|
models.clear();
|
||||||
|
materials.clear();
|
||||||
renderables.clear();
|
renderables.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,10 +75,12 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
||||||
|
|
||||||
public void init(MeshPool allocator) {
|
public void init(MeshPool allocator) {
|
||||||
for (var instanced : uninitialized) {
|
for (var instanced : uninitialized) {
|
||||||
|
|
||||||
var map = instanced.init(allocator);
|
var map = instanced.init(allocator);
|
||||||
|
|
||||||
map.forEach((type, renderable) -> renderables.get(type).add(renderable));
|
map.forEach((material, renderable) -> {
|
||||||
|
materials.put(material.getRenderType(), material);
|
||||||
|
renderables.get(material).add(renderable);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
uninitialized.clear();
|
uninitialized.clear();
|
||||||
}
|
}
|
|
@ -4,26 +4,25 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
|
||||||
import com.jozufozu.flywheel.backend.model.MeshPool;
|
import com.jozufozu.flywheel.backend.model.MeshPool;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
||||||
import com.jozufozu.flywheel.util.Pair;
|
import com.jozufozu.flywheel.util.Pair;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
|
|
||||||
public class InstancedModel<D extends InstanceData> {
|
public class InstancedModel<D extends InstanceData> {
|
||||||
|
|
||||||
final GPUInstancer<D> instancer;
|
final GPUInstancer<D> instancer;
|
||||||
final ModelSupplier model;
|
final ModelSupplier model;
|
||||||
private Map<RenderType, Layer> layers;
|
private Map<Material, Layer> layers;
|
||||||
|
|
||||||
public InstancedModel(GPUInstancer<D> instancer, ModelSupplier model) {
|
public InstancedModel(GPUInstancer<D> instancer, ModelSupplier model) {
|
||||||
this.instancer = instancer;
|
this.instancer = instancer;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<RenderType, ? extends Renderable> init(MeshPool allocator) {
|
public Map<Material, ? extends Renderable> init(MeshPool allocator) {
|
||||||
instancer.init();
|
instancer.init();
|
||||||
|
|
||||||
layers = model.get()
|
layers = model.get()
|
||||||
|
@ -38,12 +37,12 @@ public class InstancedModel<D extends InstanceData> {
|
||||||
|
|
||||||
private class Layer implements Renderable {
|
private class Layer implements Renderable {
|
||||||
|
|
||||||
final RenderType type;
|
final Material material;
|
||||||
MeshPool.BufferedMesh bufferedMesh;
|
MeshPool.BufferedMesh bufferedMesh;
|
||||||
GlVertexArray vao;
|
GlVertexArray vao;
|
||||||
|
|
||||||
private Layer(MeshPool allocator, RenderType type, Mesh mesh) {
|
private Layer(MeshPool allocator, Material material, Mesh mesh) {
|
||||||
this.type = type;
|
this.material = material;
|
||||||
vao = new GlVertexArray();
|
vao = new GlVertexArray();
|
||||||
bufferedMesh = allocator.alloc(mesh, vao);
|
bufferedMesh = allocator.alloc(mesh, vao);
|
||||||
instancer.attributeBaseIndex = bufferedMesh.getAttributeCount();
|
instancer.attributeBaseIndex = bufferedMesh.getAttributeCount();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Set;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||||
|
@ -44,7 +45,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
protected final ProgramCompiler<P> context;
|
protected final ProgramCompiler<P> context;
|
||||||
private MeshPool allocator;
|
private MeshPool allocator;
|
||||||
|
|
||||||
protected final Map<Instanced<? extends InstanceData>, InstancedMaterial<?>> materials = new HashMap<>();
|
protected final Map<Instanced<? extends InstanceData>, GPUInstancerFactory<?>> factories = new HashMap<>();
|
||||||
|
|
||||||
protected final Set<RenderType> toRender = new HashSet<>();
|
protected final Set<RenderType> toRender = new HashSet<>();
|
||||||
|
|
||||||
|
@ -61,9 +62,9 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public <D extends InstanceData> InstancedMaterial<D> material(StructType<D> type) {
|
public <D extends InstanceData> GPUInstancerFactory<D> factory(StructType<D> type) {
|
||||||
if (type instanceof Instanced<D> instanced) {
|
if (type instanceof Instanced<D> instanced) {
|
||||||
return (InstancedMaterial<D>) materials.computeIfAbsent(instanced, InstancedMaterial::new);
|
return (GPUInstancerFactory<D>) factories.computeIfAbsent(instanced, GPUInstancerFactory::new);
|
||||||
} else {
|
} else {
|
||||||
throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing.");
|
throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing.");
|
||||||
}
|
}
|
||||||
|
@ -87,7 +88,6 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type) {
|
public void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type) {
|
||||||
|
|
||||||
var camX = context.camX() - originCoordinate.getX();
|
var camX = context.camX() - originCoordinate.getX();
|
||||||
var camY = context.camY() - originCoordinate.getY();
|
var camY = context.camY() - originCoordinate.getY();
|
||||||
var camZ = context.camZ() - originCoordinate.getZ();
|
var camZ = context.camZ() - originCoordinate.getZ();
|
||||||
|
@ -109,21 +109,23 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
Textures.bindActiveTextures();
|
Textures.bindActiveTextures();
|
||||||
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
||||||
|
|
||||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
for (Map.Entry<Instanced<? extends InstanceData>, GPUInstancerFactory<?>> entry : factories.entrySet()) {
|
||||||
InstancedMaterial<?> material = entry.getValue();
|
Instanced<? extends InstanceData> instanceType = entry.getKey();
|
||||||
|
GPUInstancerFactory<?> factory = entry.getValue();
|
||||||
|
|
||||||
var toRender = material.renderables.get(type);
|
var materials = factory.materials.get(type);
|
||||||
toRender.removeIf(Renderable::shouldRemove);
|
for (Material material : materials) {
|
||||||
|
var toRender = factory.renderables.get(material);
|
||||||
|
toRender.removeIf(Renderable::shouldRemove);
|
||||||
|
|
||||||
if (!toRender.isEmpty()) {
|
if (!toRender.isEmpty()) {
|
||||||
Instanced<? extends InstanceData> instanceType = entry.getKey();
|
setup(instanceType, material, coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
||||||
|
|
||||||
setup(instanceType, coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
instanceCount += factory.getInstanceCount();
|
||||||
|
vertexCount += factory.getVertexCount();
|
||||||
|
|
||||||
instanceCount += material.getInstanceCount();
|
toRender.forEach(Renderable::render);
|
||||||
vertexCount += material.getVertexCount();
|
}
|
||||||
|
|
||||||
toRender.forEach(Renderable::render);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +147,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
return coreShaderInfo;
|
return coreShaderInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected P setup(Instanced<?> instanceType, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
|
protected P setup(Instanced<?> instanceType, Material material, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) {
|
||||||
float alphaDiscard = coreShaderInfo.alphaDiscard();
|
float alphaDiscard = coreShaderInfo.alphaDiscard();
|
||||||
if (alphaDiscard == 0) {
|
if (alphaDiscard == 0) {
|
||||||
alphaDiscard = 0.0001f;
|
alphaDiscard = 0.0001f;
|
||||||
|
@ -153,7 +155,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
alphaDiscard = 0;
|
alphaDiscard = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
P program = context.getProgram(new ProgramContext(Formats.POS_TEX_NORMAL, instanceType.getInstanceShader(), alphaDiscard, coreShaderInfo.fogType(), GameStateRegistry.takeSnapshot()));
|
P program = context.getProgram(new ProgramContext(Formats.POS_TEX_NORMAL, instanceType.getInstanceShader(), material.getVertexShader(), material.getFragmentShader(), alphaDiscard, coreShaderInfo.fogType(), GameStateRegistry.takeSnapshot()));
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
||||||
|
@ -162,15 +164,15 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearAll() {
|
public void clearAll() {
|
||||||
materials.values().forEach(InstancedMaterial::clear);
|
factories.values().forEach(GPUInstancerFactory::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
materials.values()
|
factories.values()
|
||||||
.forEach(InstancedMaterial::delete);
|
.forEach(GPUInstancerFactory::delete);
|
||||||
|
|
||||||
materials.clear();
|
factories.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -193,10 +195,10 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
|
|
||||||
MeshPool allocator = getModelAllocator();
|
MeshPool allocator = getModelAllocator();
|
||||||
|
|
||||||
for (InstancedMaterial<?> material : materials.values()) {
|
for (GPUInstancerFactory<?> factory : factories.values()) {
|
||||||
material.init(allocator);
|
factory.init(allocator);
|
||||||
|
|
||||||
toRender.addAll(material.renderables.keySet());
|
toRender.addAll(factory.materials.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator.flush();
|
allocator.flush();
|
||||||
|
@ -221,7 +223,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
private void shiftListeners(int cX, int cY, int cZ) {
|
private void shiftListeners(int cX, int cY, int cZ) {
|
||||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||||
|
|
||||||
materials.values().forEach(InstancedMaterial::clear);
|
factories.values().forEach(GPUInstancerFactory::clear);
|
||||||
|
|
||||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import java.util.Map;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
|
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
||||||
import com.jozufozu.flywheel.util.Lazy;
|
import com.jozufozu.flywheel.util.Lazy;
|
||||||
|
@ -13,31 +15,28 @@ import com.jozufozu.flywheel.util.NonNullSupplier;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
||||||
public class BasicModelSupplier implements ModelSupplier {
|
public class BasicModelSupplier implements ModelSupplier {
|
||||||
|
private static final Material DEFAULT_MATERIAL = new Material(RenderType.solid(), () -> MaterialShaders.DEFAULT_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT);
|
||||||
|
|
||||||
private RenderType renderType;
|
private Material material;
|
||||||
private final Lazy<Mesh> supplier;
|
private final Lazy<Mesh> supplier;
|
||||||
|
|
||||||
public BasicModelSupplier(NonNullSupplier<Mesh> supplier) {
|
public BasicModelSupplier(NonNullSupplier<Mesh> supplier) {
|
||||||
this(supplier, RenderType.solid());
|
this(supplier, DEFAULT_MATERIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicModelSupplier(NonNullSupplier<Mesh> supplier, RenderType renderType) {
|
public BasicModelSupplier(NonNullSupplier<Mesh> supplier, Material material) {
|
||||||
this.supplier = Lazy.of(supplier);
|
this.supplier = Lazy.of(supplier);
|
||||||
this.renderType = renderType;
|
this.material = material;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicModelSupplier setCutout() {
|
public BasicModelSupplier setMaterial(@NotNull Material material) {
|
||||||
return setRenderType(RenderType.cutoutMipped());
|
this.material = material;
|
||||||
}
|
|
||||||
|
|
||||||
public BasicModelSupplier setRenderType(@NotNull RenderType renderType) {
|
|
||||||
this.renderType = renderType;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<RenderType, Mesh> get() {
|
public Map<Material, Mesh> get() {
|
||||||
return ImmutableMap.of(renderType, supplier.get());
|
return ImmutableMap.of(material, supplier.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getVertexCount() {
|
public int getVertexCount() {
|
||||||
|
@ -47,7 +46,7 @@ public class BasicModelSupplier implements ModelSupplier {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ModelSupplier{" + supplier.map(Mesh::name)
|
return "BasicModelSupplier{" + supplier.map(Mesh::name)
|
||||||
.orElse("Uninitialized") + '}';
|
.orElse("Uninitialized") + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ public class Contexts {
|
||||||
FileResolution crumblingVertex = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".vert"));
|
FileResolution crumblingVertex = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".vert"));
|
||||||
FileResolution crumblingFragment = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".frag"));
|
FileResolution crumblingFragment = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".frag"));
|
||||||
|
|
||||||
WORLD = ProgramCompiler.create(WorldProgram::new, Templates.INSTANCING, Templates.FRAGMENT, worldVertex, worldFragment);
|
WORLD = ProgramCompiler.create(WorldProgram::new, worldVertex, worldFragment);
|
||||||
CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, Templates.INSTANCING, Templates.FRAGMENT, crumblingVertex, crumblingFragment);
|
CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, crumblingVertex, crumblingFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
public static class Names {
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
|
|
||||||
import com.jozufozu.flywheel.core.compile.FragmentTemplateData;
|
|
||||||
import com.jozufozu.flywheel.core.compile.InstancingTemplateData;
|
|
||||||
import com.jozufozu.flywheel.core.compile.OneShotTemplateData;
|
|
||||||
import com.jozufozu.flywheel.core.compile.Template;
|
|
||||||
|
|
||||||
public class Templates {
|
|
||||||
public static final Template<InstancingTemplateData> INSTANCING = new Template<>(GLSLVersion.V330, InstancingTemplateData::new);
|
|
||||||
public static final Template<OneShotTemplateData> ONE_SHOT = new Template<>(GLSLVersion.V150, OneShotTemplateData::new);
|
|
||||||
public static final Template<FragmentTemplateData> FRAGMENT = new Template<>(GLSLVersion.V150, FragmentTemplateData::new);
|
|
||||||
}
|
|
|
@ -1,7 +1,10 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
package com.jozufozu.flywheel.core.compile;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType;
|
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType;
|
||||||
|
@ -9,13 +12,16 @@ import com.jozufozu.flywheel.core.shader.ShaderConstants;
|
||||||
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
||||||
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
import com.jozufozu.flywheel.core.source.ShaderLoadingException;
|
||||||
|
import com.jozufozu.flywheel.core.source.SourceFile;
|
||||||
|
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
||||||
|
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
|
||||||
|
import com.jozufozu.flywheel.core.source.parse.Variable;
|
||||||
|
|
||||||
public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShader> {
|
public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShader> {
|
||||||
private final Template<? extends FragmentData> template;
|
|
||||||
private final FileResolution contextShader;
|
private final FileResolution contextShader;
|
||||||
|
|
||||||
public FragmentCompiler(Template<? extends FragmentData> template, FileResolution contextShader) {
|
public FragmentCompiler(FileResolution contextShader) {
|
||||||
this.template = template;
|
|
||||||
this.contextShader = contextShader;
|
this.contextShader = contextShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,21 +29,77 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
protected GlShader _create(Context key) {
|
protected GlShader _create(Context key) {
|
||||||
StringBuilder finalSource = new StringBuilder();
|
StringBuilder finalSource = new StringBuilder();
|
||||||
|
|
||||||
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.FRAGMENT));
|
finalSource.append(CompileUtil.generateHeader(GLSLVersion.V150, ShaderType.FRAGMENT));
|
||||||
|
|
||||||
key.getShaderConstants().writeInto(finalSource);
|
key.getShaderConstants().writeInto(finalSource);
|
||||||
finalSource.append('\n');
|
finalSource.append('\n');
|
||||||
|
|
||||||
FileIndexImpl index = new FileIndexImpl();
|
FileIndexImpl index = new FileIndexImpl();
|
||||||
|
|
||||||
contextShader.getFile().generateFinalSource(index, finalSource);
|
//
|
||||||
|
|
||||||
FragmentData appliedTemplate = template.apply(contextShader.getFile());
|
SourceFile materialShader = key.materialShader;
|
||||||
finalSource.append(appliedTemplate.generateFooter());
|
|
||||||
|
Optional<ShaderFunction> maybeMaterialFragment = materialShader.findFunction("flw_materialFragment");
|
||||||
|
|
||||||
|
if (maybeMaterialFragment.isEmpty()) {
|
||||||
|
ErrorReporter.generateMissingFunction(materialShader, "flw_materialFragment", "\"flw_materialFragment\" function not defined");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderFunction materialFragment = maybeMaterialFragment.get();
|
||||||
|
ImmutableList<Variable> params = materialFragment.getParameters();
|
||||||
|
|
||||||
|
if (params.size() != 0) {
|
||||||
|
ErrorReporter.generateSpanError(materialFragment.getArgs(), "\"flw_materialFragment\" function must not have any arguments");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
materialShader.generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
SourceFile contextShaderSource = contextShader.getFile();
|
||||||
|
|
||||||
|
Optional<ShaderFunction> maybeContextFragment = contextShaderSource.findFunction("flw_contextFragment");
|
||||||
|
|
||||||
|
if (maybeContextFragment.isEmpty()) {
|
||||||
|
ErrorReporter.generateMissingFunction(contextShaderSource, "flw_contextFragment", "\"flw_contextFragment\" function not defined");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderFunction contextFragment = maybeContextFragment.get();
|
||||||
|
params = contextFragment.getParameters();
|
||||||
|
|
||||||
|
if (params.size() != 0) {
|
||||||
|
ErrorReporter.generateSpanError(contextFragment.getArgs(), "\"flw_contextFragment\" function must not have any arguments");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
contextShaderSource.generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
finalSource.append(generateFooter());
|
||||||
|
|
||||||
return new GlShader(contextShader.getFile().name, ShaderType.FRAGMENT, finalSource.toString());
|
return new GlShader(contextShader.getFile().name, ShaderType.FRAGMENT, finalSource.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String generateFooter() {
|
||||||
|
StringBuilder footer = new StringBuilder();
|
||||||
|
|
||||||
|
footer.append("""
|
||||||
|
void main() {
|
||||||
|
flw_materialFragment();
|
||||||
|
|
||||||
|
flw_contextFragment();
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
);
|
||||||
|
|
||||||
|
return footer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void _destroy(GlShader value) {
|
protected void _destroy(GlShader value) {
|
||||||
value.delete();
|
value.delete();
|
||||||
|
@ -48,9 +110,9 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
*/
|
*/
|
||||||
public static final class Context {
|
public static final class Context {
|
||||||
/**
|
/**
|
||||||
* The shader constants to apply.
|
* The fragment material shader source.
|
||||||
*/
|
*/
|
||||||
private final StateSnapshot ctx;
|
private final SourceFile materialShader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alpha threshold below which fragments are discarded.
|
* Alpha threshold below which fragments are discarded.
|
||||||
|
@ -62,7 +124,13 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
*/
|
*/
|
||||||
private final FogType fogType;
|
private final FogType fogType;
|
||||||
|
|
||||||
public Context(float alphaDiscard, FogType fogType, StateSnapshot ctx) {
|
/**
|
||||||
|
* The shader constants to apply.
|
||||||
|
*/
|
||||||
|
private final StateSnapshot ctx;
|
||||||
|
|
||||||
|
public Context(SourceFile materialShader, float alphaDiscard, FogType fogType, StateSnapshot ctx) {
|
||||||
|
this.materialShader = materialShader;
|
||||||
this.alphaDiscard = alphaDiscard;
|
this.alphaDiscard = alphaDiscard;
|
||||||
this.fogType = fogType;
|
this.fogType = fogType;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
@ -84,18 +152,17 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
||||||
if (obj == this) return true;
|
if (obj == this) return true;
|
||||||
if (obj == null || obj.getClass() != this.getClass()) return false;
|
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||||
var that = (Context) obj;
|
var that = (Context) obj;
|
||||||
return Objects.equals(this.ctx, that.ctx) && Float.floatToIntBits(this.alphaDiscard) == Float.floatToIntBits(that.alphaDiscard) && fogType == that.fogType;
|
return materialShader == that.materialShader && Objects.equals(this.ctx, that.ctx) && Float.floatToIntBits(this.alphaDiscard) == Float.floatToIntBits(that.alphaDiscard) && fogType == that.fogType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(alphaDiscard, fogType, ctx);
|
return Objects.hash(materialShader, alphaDiscard, fogType, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Context[" + "alphaDiscard=" + alphaDiscard + ", " + "fogType=" + fogType + ", " + "ctx=" + ctx + ']';
|
return "Context[" + "materialShader=" + materialShader + ", " + "alphaDiscard=" + alphaDiscard + ", " + "fogType=" + fogType + ", " + "ctx=" + ctx + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
|
||||||
|
|
||||||
public interface FragmentData {
|
|
||||||
/**
|
|
||||||
* Generate the necessary glue code here.
|
|
||||||
*/
|
|
||||||
String generateFooter();
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.jozufozu.flywheel.core.source.ShaderLoadingException;
|
|
||||||
import com.jozufozu.flywheel.core.source.SourceFile;
|
|
||||||
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.Variable;
|
|
||||||
|
|
||||||
public class FragmentTemplateData implements FragmentData {
|
|
||||||
public final SourceFile file;
|
|
||||||
public final ShaderFunction contextFragment;
|
|
||||||
|
|
||||||
public FragmentTemplateData(SourceFile file) {
|
|
||||||
this.file = file;
|
|
||||||
|
|
||||||
Optional<ShaderFunction> maybeContextFragment = file.findFunction("flw_contextFragment");
|
|
||||||
|
|
||||||
if (maybeContextFragment.isEmpty()) {
|
|
||||||
ErrorReporter.generateMissingFunction(file, "flw_contextFragment", "\"flw_contextFragment\" function not defined");
|
|
||||||
throw new ShaderLoadingException();
|
|
||||||
}
|
|
||||||
|
|
||||||
contextFragment = maybeContextFragment.get();
|
|
||||||
ImmutableList<Variable> params = contextFragment.getParameters();
|
|
||||||
|
|
||||||
if (params.size() != 0) {
|
|
||||||
ErrorReporter.generateSpanError(contextFragment.getArgs(), "\"flw_contextFragment\" function must not have any arguments");
|
|
||||||
throw new ShaderLoadingException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateFooter() {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
builder.append("""
|
|
||||||
void main() {
|
|
||||||
flw_contextFragment();
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
);
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.core.source.FileIndex;
|
|
||||||
import com.jozufozu.flywheel.core.source.ShaderLoadingException;
|
|
||||||
import com.jozufozu.flywheel.core.source.SourceFile;
|
|
||||||
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.ShaderStruct;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.StructField;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.Variable;
|
|
||||||
import com.jozufozu.flywheel.core.source.span.Span;
|
|
||||||
|
|
||||||
public class InstancingTemplateData implements VertexData {
|
|
||||||
public final SourceFile file;
|
|
||||||
public final ShaderFunction instanceVertex;
|
|
||||||
public final Span instanceName;
|
|
||||||
public final ShaderStruct instance;
|
|
||||||
|
|
||||||
public InstancingTemplateData(SourceFile file) {
|
|
||||||
this.file = file;
|
|
||||||
|
|
||||||
Optional<ShaderFunction> maybeInstanceVertex = file.findFunction("flw_instanceVertex");
|
|
||||||
|
|
||||||
if (maybeInstanceVertex.isEmpty()) {
|
|
||||||
ErrorReporter.generateMissingFunction(file, "flw_instanceVertex", "\"flw_instanceVertex\" function not defined");
|
|
||||||
throw new ShaderLoadingException();
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceVertex = maybeInstanceVertex.get();
|
|
||||||
ImmutableList<Variable> params = instanceVertex.getParameters();
|
|
||||||
|
|
||||||
if (params.size() != 1) {
|
|
||||||
ErrorReporter.generateSpanError(instanceVertex.getArgs(), "\"flw_contextFragment\" function must have exactly 1 argument");
|
|
||||||
throw new ShaderLoadingException();
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceName = params.get(0).type;
|
|
||||||
Optional<ShaderStruct> maybeInstance = file.findStruct(instanceName);
|
|
||||||
|
|
||||||
if (maybeInstance.isEmpty()) {
|
|
||||||
ErrorReporter.generateMissingStruct(file, instanceName, "struct not defined");
|
|
||||||
throw new ShaderLoadingException();
|
|
||||||
}
|
|
||||||
|
|
||||||
instance = maybeInstance.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateFooter(FileIndex shader, VertexType vertexType) {
|
|
||||||
ImmutableList<StructField> fields = instance.getFields();
|
|
||||||
|
|
||||||
int attributeBinding = vertexType.getLayout()
|
|
||||||
.getAttributeCount();
|
|
||||||
|
|
||||||
StringBuilder template = new StringBuilder();
|
|
||||||
|
|
||||||
for (StructField field : fields) {
|
|
||||||
template.append("layout(location = ")
|
|
||||||
.append(attributeBinding)
|
|
||||||
.append(") in")
|
|
||||||
.append(' ')
|
|
||||||
.append(field.type)
|
|
||||||
.append(' ')
|
|
||||||
.append("_flw_a_i_")
|
|
||||||
.append(field.name)
|
|
||||||
.append(";\n");
|
|
||||||
attributeBinding += CompileUtil.getAttributeCount(field.type);
|
|
||||||
}
|
|
||||||
template.append('\n');
|
|
||||||
|
|
||||||
template.append(String.format("""
|
|
||||||
void main() {
|
|
||||||
flw_layoutVertex();
|
|
||||||
|
|
||||||
%s instance;
|
|
||||||
%s
|
|
||||||
flw_instanceVertex(instance);
|
|
||||||
|
|
||||||
flw_contextVertex();
|
|
||||||
}
|
|
||||||
""",
|
|
||||||
instanceName,
|
|
||||||
assignFields(instance, "instance.", "_flw_a_i_")
|
|
||||||
));
|
|
||||||
|
|
||||||
return template.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static StringBuilder assignFields(ShaderStruct struct, String prefix1, String prefix2) {
|
|
||||||
ImmutableList<StructField> fields = struct.getFields();
|
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
for (StructField field : fields) {
|
|
||||||
builder.append(prefix1)
|
|
||||||
.append(field.name)
|
|
||||||
.append(" = ")
|
|
||||||
.append(prefix2)
|
|
||||||
.append(field.name)
|
|
||||||
.append(";\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.core.source.FileIndex;
|
|
||||||
import com.jozufozu.flywheel.core.source.ShaderLoadingException;
|
|
||||||
import com.jozufozu.flywheel.core.source.SourceFile;
|
|
||||||
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
|
|
||||||
import com.jozufozu.flywheel.core.source.parse.Variable;
|
|
||||||
|
|
||||||
public class OneShotTemplateData implements VertexData {
|
|
||||||
|
|
||||||
public final SourceFile file;
|
|
||||||
public final ShaderFunction vertexMain;
|
|
||||||
|
|
||||||
public OneShotTemplateData(SourceFile file) {
|
|
||||||
this.file = file;
|
|
||||||
|
|
||||||
Optional<ShaderFunction> maybeVertexMain = file.findFunction("vertex");
|
|
||||||
|
|
||||||
if (maybeVertexMain.isEmpty()) {
|
|
||||||
ErrorReporter.generateFileError(file, "could not find \"vertex\" function");
|
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
vertexMain = maybeVertexMain.get();
|
|
||||||
ImmutableList<Variable> vertexParameters = vertexMain.getParameters();
|
|
||||||
|
|
||||||
if (vertexParameters.size() != 1) {
|
|
||||||
ErrorReporter.generateSpanError(vertexMain.getArgs(), "a basic model requires vertex function to have one argument");
|
|
||||||
throw new RuntimeException();
|
|
||||||
}
|
|
||||||
|
|
||||||
Variable vertexParam = vertexMain.getParameters().get(0);
|
|
||||||
|
|
||||||
boolean namedVertex = vertexParam.type
|
|
||||||
.toString()
|
|
||||||
.equals("Vertex");
|
|
||||||
|
|
||||||
if (!(namedVertex && vertexParam.qualifier == Variable.Qualifier.INOUT)) {
|
|
||||||
ErrorReporter.generateSpanError(vertexParam.qualifierSpan, "first parameter must be inout Vertex");
|
|
||||||
throw new ShaderLoadingException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateFooter(FileIndex file, VertexType vertexType) {
|
|
||||||
return """
|
|
||||||
out vec4 v2f_color;
|
|
||||||
out vec2 v2f_texCoords;
|
|
||||||
out vec2 v2f_light;
|
|
||||||
out float v2f_diffuse;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
Vertex v = FLWCreateVertex();
|
|
||||||
vertex(v);
|
|
||||||
gl_Position = FLWVertex(v);
|
|
||||||
v.normal = normalize(v.normal);
|
|
||||||
|
|
||||||
v2f_color = v.color;
|
|
||||||
v2f_texCoords = v.texCoords;
|
|
||||||
v2f_light = v.light;
|
|
||||||
v2f_diffuse = FLWDiffuse(v.normal);
|
|
||||||
#if defined(DEBUG_NORMAL)
|
|
||||||
v2f_color = vec4(v.normal, 1.);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -34,15 +34,13 @@ public class ProgramCompiler<P extends GlProgram> extends Memoizer<ProgramContex
|
||||||
/**
|
/**
|
||||||
* Creates a program compiler using provided templates and headers.
|
* Creates a program compiler using provided templates and headers.
|
||||||
* @param factory A factory to add meaning to compiled programs.
|
* @param factory A factory to add meaning to compiled programs.
|
||||||
* @param vertexTemplate The vertex template to use.
|
|
||||||
* @param fragmentTemplate The fragment template to use.
|
|
||||||
* @param vertexContextShader The context shader to use when compiling vertex shaders.
|
* @param vertexContextShader The context shader to use when compiling vertex shaders.
|
||||||
* @param fragmentContextShader The context shader to use when compiling fragment shaders.
|
* @param fragmentContextShader The context shader to use when compiling fragment shaders.
|
||||||
* @param <P> The type of program to compile.
|
* @param <P> The type of program to compile.
|
||||||
* @return A program compiler.
|
* @return A program compiler.
|
||||||
*/
|
*/
|
||||||
public static <V extends VertexData, F extends FragmentData, P extends GlProgram> ProgramCompiler<P> create(GlProgram.Factory<P> factory, Template<V> vertexTemplate, Template<F> fragmentTemplate, FileResolution vertexContextShader, FileResolution fragmentContextShader) {
|
public static <P extends GlProgram> ProgramCompiler<P> create(GlProgram.Factory<P> factory, FileResolution vertexContextShader, FileResolution fragmentContextShader) {
|
||||||
return new ProgramCompiler<>(factory, new VertexCompiler(vertexTemplate, vertexContextShader), new FragmentCompiler(fragmentTemplate, fragmentContextShader));
|
return new ProgramCompiler<>(factory, new VertexCompiler(vertexContextShader), new FragmentCompiler(fragmentContextShader));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,8 +63,8 @@ public class ProgramCompiler<P extends GlProgram> extends Memoizer<ProgramContex
|
||||||
@Override
|
@Override
|
||||||
protected P _create(ProgramContext ctx) {
|
protected P _create(ProgramContext ctx) {
|
||||||
return new ProgramAssembler(ctx.instanceShader.getFileLoc())
|
return new ProgramAssembler(ctx.instanceShader.getFileLoc())
|
||||||
.attachShader(vertexCompiler.get(new VertexCompiler.Context(ctx.vertexType, ctx.instanceShader.getFile(), ctx.ctx)))
|
.attachShader(vertexCompiler.get(new VertexCompiler.Context(ctx.vertexType, ctx.instanceShader.getFile(), ctx.vertexMaterialShader.getFile(), ctx.ctx)))
|
||||||
.attachShader(fragmentCompiler.get(new FragmentCompiler.Context(ctx.alphaDiscard, ctx.fogType, ctx.ctx)))
|
.attachShader(fragmentCompiler.get(new FragmentCompiler.Context(ctx.fragmentMaterialShader.getFile(), ctx.alphaDiscard, ctx.fogType, ctx.ctx)))
|
||||||
.link()
|
.link()
|
||||||
.build(this.factory);
|
.build(this.factory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,20 +14,26 @@ public final class ProgramContext {
|
||||||
|
|
||||||
public final VertexType vertexType;
|
public final VertexType vertexType;
|
||||||
public final FileResolution instanceShader;
|
public final FileResolution instanceShader;
|
||||||
|
public final FileResolution vertexMaterialShader;
|
||||||
|
public final FileResolution fragmentMaterialShader;
|
||||||
public final float alphaDiscard;
|
public final float alphaDiscard;
|
||||||
public final FogType fogType;
|
public final FogType fogType;
|
||||||
public final StateSnapshot ctx;
|
public final StateSnapshot ctx;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param vertexType The vertexType the program should be adapted for.
|
* @param vertexType The vertexType the program should be adapted for.
|
||||||
* @param spec The program to use.
|
* @param instanceShader The instance shader to use.
|
||||||
* @param alphaDiscard Alpha threshold below which pixels are discarded.
|
* @param vertexMaterialShader The vertex material shader to use.
|
||||||
* @param fogType Which type of fog should be applied.
|
* @param fragmentMaterialShader The fragment material shader to use.
|
||||||
* @param ctx A snapshot of the game state.
|
* @param alphaDiscard Alpha threshold below which pixels are discarded.
|
||||||
|
* @param fogType Which type of fog should be applied.
|
||||||
|
* @param ctx A snapshot of the game state.
|
||||||
*/
|
*/
|
||||||
public ProgramContext(VertexType vertexType, FileResolution instanceShader, float alphaDiscard, FogType fogType, StateSnapshot ctx) {
|
public ProgramContext(VertexType vertexType, FileResolution instanceShader, FileResolution vertexMaterialShader, FileResolution fragmentMaterialShader, float alphaDiscard, FogType fogType, StateSnapshot ctx) {
|
||||||
this.vertexType = vertexType;
|
this.vertexType = vertexType;
|
||||||
this.instanceShader = instanceShader;
|
this.instanceShader = instanceShader;
|
||||||
|
this.vertexMaterialShader = vertexMaterialShader;
|
||||||
|
this.fragmentMaterialShader = fragmentMaterialShader;
|
||||||
this.alphaDiscard = alphaDiscard;
|
this.alphaDiscard = alphaDiscard;
|
||||||
this.fogType = fogType;
|
this.fogType = fogType;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
@ -38,16 +44,16 @@ public final class ProgramContext {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
var that = (ProgramContext) o;
|
var that = (ProgramContext) o;
|
||||||
return instanceShader == that.instanceShader && vertexType == that.vertexType && ctx.equals(that.ctx) && Float.floatToIntBits(alphaDiscard) == Float.floatToIntBits(that.alphaDiscard) && fogType == that.fogType;
|
return vertexType == that.vertexType && instanceShader == that.instanceShader && vertexMaterialShader == that.vertexMaterialShader && fragmentMaterialShader == that.fragmentMaterialShader && ctx.equals(that.ctx) && Float.floatToIntBits(alphaDiscard) == Float.floatToIntBits(that.alphaDiscard) && fogType == that.fogType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(vertexType, instanceShader, alphaDiscard, fogType, ctx);
|
return Objects.hash(vertexType, instanceShader, vertexMaterialShader, fragmentMaterialShader, alphaDiscard, fogType, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "ProgramContext{" + "vertexType=" + vertexType + ", instanceShader=" + instanceShader + ", alphaDiscard=" + alphaDiscard + ", fogType=" + fogType + ", ctx=" + ctx + '}';
|
return "ProgramContext{" + "vertexType=" + vertexType + ", instanceShader=" + instanceShader + ", vertexMaterialShader=" + vertexMaterialShader + ", fragmentMaterialShader=" + fragmentMaterialShader + ", alphaDiscard=" + alphaDiscard + ", fogType=" + fogType + ", ctx=" + ctx + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
|
|
||||||
import com.jozufozu.flywheel.core.source.SourceFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class that generates glsl glue code given a SourceFile.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Shader files are written somewhat abstractly. Subclasses of Template handle those abstractions, using SourceFile
|
|
||||||
* metadata to generate shader code that OpenGL can use to call into our shader programs.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
public class Template<T> extends Memoizer<SourceFile, T> {
|
|
||||||
|
|
||||||
private final Function<SourceFile, T> reader;
|
|
||||||
private final GLSLVersion glslVersion;
|
|
||||||
|
|
||||||
public Template(GLSLVersion glslVersion, Function<SourceFile, T> reader) {
|
|
||||||
this.reader = reader;
|
|
||||||
this.glslVersion = glslVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify that the given SourceFile is valid for this Template and return the metadata.
|
|
||||||
* @param file The SourceFile to apply this Template to.
|
|
||||||
* @return The applied template metadata.
|
|
||||||
*/
|
|
||||||
public T apply(SourceFile file) {
|
|
||||||
// lazily read files, cache results
|
|
||||||
return super.get(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The GLSL version this template requires.
|
|
||||||
*/
|
|
||||||
public GLSLVersion getVersion() {
|
|
||||||
return glslVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected T _create(SourceFile key) {
|
|
||||||
return reader.apply(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _destroy(T value) {
|
|
||||||
// noop
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +1,29 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
package com.jozufozu.flywheel.core.compile;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
||||||
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
import com.jozufozu.flywheel.core.source.ShaderLoadingException;
|
||||||
import com.jozufozu.flywheel.core.source.SourceFile;
|
import com.jozufozu.flywheel.core.source.SourceFile;
|
||||||
|
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
|
||||||
|
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
|
||||||
|
import com.jozufozu.flywheel.core.source.parse.ShaderStruct;
|
||||||
|
import com.jozufozu.flywheel.core.source.parse.StructField;
|
||||||
|
import com.jozufozu.flywheel.core.source.parse.Variable;
|
||||||
|
import com.jozufozu.flywheel.core.source.span.Span;
|
||||||
|
|
||||||
public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
private final Template<? extends VertexData> template;
|
|
||||||
private final FileResolution contextShader;
|
private final FileResolution contextShader;
|
||||||
|
|
||||||
public VertexCompiler(Template<? extends VertexData> template, FileResolution contextShader) {
|
public VertexCompiler(FileResolution contextShader) {
|
||||||
this.template = template;
|
|
||||||
this.contextShader = contextShader;
|
this.contextShader = contextShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,24 +31,171 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
protected GlShader _create(Context key) {
|
protected GlShader _create(Context key) {
|
||||||
StringBuilder finalSource = new StringBuilder();
|
StringBuilder finalSource = new StringBuilder();
|
||||||
|
|
||||||
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.VERTEX));
|
finalSource.append(CompileUtil.generateHeader(GLSLVersion.V330, ShaderType.VERTEX));
|
||||||
|
|
||||||
key.ctx.getShaderConstants().writeInto(finalSource);
|
key.ctx.getShaderConstants().writeInto(finalSource);
|
||||||
finalSource.append('\n');
|
finalSource.append('\n');
|
||||||
|
|
||||||
FileIndexImpl index = new FileIndexImpl();
|
FileIndexImpl index = new FileIndexImpl();
|
||||||
|
|
||||||
FileResolution layoutShader = key.vertexType.getLayoutShader();
|
//
|
||||||
layoutShader.getFile().generateFinalSource(index, finalSource);
|
|
||||||
|
|
||||||
contextShader.getFile().generateFinalSource(index, finalSource);
|
SourceFile layoutShader = key.vertexType.getLayoutShader().getFile();
|
||||||
|
|
||||||
key.instanceShader.generateFinalSource(index, finalSource);
|
Optional<ShaderFunction> maybeLayoutVertex = layoutShader.findFunction("flw_layoutVertex");
|
||||||
|
|
||||||
VertexData appliedTemplate = template.apply(key.instanceShader);
|
if (maybeLayoutVertex.isEmpty()) {
|
||||||
finalSource.append(appliedTemplate.generateFooter(index, key.vertexType));
|
ErrorReporter.generateMissingFunction(layoutShader, "flw_layoutVertex", "\"flw_layoutVertex\" function not defined");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
return new GlShader(key.instanceShader.name, ShaderType.VERTEX, finalSource.toString());
|
ShaderFunction layoutVertex = maybeLayoutVertex.get();
|
||||||
|
ImmutableList<Variable> params = layoutVertex.getParameters();
|
||||||
|
|
||||||
|
if (params.size() != 0) {
|
||||||
|
ErrorReporter.generateSpanError(layoutVertex.getArgs(), "\"flw_layoutVertex\" function must not have any arguments");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
layoutShader.generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
SourceFile instanceShader = key.instanceShader;
|
||||||
|
|
||||||
|
Optional<ShaderFunction> maybeInstanceVertex = instanceShader.findFunction("flw_instanceVertex");
|
||||||
|
|
||||||
|
if (maybeInstanceVertex.isEmpty()) {
|
||||||
|
ErrorReporter.generateMissingFunction(instanceShader, "flw_instanceVertex", "\"flw_instanceVertex\" function not defined");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderFunction instanceVertex = maybeInstanceVertex.get();
|
||||||
|
params = instanceVertex.getParameters();
|
||||||
|
|
||||||
|
if (params.size() != 1) {
|
||||||
|
ErrorReporter.generateSpanError(instanceVertex.getArgs(), "\"flw_instanceVertex\" function must have exactly 1 argument");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
Span instanceName = params.get(0).type;
|
||||||
|
Optional<ShaderStruct> maybeInstance = instanceShader.findStruct(instanceName);
|
||||||
|
|
||||||
|
if (maybeInstance.isEmpty()) {
|
||||||
|
ErrorReporter.generateMissingStruct(instanceShader, instanceName, "instance struct not defined");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderStruct instance = maybeInstance.get();
|
||||||
|
|
||||||
|
instanceShader.generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
SourceFile materialShader = key.materialShader;
|
||||||
|
|
||||||
|
Optional<ShaderFunction> maybeMaterialVertex = materialShader.findFunction("flw_materialVertex");
|
||||||
|
|
||||||
|
if (maybeMaterialVertex.isEmpty()) {
|
||||||
|
ErrorReporter.generateMissingFunction(materialShader, "flw_materialVertex", "\"flw_materialVertex\" function not defined");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderFunction materialVertex = maybeMaterialVertex.get();
|
||||||
|
params = materialVertex.getParameters();
|
||||||
|
|
||||||
|
if (params.size() != 0) {
|
||||||
|
ErrorReporter.generateSpanError(materialVertex.getArgs(), "\"flw_materialVertex\" function must not have any arguments");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
materialShader.generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
SourceFile contextShaderSource = contextShader.getFile();
|
||||||
|
|
||||||
|
Optional<ShaderFunction> maybeContextVertex = contextShaderSource.findFunction("flw_contextVertex");
|
||||||
|
|
||||||
|
if (maybeContextVertex.isEmpty()) {
|
||||||
|
ErrorReporter.generateMissingFunction(contextShaderSource, "flw_contextVertex", "\"flw_contextVertex\" function not defined");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderFunction contextVertex = maybeContextVertex.get();
|
||||||
|
params = contextVertex.getParameters();
|
||||||
|
|
||||||
|
if (params.size() != 0) {
|
||||||
|
ErrorReporter.generateSpanError(contextVertex.getArgs(), "\"flw_contextVertex\" function must not have any arguments");
|
||||||
|
throw new ShaderLoadingException();
|
||||||
|
}
|
||||||
|
|
||||||
|
contextShaderSource.generateFinalSource(index, finalSource);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
finalSource.append(generateFooter(key.vertexType, instance));
|
||||||
|
|
||||||
|
return new GlShader(instanceShader.name, ShaderType.VERTEX, finalSource.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String generateFooter(VertexType vertexType, ShaderStruct instance) {
|
||||||
|
ImmutableList<StructField> fields = instance.getFields();
|
||||||
|
|
||||||
|
int attributeBinding = vertexType.getLayout()
|
||||||
|
.getAttributeCount();
|
||||||
|
|
||||||
|
StringBuilder footer = new StringBuilder();
|
||||||
|
|
||||||
|
for (StructField field : fields) {
|
||||||
|
footer.append("layout(location = ")
|
||||||
|
.append(attributeBinding)
|
||||||
|
.append(") in")
|
||||||
|
.append(' ')
|
||||||
|
.append(field.type)
|
||||||
|
.append(' ')
|
||||||
|
.append("_flw_a_i_")
|
||||||
|
.append(field.name)
|
||||||
|
.append(";\n");
|
||||||
|
attributeBinding += CompileUtil.getAttributeCount(field.type);
|
||||||
|
}
|
||||||
|
footer.append('\n');
|
||||||
|
|
||||||
|
footer.append(String.format("""
|
||||||
|
void main() {
|
||||||
|
flw_layoutVertex();
|
||||||
|
|
||||||
|
%s instance;
|
||||||
|
%s
|
||||||
|
flw_instanceVertex(instance);
|
||||||
|
|
||||||
|
flw_materialVertex();
|
||||||
|
|
||||||
|
flw_contextVertex();
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
instance.name,
|
||||||
|
assignFields(instance, "instance.", "_flw_a_i_")
|
||||||
|
));
|
||||||
|
|
||||||
|
return footer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static StringBuilder assignFields(ShaderStruct struct, String prefix1, String prefix2) {
|
||||||
|
ImmutableList<StructField> fields = struct.getFields();
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
for (StructField field : fields) {
|
||||||
|
builder.append(prefix1)
|
||||||
|
.append(field.name)
|
||||||
|
.append(" = ")
|
||||||
|
.append(prefix2)
|
||||||
|
.append(field.name)
|
||||||
|
.append(";\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,14 +214,20 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
*/
|
*/
|
||||||
private final SourceFile instanceShader;
|
private final SourceFile instanceShader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The vertex material shader source.
|
||||||
|
*/
|
||||||
|
private final SourceFile materialShader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The shader constants to apply.
|
* The shader constants to apply.
|
||||||
*/
|
*/
|
||||||
private final StateSnapshot ctx;
|
private final StateSnapshot ctx;
|
||||||
|
|
||||||
public Context(VertexType vertexType, SourceFile instanceShader, StateSnapshot ctx) {
|
public Context(VertexType vertexType, SourceFile instanceShader, SourceFile materialShader, StateSnapshot ctx) {
|
||||||
this.vertexType = vertexType;
|
this.vertexType = vertexType;
|
||||||
this.instanceShader = instanceShader;
|
this.instanceShader = instanceShader;
|
||||||
|
this.materialShader = materialShader;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,12 +236,12 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
var that = (Context) o;
|
var that = (Context) o;
|
||||||
return vertexType == that.vertexType && instanceShader == that.instanceShader && ctx.equals(that.ctx);
|
return vertexType == that.vertexType && instanceShader == that.instanceShader && materialShader == that.materialShader && ctx.equals(that.ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(vertexType, instanceShader, ctx);
|
return Objects.hash(vertexType, instanceShader, materialShader, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.compile;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.core.source.FileIndex;
|
|
||||||
|
|
||||||
public interface VertexData {
|
|
||||||
/**
|
|
||||||
* Generate the necessary glue code here.
|
|
||||||
* @param file The SourceFile with user written code.
|
|
||||||
*/
|
|
||||||
String generateFooter(FileIndex file, VertexType vertexType);
|
|
||||||
}
|
|
|
@ -1,13 +1,13 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
|
|
||||||
public class CrumblingInstanceManager extends BlockEntityInstanceManager {
|
public class CrumblingInstanceManager extends BlockEntityInstanceManager {
|
||||||
|
|
||||||
public CrumblingInstanceManager(MaterialManager materialManager) {
|
public CrumblingInstanceManager(InstancerManager instancerManager) {
|
||||||
super(materialManager);
|
super(instancerManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,7 +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.instancing.SerialTaskEngine;
|
import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancedMaterial;
|
import com.jozufozu.flywheel.backend.instancing.instancing.GPUInstancerFactory;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
||||||
import com.jozufozu.flywheel.core.Contexts;
|
import com.jozufozu.flywheel.core.Contexts;
|
||||||
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
|
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
|
||||||
|
@ -65,7 +65,7 @@ public class CrumblingRenderer {
|
||||||
|
|
||||||
State state = STATE.get();
|
State state = STATE.get();
|
||||||
var instanceManager = state.instanceManager;
|
var instanceManager = state.instanceManager;
|
||||||
var engine = state.materialManager;
|
var engine = state.instancerManager;
|
||||||
|
|
||||||
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
|
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
|
||||||
Camera info = Minecraft.getInstance().gameRenderer.getMainCamera();
|
Camera info = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||||
|
@ -140,17 +140,17 @@ public class CrumblingRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class State {
|
private static class State {
|
||||||
private final CrumblingEngine materialManager;
|
private final CrumblingEngine instancerManager;
|
||||||
private final InstanceManager<BlockEntity> instanceManager;
|
private final InstanceManager<BlockEntity> instanceManager;
|
||||||
|
|
||||||
private State() {
|
private State() {
|
||||||
materialManager = new CrumblingEngine();
|
instancerManager = new CrumblingEngine();
|
||||||
instanceManager = new CrumblingInstanceManager(materialManager);
|
instanceManager = new CrumblingInstanceManager(instancerManager);
|
||||||
materialManager.addListener(instanceManager);
|
instancerManager.addListener(instanceManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void kill() {
|
private void kill() {
|
||||||
materialManager.delete();
|
instancerManager.delete();
|
||||||
instanceManager.invalidate();
|
instanceManager.invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,10 +190,10 @@ public class CrumblingRenderer {
|
||||||
Textures.bindActiveTextures();
|
Textures.bindActiveTextures();
|
||||||
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
||||||
|
|
||||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
for (Map.Entry<Instanced<? extends InstanceData>, GPUInstancerFactory<?>> entry : factories.entrySet()) {
|
||||||
CrumblingProgram program = setup(entry.getKey(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
//CrumblingProgram program = setup(entry.getKey(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
||||||
|
|
||||||
program.setAtlasSize(width, height);
|
//program.setAtlasSize(width, height);
|
||||||
|
|
||||||
//entry.getValue().getAllRenderables().forEach(Renderable::draw);
|
//entry.getValue().getAllRenderables().forEach(Renderable::draw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.jozufozu.flywheel.core.material;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
import com.jozufozu.flywheel.core.source.Resolver;
|
||||||
|
import com.jozufozu.flywheel.event.GatherContextEvent;
|
||||||
|
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||||
|
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
public class MaterialShaders {
|
||||||
|
public static FileResolution DEFAULT_VERTEX;
|
||||||
|
public static FileResolution DEFAULT_FRAGMENT;
|
||||||
|
public static FileResolution SHADED_VERTEX;
|
||||||
|
|
||||||
|
public static void flwInit(GatherContextEvent event) {
|
||||||
|
DEFAULT_VERTEX = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.DEFAULT, ".vert"));
|
||||||
|
DEFAULT_FRAGMENT = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.DEFAULT, ".frag"));
|
||||||
|
SHADED_VERTEX = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.SHADED, ".vert"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Names {
|
||||||
|
public static final ResourceLocation DEFAULT = Flywheel.rl("material/default");
|
||||||
|
public static final ResourceLocation SHADED = Flywheel.rl("material/shaded");
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
package com.jozufozu.flywheel.core.materials;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelType;
|
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedType;
|
|
||||||
|
|
||||||
public class Materials {
|
|
||||||
public static final StructType<ModelData> TRANSFORMED = new ModelType();
|
|
||||||
public static final StructType<OrientedData> ORIENTED = new OrientedType();
|
|
||||||
}
|
|
|
@ -2,11 +2,10 @@ package com.jozufozu.flywheel.core.model;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
|
|
||||||
public interface ModelSupplier {
|
public interface ModelSupplier {
|
||||||
|
Map<Material, Mesh> get();
|
||||||
Map<RenderType, Mesh> get();
|
|
||||||
|
|
||||||
int getVertexCount();
|
int getVertexCount();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core.materials;
|
package com.jozufozu.flywheel.core.structs;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
import com.jozufozu.flywheel.util.Color;
|
import com.jozufozu.flywheel.util.Color;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core.materials;
|
package com.jozufozu.flywheel.core.structs;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core.materials;
|
package com.jozufozu.flywheel.core.structs;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.InstanceData;
|
import com.jozufozu.flywheel.api.InstanceData;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core.materials;
|
package com.jozufozu.flywheel.core.structs;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.jozufozu.flywheel.core.structs;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.core.structs.model.ModelData;
|
||||||
|
import com.jozufozu.flywheel.core.structs.model.ModelType;
|
||||||
|
import com.jozufozu.flywheel.core.structs.oriented.OrientedData;
|
||||||
|
import com.jozufozu.flywheel.core.structs.oriented.OrientedType;
|
||||||
|
|
||||||
|
public class StructTypes {
|
||||||
|
public static final StructType<ModelData> MODEL = new ModelType();
|
||||||
|
public static final StructType<OrientedData> ORIENTED = new OrientedType();
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.core.materials.model;
|
package com.jozufozu.flywheel.core.structs.model;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.materials.BasicData;
|
import com.jozufozu.flywheel.core.structs.BasicData;
|
||||||
import com.jozufozu.flywheel.util.transform.Transform;
|
import com.jozufozu.flywheel.util.transform.Transform;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Matrix3f;
|
import com.mojang.math.Matrix3f;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core.materials.model;
|
package com.jozufozu.flywheel.core.structs.model;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.Batched;
|
import com.jozufozu.flywheel.api.struct.Batched;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
|
@ -6,9 +6,9 @@ import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
import com.jozufozu.flywheel.core.materials.InstanceShaders;
|
|
||||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
import com.jozufozu.flywheel.core.structs.InstanceShaders;
|
||||||
|
|
||||||
public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
|
public class ModelType implements Instanced<ModelData>, Batched<ModelData> {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.jozufozu.flywheel.core.materials.model;
|
package com.jozufozu.flywheel.core.structs.model;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
|
import com.jozufozu.flywheel.core.structs.BasicWriterUnsafe;
|
||||||
import com.jozufozu.flywheel.util.MatrixWrite;
|
import com.jozufozu.flywheel.util.MatrixWrite;
|
||||||
|
|
||||||
public class ModelWriterUnsafe extends BasicWriterUnsafe<ModelData> {
|
public class ModelWriterUnsafe extends BasicWriterUnsafe<ModelData> {
|
|
@ -1,5 +1,5 @@
|
||||||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||||
package com.jozufozu.flywheel.core.materials.model;
|
package com.jozufozu.flywheel.core.structs.model;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.core.materials.oriented;
|
package com.jozufozu.flywheel.core.structs.oriented;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.core.materials.BasicData;
|
import com.jozufozu.flywheel.core.structs.BasicData;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.core.materials.oriented;
|
package com.jozufozu.flywheel.core.structs.oriented;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.Batched;
|
import com.jozufozu.flywheel.api.struct.Batched;
|
||||||
import com.jozufozu.flywheel.api.struct.Instanced;
|
import com.jozufozu.flywheel.api.struct.Instanced;
|
||||||
|
@ -6,9 +6,9 @@ import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||||
import com.jozufozu.flywheel.core.materials.InstanceShaders;
|
|
||||||
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
import com.jozufozu.flywheel.core.model.ModelTransformer;
|
||||||
import com.jozufozu.flywheel.core.source.FileResolution;
|
import com.jozufozu.flywheel.core.source.FileResolution;
|
||||||
|
import com.jozufozu.flywheel.core.structs.InstanceShaders;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
|
|
||||||
public class OrientedType implements Instanced<OrientedData>, Batched<OrientedData> {
|
public class OrientedType implements Instanced<OrientedData>, Batched<OrientedData> {
|
|
@ -1,10 +1,10 @@
|
||||||
package com.jozufozu.flywheel.core.materials.oriented;
|
package com.jozufozu.flywheel.core.structs.oriented;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||||
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
|
import com.jozufozu.flywheel.core.structs.BasicWriterUnsafe;
|
||||||
|
|
||||||
public class OrientedWriterUnsafe extends BasicWriterUnsafe<OrientedData> {
|
public class OrientedWriterUnsafe extends BasicWriterUnsafe<OrientedData> {
|
||||||
public OrientedWriterUnsafe(VecBuffer backingBuffer, StructType<OrientedData> vertexType) {
|
public OrientedWriterUnsafe(VecBuffer backingBuffer, StructType<OrientedData> vertexType) {
|
|
@ -1,5 +1,5 @@
|
||||||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||||
package com.jozufozu.flywheel.core.materials.oriented;
|
package com.jozufozu.flywheel.core.structs.oriented;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||||
package com.jozufozu.flywheel.core.materials;
|
package com.jozufozu.flywheel.core.structs;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
|
@ -2,13 +2,15 @@ package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
import com.jozufozu.flywheel.core.materials.Materials;
|
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||||
|
import com.jozufozu.flywheel.core.structs.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
@ -20,14 +22,14 @@ import net.minecraft.world.level.block.entity.BellBlockEntity;
|
||||||
|
|
||||||
public class BellInstance extends BlockEntityInstance<BellBlockEntity> implements DynamicInstance {
|
public class BellInstance extends BlockEntityInstance<BellBlockEntity> implements DynamicInstance {
|
||||||
|
|
||||||
private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, Sheets.solidBlockSheet());
|
private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, new Material(Sheets.solidBlockSheet(), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT));
|
||||||
|
|
||||||
private final OrientedData bell;
|
private final OrientedData bell;
|
||||||
|
|
||||||
private float lastRingTime = Float.NaN;
|
private float lastRingTime = Float.NaN;
|
||||||
|
|
||||||
public BellInstance(MaterialManager materialManager, BellBlockEntity blockEntity) {
|
public BellInstance(InstancerManager instancerManager, BellBlockEntity blockEntity) {
|
||||||
super(materialManager, blockEntity);
|
super(instancerManager, blockEntity);
|
||||||
|
|
||||||
bell = createBellInstance()
|
bell = createBellInstance()
|
||||||
.setPivot(0.5f, 0.75f, 0.5f)
|
.setPivot(0.5f, 0.75f, 0.5f)
|
||||||
|
@ -63,7 +65,7 @@ public class BellInstance extends BlockEntityInstance<BellBlockEntity> implement
|
||||||
}
|
}
|
||||||
|
|
||||||
private OrientedData createBellInstance() {
|
private OrientedData createBellInstance() {
|
||||||
return materialManager.material(Materials.ORIENTED)
|
return instancerManager.factory(StructTypes.ORIENTED)
|
||||||
.model(MODEL)
|
.model(MODEL)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,15 @@ import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
import com.jozufozu.flywheel.core.materials.Materials;
|
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
import com.jozufozu.flywheel.core.structs.model.ModelData;
|
||||||
|
import com.jozufozu.flywheel.core.structs.oriented.OrientedData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
@ -33,8 +34,8 @@ import net.minecraft.world.level.block.state.properties.ChestType;
|
||||||
|
|
||||||
public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends BlockEntityInstance<T> implements DynamicInstance {
|
public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends BlockEntityInstance<T> implements DynamicInstance {
|
||||||
|
|
||||||
private static final BiFunction<ChestType, Material, BasicModelSupplier> LID = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createLidModel(type, mat.sprite()), Sheets.chestSheet()));
|
private static final BiFunction<ChestType, Material, BasicModelSupplier> LID = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createLidModel(type, mat.sprite()), new com.jozufozu.flywheel.api.material.Material(Sheets.chestSheet(), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT)));
|
||||||
private static final BiFunction<ChestType, Material, BasicModelSupplier> BASE = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createBaseModel(type, mat.sprite()), Sheets.chestSheet()));
|
private static final BiFunction<ChestType, Material, BasicModelSupplier> BASE = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createBaseModel(type, mat.sprite()), new com.jozufozu.flywheel.api.material.Material(Sheets.chestSheet(), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT)));
|
||||||
|
|
||||||
private final OrientedData body;
|
private final OrientedData body;
|
||||||
private final ModelData lid;
|
private final ModelData lid;
|
||||||
|
@ -47,8 +48,8 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
||||||
|
|
||||||
private float lastProgress = Float.NaN;
|
private float lastProgress = Float.NaN;
|
||||||
|
|
||||||
public ChestInstance(MaterialManager materialManager, T blockEntity) {
|
public ChestInstance(InstancerManager instancerManager, T blockEntity) {
|
||||||
super(materialManager, blockEntity);
|
super(instancerManager, blockEntity);
|
||||||
|
|
||||||
Block block = blockState.getBlock();
|
Block block = blockState.getBlock();
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
||||||
|
|
||||||
body.setRotation(baseRotation);
|
body.setRotation(baseRotation);
|
||||||
|
|
||||||
DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> wrapper = chestBlock.combine(blockState, world, getWorldPosition(), true);
|
DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> wrapper = chestBlock.combine(blockState, level, getWorldPosition(), true);
|
||||||
|
|
||||||
this.lidProgress = wrapper.apply(ChestBlock.opennessCombiner(blockEntity));
|
this.lidProgress = wrapper.apply(ChestBlock.opennessCombiner(blockEntity));
|
||||||
|
|
||||||
|
@ -115,14 +116,14 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
||||||
|
|
||||||
private OrientedData baseInstance() {
|
private OrientedData baseInstance() {
|
||||||
|
|
||||||
return materialManager.material(Materials.ORIENTED)
|
return instancerManager.factory(StructTypes.ORIENTED)
|
||||||
.model(BASE.apply(chestType, renderMaterial))
|
.model(BASE.apply(chestType, renderMaterial))
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelData lidInstance() {
|
private ModelData lidInstance() {
|
||||||
|
|
||||||
return materialManager.material(Materials.TRANSFORMED)
|
return instancerManager.factory(StructTypes.MODEL)
|
||||||
.model(LID.apply(chestType, renderMaterial))
|
.model(LID.apply(chestType, renderMaterial))
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,18 @@ package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.Models;
|
import com.jozufozu.flywheel.core.Models;
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
import com.jozufozu.flywheel.core.materials.Materials;
|
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
|
||||||
import com.jozufozu.flywheel.core.model.Mesh;
|
import com.jozufozu.flywheel.core.model.Mesh;
|
||||||
|
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||||
|
import com.jozufozu.flywheel.core.structs.model.ModelData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
@ -29,7 +31,7 @@ import net.minecraft.world.phys.Vec3;
|
||||||
public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance<T> implements DynamicInstance, TickableInstance {
|
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 ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png");
|
||||||
private static final BasicModelSupplier MODEL = new BasicModelSupplier(MinecartInstance::getBodyModel, RenderType.entitySolid(MINECART_LOCATION));
|
private static final BasicModelSupplier MODEL = new BasicModelSupplier(MinecartInstance::getBodyModel, new Material(RenderType.entitySolid(MINECART_LOCATION), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT));
|
||||||
|
|
||||||
private final PoseStack stack = new PoseStack();
|
private final PoseStack stack = new PoseStack();
|
||||||
|
|
||||||
|
@ -37,8 +39,8 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
|
||||||
private ModelData contents;
|
private ModelData contents;
|
||||||
private BlockState blockstate;
|
private BlockState blockstate;
|
||||||
|
|
||||||
public MinecartInstance(MaterialManager materialManager, T entity) {
|
public MinecartInstance(InstancerManager instancerManager, T entity) {
|
||||||
super(materialManager, entity);
|
super(instancerManager, entity);
|
||||||
|
|
||||||
blockstate = entity.getDisplayBlockState();
|
blockstate = entity.getDisplayBlockState();
|
||||||
contents = getContents();
|
contents = getContents();
|
||||||
|
@ -63,7 +65,7 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
|
||||||
stack.setIdentity();
|
stack.setIdentity();
|
||||||
float pt = AnimationTickHolder.getPartialTicks();
|
float pt = AnimationTickHolder.getPartialTicks();
|
||||||
|
|
||||||
Vec3i originCoordinate = materialManager.getOriginCoordinate();
|
Vec3i originCoordinate = instancerManager.getOriginCoordinate();
|
||||||
tstack.translate(
|
tstack.translate(
|
||||||
Mth.lerp(pt, entity.xOld, entity.getX()) - originCoordinate.getX(),
|
Mth.lerp(pt, entity.xOld, entity.getX()) - originCoordinate.getX(),
|
||||||
Mth.lerp(pt, entity.yOld, entity.getY()) - originCoordinate.getY(),
|
Mth.lerp(pt, entity.yOld, entity.getY()) - originCoordinate.getY(),
|
||||||
|
@ -147,13 +149,13 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
|
||||||
if (blockstate.getRenderShape() == RenderShape.INVISIBLE)
|
if (blockstate.getRenderShape() == RenderShape.INVISIBLE)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return materialManager.material(Materials.TRANSFORMED)
|
return instancerManager.factory(StructTypes.MODEL)
|
||||||
.model(Models.block(blockstate))
|
.model(Models.block(blockstate))
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelData getBody() {
|
private ModelData getBody() {
|
||||||
return materialManager.material(Materials.TRANSFORMED)
|
return instancerManager.factory(StructTypes.MODEL)
|
||||||
.model(MODEL)
|
.model(MODEL)
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,15 @@ package com.jozufozu.flywheel.vanilla;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.InstancerManager;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||||
import com.jozufozu.flywheel.core.materials.Materials;
|
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||||
|
import com.jozufozu.flywheel.core.structs.model.ModelData;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
@ -26,8 +28,8 @@ import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
|
||||||
|
|
||||||
public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntity> implements DynamicInstance {
|
public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntity> implements DynamicInstance {
|
||||||
|
|
||||||
private static final Function<TextureAtlasSprite, BasicModelSupplier> BASE = Util.memoize(it -> new BasicModelSupplier(() -> makeBaseModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET)));
|
private static final Function<TextureAtlasSprite, BasicModelSupplier> BASE = Util.memoize(it -> new BasicModelSupplier(() -> makeBaseModel(it), new Material(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT)));
|
||||||
private static final Function<TextureAtlasSprite, BasicModelSupplier> LID = Util.memoize(it -> new BasicModelSupplier(() -> makeLidModel(it), RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET)));
|
private static final Function<TextureAtlasSprite, BasicModelSupplier> LID = Util.memoize(it -> new BasicModelSupplier(() -> makeLidModel(it), new Material(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT)));
|
||||||
|
|
||||||
private final TextureAtlasSprite texture;
|
private final TextureAtlasSprite texture;
|
||||||
|
|
||||||
|
@ -37,8 +39,8 @@ public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntit
|
||||||
|
|
||||||
private float lastProgress = Float.NaN;
|
private float lastProgress = Float.NaN;
|
||||||
|
|
||||||
public ShulkerBoxInstance(MaterialManager materialManager, ShulkerBoxBlockEntity blockEntity) {
|
public ShulkerBoxInstance(InstancerManager instancerManager, ShulkerBoxBlockEntity blockEntity) {
|
||||||
super(materialManager, blockEntity);
|
super(instancerManager, blockEntity);
|
||||||
|
|
||||||
DyeColor color = blockEntity.getColor();
|
DyeColor color = blockEntity.getColor();
|
||||||
if (color == null) {
|
if (color == null) {
|
||||||
|
@ -97,13 +99,13 @@ public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntit
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelData makeBaseInstance() {
|
private ModelData makeBaseInstance() {
|
||||||
return materialManager.material(Materials.TRANSFORMED)
|
return instancerManager.factory(StructTypes.MODEL)
|
||||||
.model(BASE.apply(texture))
|
.model(BASE.apply(texture))
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelData makeLidInstance() {
|
private ModelData makeLidInstance() {
|
||||||
return materialManager.material(Materials.TRANSFORMED)
|
return instancerManager.factory(StructTypes.MODEL)
|
||||||
.model(LID.apply(texture))
|
.model(LID.apply(texture))
|
||||||
.createInstance();
|
.createInstance();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
#use "flywheel:api/vertex.glsl"
|
#use "flywheel:api/vertex.glsl"
|
||||||
#use "flywheel:util/diffuse.glsl"
|
|
||||||
#use "flywheel:util/fog.glsl"
|
#use "flywheel:util/fog.glsl"
|
||||||
|
|
||||||
uniform mat4 uViewProjection;
|
uniform mat4 uViewProjection;
|
||||||
uniform vec3 uCameraPos;
|
uniform vec3 uCameraPos;
|
||||||
uniform int uConstantAmbientLight;
|
|
||||||
uniform int uFogShape;
|
uniform int uFogShape;
|
||||||
|
|
||||||
out float _flw_diffuse;
|
|
||||||
|
|
||||||
void flw_contextVertex() {
|
void flw_contextVertex() {
|
||||||
flw_vertexNormal = normalize(flw_vertexNormal);
|
|
||||||
if (uConstantAmbientLight == 1) {
|
|
||||||
_flw_diffuse = diffuseNether(flw_vertexNormal);
|
|
||||||
} else {
|
|
||||||
_flw_diffuse = diffuse(flw_vertexNormal);
|
|
||||||
}
|
|
||||||
flw_distance = fog_distance(flw_vertexPos.xyz, uCameraPos, uFogShape);
|
flw_distance = fog_distance(flw_vertexPos.xyz, uCameraPos, uFogShape);
|
||||||
gl_Position = uViewProjection * flw_vertexPos;
|
gl_Position = uViewProjection * flw_vertexPos;
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,13 @@ uniform vec2 uTextureScale;
|
||||||
uniform sampler2D uBlockAtlas;
|
uniform sampler2D uBlockAtlas;
|
||||||
uniform sampler2D uCrumbling;
|
uniform sampler2D uCrumbling;
|
||||||
|
|
||||||
in float _flw_diffuse;
|
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
void flw_contextFragment() {
|
void flw_contextFragment() {
|
||||||
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
||||||
vec4 crumblingColor = texture(uCrumbling, flw_vertexTexCoord * uTextureScale);
|
vec4 crumblingColor = texture(uCrumbling, flw_vertexTexCoord * uTextureScale);
|
||||||
crumblingColor.a *= texColor.a;
|
crumblingColor.a *= texColor.a;
|
||||||
vec4 color = flw_vertexColor * vec4(crumblingColor.rgb * _flw_diffuse, crumblingColor.a);
|
vec4 color = flw_vertexColor * vec4(crumblingColor.rgb, crumblingColor.a);
|
||||||
|
|
||||||
#ifdef ALPHA_DISCARD
|
#ifdef ALPHA_DISCARD
|
||||||
if (color.a < ALPHA_DISCARD) {
|
if (color.a < ALPHA_DISCARD) {
|
||||||
|
|
|
@ -14,14 +14,12 @@ uniform vec4 uFogColor;
|
||||||
uniform sampler2D uBlockAtlas;
|
uniform sampler2D uBlockAtlas;
|
||||||
uniform sampler2D uLightMap;
|
uniform sampler2D uLightMap;
|
||||||
|
|
||||||
in float _flw_diffuse;
|
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
void flw_contextFragment() {
|
void flw_contextFragment() {
|
||||||
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
||||||
vec4 lightColor = texture(uLightMap, flw_vertexLight);
|
vec4 lightColor = texture(uLightMap, flw_vertexLight);
|
||||||
vec4 color = flw_vertexColor * vec4(texColor.rgb * lightColor.rgb * _flw_diffuse, texColor.a);
|
vec4 color = flw_vertexColor * vec4(texColor.rgb * lightColor.rgb, texColor.a);
|
||||||
|
|
||||||
#ifdef ALPHA_DISCARD
|
#ifdef ALPHA_DISCARD
|
||||||
if (color.a < ALPHA_DISCARD) {
|
if (color.a < ALPHA_DISCARD) {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#use "flywheel:api/fragment.glsl"
|
||||||
|
|
||||||
|
void flw_materialFragment() {
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#use "flywheel:api/vertex.glsl"
|
||||||
|
|
||||||
|
void flw_materialVertex() {
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#use "flywheel:api/vertex.glsl"
|
||||||
|
#use "flywheel:util/diffuse.glsl"
|
||||||
|
|
||||||
|
uniform int uConstantAmbientLight;
|
||||||
|
|
||||||
|
void flw_materialVertex() {
|
||||||
|
flw_vertexNormal = normalize(flw_vertexNormal);
|
||||||
|
|
||||||
|
float diffuseFactor;
|
||||||
|
if (uConstantAmbientLight == 1) {
|
||||||
|
diffuseFactor = diffuseNether(flw_vertexNormal);
|
||||||
|
} else {
|
||||||
|
diffuseFactor = diffuse(flw_vertexNormal);
|
||||||
|
}
|
||||||
|
flw_vertexColor = vec4(flw_vertexColor.rgb * diffuseFactor, flw_vertexColor.a);
|
||||||
|
}
|
Loading…
Reference in a new issue