mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-27 05:17: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.StitchedSprite;
|
||||
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.event.ReloadRenderersEvent;
|
||||
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
||||
|
@ -77,6 +78,7 @@ public class Flywheel {
|
|||
|
||||
modEventBus.addListener(LayoutShaders::flwInit);
|
||||
modEventBus.addListener(InstanceShaders::flwInit);
|
||||
modEventBus.addListener(MaterialShaders::flwInit);
|
||||
modEventBus.addListener(Contexts::flwInit);
|
||||
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||
modEventBus.addListener(PartialModel::onModelBake);
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.api;
|
|||
|
||||
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.
|
|
@ -4,9 +4,9 @@ import com.jozufozu.flywheel.api.struct.StructType;
|
|||
|
||||
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();
|
||||
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.api;
|
|||
|
||||
import com.jozufozu.flywheel.api.struct.StructType;
|
||||
|
||||
@Deprecated
|
||||
public interface MaterialGroup {
|
||||
/**
|
||||
* 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.
|
||||
* @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.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.Instance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
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.LightProvider;
|
||||
import com.jozufozu.flywheel.light.ListenerStatus;
|
||||
|
@ -24,12 +24,12 @@ import net.minecraft.world.level.LightLayer;
|
|||
*/
|
||||
public abstract class AbstractInstance implements Instance, LightListener {
|
||||
|
||||
protected final MaterialManager materialManager;
|
||||
public final Level world;
|
||||
protected final InstancerManager instancerManager;
|
||||
public final Level level;
|
||||
|
||||
public AbstractInstance(MaterialManager materialManager, Level world) {
|
||||
this.materialManager = materialManager;
|
||||
this.world = world;
|
||||
public AbstractInstance(InstancerManager instancerManager, Level level) {
|
||||
this.instancerManager = instancerManager;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,11 +88,11 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
|||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.jozufozu.flywheel.backend.instancing;
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Set;
|
|||
|
||||
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.TickableInstance;
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
|
@ -27,7 +27,7 @@ import net.minecraft.core.BlockPos;
|
|||
|
||||
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> queuedUpdates;
|
||||
|
@ -39,8 +39,8 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
|||
protected DistanceUpdateLimiter frame;
|
||||
protected DistanceUpdateLimiter tick;
|
||||
|
||||
public InstanceManager(MaterialManager materialManager) {
|
||||
this.materialManager = materialManager;
|
||||
public InstanceManager(InstancerManager instancerManager) {
|
||||
this.instancerManager = instancerManager;
|
||||
this.queuedUpdates = new HashSet<>(64);
|
||||
this.queuedAdditions = new HashSet<>(64);
|
||||
this.instances = new HashMap<>();
|
||||
|
@ -318,7 +318,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
|||
instances.remove(obj);
|
||||
dynamicInstances.remove(obj);
|
||||
tickableInstances.remove(obj);
|
||||
LightUpdater.get(instance.world)
|
||||
LightUpdater.get(instance.level)
|
||||
.removeListener(instance);
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
|||
if (renderer != null) {
|
||||
renderer.init();
|
||||
renderer.updateLight();
|
||||
LightUpdater.get(renderer.world)
|
||||
LightUpdater.get(renderer.level)
|
||||
.addListener(renderer);
|
||||
instances.put(obj, renderer);
|
||||
|
||||
|
@ -356,7 +356,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
|||
|
||||
public void detachLightListeners() {
|
||||
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.
|
||||
* <p>
|
||||
* The material manager is shared between the different instance managers.
|
||||
* The instancer manager is shared between the different instance managers.
|
||||
* </p>
|
||||
*/
|
||||
public class InstanceWorld {
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.function.Predicate;
|
|||
|
||||
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.BlockEntityInstancingController;
|
||||
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.
|
||||
* @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 <T> The type of the block entity.
|
||||
* @return An instance of the block entity, or {@code null} if the block entity cannot be instanced.
|
||||
*/
|
||||
@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));
|
||||
if (controller == null) {
|
||||
return null;
|
||||
}
|
||||
return controller.createInstance(materialManager, blockEntity);
|
||||
return controller.createInstance(instancerManager, blockEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 <T> The type of the entity.
|
||||
* @return An instance of the entity, or {@code null} if the entity cannot be instanced.
|
||||
*/
|
||||
@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));
|
||||
if (controller == 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> {
|
||||
protected BlockEntityType<T> type;
|
||||
protected BiFunction<MaterialManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||
protected BiFunction<InstancerManager, T, BlockEntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public BlockEntityConfig(BlockEntityType<T> type) {
|
||||
|
@ -206,7 +206,7 @@ public class InstancedRenderRegistry {
|
|||
* @param instanceFactory The instance factory.
|
||||
* @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;
|
||||
return this;
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ public class InstancedRenderRegistry {
|
|||
*/
|
||||
public static class EntityConfig<T extends Entity> {
|
||||
protected EntityType<T> type;
|
||||
protected BiFunction<MaterialManager, T, EntityInstance<? super T>> instanceFactory;
|
||||
protected BiFunction<InstancerManager, T, EntityInstance<? super T>> instanceFactory;
|
||||
protected Predicate<T> skipRender;
|
||||
|
||||
public EntityConfig(EntityType<T> type) {
|
||||
|
@ -263,7 +263,7 @@ public class InstancedRenderRegistry {
|
|||
* @param instanceFactory The instance factory.
|
||||
* @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;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
|||
|
||||
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 instanceCount;
|
||||
|
||||
|
@ -27,9 +27,9 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@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) {
|
||||
return (BatchedMaterial<D>) materials.computeIfAbsent(batched, BatchedMaterial::new);
|
||||
return (CPUInstancerFactory<D>) materials.computeIfAbsent(batched, CPUInstancerFactory::new);
|
||||
} else {
|
||||
throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing.");
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public class BatchedMaterialGroup implements MaterialGroup {
|
|||
}
|
||||
|
||||
public void clear() {
|
||||
materials.values().forEach(BatchedMaterial::clear);
|
||||
materials.values().forEach(CPUInstancerFactory::clear);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
|
|
|
@ -21,16 +21,16 @@ import net.minecraft.core.Vec3i;
|
|||
|
||||
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();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@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) {
|
||||
return (BatchedMaterial<D>) materials.computeIfAbsent(batched, BatchedMaterial::new);
|
||||
return (CPUInstancerFactory<D>) factories.computeIfAbsent(batched, CPUInstancerFactory::new);
|
||||
} 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
|
||||
public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) {
|
||||
|
||||
// vertexCount = 0;
|
||||
// instanceCount = 0;
|
||||
// for (BatchedMaterial<?> material : materials.values()) {
|
||||
|
|
|
@ -5,18 +5,18 @@ import java.util.Map;
|
|||
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
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.core.model.ModelSupplier;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
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;
|
||||
private final Batched<D> type;
|
||||
|
||||
public BatchedMaterial(Batched<D> type) {
|
||||
public CPUInstancerFactory(Batched<D> type) {
|
||||
this.type = type;
|
||||
|
||||
this.models = new HashMap<>();
|
|
@ -1,13 +1,13 @@
|
|||
package com.jozufozu.flywheel.backend.instancing.blockentity;
|
||||
|
||||
import com.jozufozu.flywheel.api.Material;
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.InstancerFactory;
|
||||
import com.jozufozu.flywheel.api.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.core.materials.Materials;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||
import com.jozufozu.flywheel.core.structs.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.structs.oriented.OrientedData;
|
||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
||||
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 BlockState blockState;
|
||||
|
||||
public BlockEntityInstance(MaterialManager materialManager, T blockEntity) {
|
||||
super(materialManager, blockEntity.getLevel());
|
||||
public BlockEntityInstance(InstancerManager instancerManager, T blockEntity) {
|
||||
super(instancerManager, blockEntity.getLevel());
|
||||
this.blockEntity = blockEntity;
|
||||
this.pos = blockEntity.getBlockPos();
|
||||
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.
|
||||
*/
|
||||
public BlockPos getInstancePosition() {
|
||||
return pos.subtract(materialManager.getOriginCoordinate());
|
||||
return pos.subtract(instancerManager.getOriginCoordinate());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,12 +76,12 @@ public abstract class BlockEntityInstance<T extends BlockEntity> extends Abstrac
|
|||
return pos;
|
||||
}
|
||||
|
||||
protected Material<ModelData> getTransformMaterial() {
|
||||
return materialManager.material(Materials.TRANSFORMED);
|
||||
protected InstancerFactory<ModelData> getTransformFactory() {
|
||||
return instancerManager.factory(StructTypes.MODEL);
|
||||
}
|
||||
|
||||
protected Material<OrientedData> getOrientedMaterial() {
|
||||
return materialManager.material(Materials.ORIENTED);
|
||||
protected InstancerFactory<OrientedData> getOrientedFactory() {
|
||||
return instancerManager.factory(StructTypes.ORIENTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.instancing.AbstractInstance;
|
||||
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 BlockEntityInstanceManager(MaterialManager materialManager) {
|
||||
super(materialManager);
|
||||
public BlockEntityInstanceManager(InstancerManager instancerManager) {
|
||||
super(instancerManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,7 +24,7 @@ public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
|||
|
||||
@Override
|
||||
protected AbstractInstance createRaw(BlockEntity obj) {
|
||||
return InstancedRenderRegistry.createInstance(materialManager, obj);
|
||||
return InstancedRenderRegistry.createInstance(instancerManager, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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;
|
||||
|
||||
|
@ -10,12 +10,12 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||
*/
|
||||
public interface BlockEntityInstancingController<T extends BlockEntity> {
|
||||
/**
|
||||
* Given a block entity and a material manager, constructs an instance for the block entity.
|
||||
* @param materialManager The material manager to use.
|
||||
* Given a block entity and an instancer manager, constructs an instance for the block entity.
|
||||
* @param instancerManager The instancer manager to use.
|
||||
* @param blockEntity The block entity to construct an instance for.
|
||||
* @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.
|
||||
|
|
|
@ -3,22 +3,22 @@ package com.jozufozu.flywheel.backend.instancing.blockentity;
|
|||
import java.util.function.BiFunction;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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.skipRender = skipRender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityInstance<? super T> createInstance(MaterialManager materialManager, T blockEntity) {
|
||||
return instanceFactory.apply(materialManager, blockEntity);
|
||||
public BlockEntityInstance<? super T> createInstance(InstancerManager instancerManager, T blockEntity) {
|
||||
return instanceFactory.apply(instancerManager, blockEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.TickableInstance;
|
||||
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 GridAlignedBB bounds;
|
||||
|
||||
public EntityInstance(MaterialManager materialManager, E entity) {
|
||||
super(materialManager, entity.level);
|
||||
public EntityInstance(InstancerManager instancerManager, E entity) {
|
||||
super(instancerManager, entity.level);
|
||||
this.entity = entity;
|
||||
bounds = GridAlignedBB.from(entity.getBoundingBox());
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
|||
*/
|
||||
public Vector3f getInstancePosition() {
|
||||
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()));
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ public abstract class EntityInstance<E extends Entity> extends AbstractInstance
|
|||
*/
|
||||
public Vector3f getInstancePosition(float partialTicks) {
|
||||
Vec3 pos = entity.position();
|
||||
Vec3i origin = materialManager.getOriginCoordinate();
|
||||
Vec3i origin = instancerManager.getOriginCoordinate();
|
||||
return new Vector3f(
|
||||
(float) (Mth.lerp(partialTicks, entity.xOld, pos.x) - origin.getX()),
|
||||
(float) (Mth.lerp(partialTicks, entity.yOld, pos.y) - origin.getY()),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.instancing.AbstractInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
|
@ -13,8 +13,8 @@ import net.minecraft.world.level.Level;
|
|||
|
||||
public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||
|
||||
public EntityInstanceManager(MaterialManager materialManager) {
|
||||
super(materialManager);
|
||||
public EntityInstanceManager(InstancerManager instancerManager) {
|
||||
super(instancerManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,7 +24,7 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
|||
|
||||
@Override
|
||||
protected AbstractInstance createRaw(Entity obj) {
|
||||
return InstancedRenderRegistry.createInstance(materialManager, obj);
|
||||
return InstancedRenderRegistry.createInstance(instancerManager, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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;
|
||||
|
||||
|
@ -10,12 +10,12 @@ import net.minecraft.world.entity.Entity;
|
|||
*/
|
||||
public interface EntityInstancingController<T extends Entity> {
|
||||
/**
|
||||
* Given an entity and a material manager, constructs an instance for the entity.
|
||||
* @param materialManager The material manager to use.
|
||||
* Given an entity and an instancer manager, constructs an instance for the entity.
|
||||
* @param instancerManager The instancer manager to use.
|
||||
* @param entity The entity to construct an instance for.
|
||||
* @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.
|
||||
|
|
|
@ -3,22 +3,22 @@ package com.jozufozu.flywheel.backend.instancing.entity;
|
|||
import java.util.function.BiFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.InstancerManager;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
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;
|
||||
|
||||
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.skipRender = skipRender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityInstance<? super T> createInstance(MaterialManager materialManager, T entity) {
|
||||
return instanceFactory.apply(materialManager, entity);
|
||||
public EntityInstance<? super T> createInstance(InstancerManager instancerManager, T entity) {
|
||||
return instanceFactory.apply(instancerManager, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,10 +6,12 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.jozufozu.flywheel.api.InstanceData;
|
||||
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.backend.model.MeshPool;
|
||||
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.
|
||||
* @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 Instanced<D> type;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -56,6 +59,7 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
|||
public void delete() {
|
||||
models.values().forEach(InstancedModel::delete);
|
||||
models.clear();
|
||||
materials.clear();
|
||||
renderables.clear();
|
||||
}
|
||||
|
||||
|
@ -71,10 +75,12 @@ public class InstancedMaterial<D extends InstanceData> implements Material<D> {
|
|||
|
||||
public void init(MeshPool allocator) {
|
||||
for (var instanced : uninitialized) {
|
||||
|
||||
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();
|
||||
}
|
|
@ -4,26 +4,25 @@ import java.util.Map;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
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.model.MeshPool;
|
||||
import com.jozufozu.flywheel.core.model.Mesh;
|
||||
import com.jozufozu.flywheel.core.model.ModelSupplier;
|
||||
import com.jozufozu.flywheel.util.Pair;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class InstancedModel<D extends InstanceData> {
|
||||
|
||||
final GPUInstancer<D> instancer;
|
||||
final ModelSupplier model;
|
||||
private Map<RenderType, Layer> layers;
|
||||
private Map<Material, Layer> layers;
|
||||
|
||||
public InstancedModel(GPUInstancer<D> instancer, ModelSupplier model) {
|
||||
this.instancer = instancer;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public Map<RenderType, ? extends Renderable> init(MeshPool allocator) {
|
||||
public Map<Material, ? extends Renderable> init(MeshPool allocator) {
|
||||
instancer.init();
|
||||
|
||||
layers = model.get()
|
||||
|
@ -38,12 +37,12 @@ public class InstancedModel<D extends InstanceData> {
|
|||
|
||||
private class Layer implements Renderable {
|
||||
|
||||
final RenderType type;
|
||||
final Material material;
|
||||
MeshPool.BufferedMesh bufferedMesh;
|
||||
GlVertexArray vao;
|
||||
|
||||
private Layer(MeshPool allocator, RenderType type, Mesh mesh) {
|
||||
this.type = type;
|
||||
private Layer(MeshPool allocator, Material material, Mesh mesh) {
|
||||
this.material = material;
|
||||
vao = new GlVertexArray();
|
||||
bufferedMesh = allocator.alloc(mesh, vao);
|
||||
instancer.attributeBaseIndex = bufferedMesh.getAttributeCount();
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.Set;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
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.StructType;
|
||||
import com.jozufozu.flywheel.backend.instancing.Engine;
|
||||
|
@ -44,7 +45,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
protected final ProgramCompiler<P> context;
|
||||
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<>();
|
||||
|
||||
|
@ -61,9 +62,9 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
@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) {
|
||||
return (InstancedMaterial<D>) materials.computeIfAbsent(instanced, InstancedMaterial::new);
|
||||
return (GPUInstancerFactory<D>) factories.computeIfAbsent(instanced, GPUInstancerFactory::new);
|
||||
} else {
|
||||
throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing.");
|
||||
}
|
||||
|
@ -87,7 +88,6 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
|
||||
@Override
|
||||
public void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type) {
|
||||
|
||||
var camX = context.camX() - originCoordinate.getX();
|
||||
var camY = context.camY() - originCoordinate.getY();
|
||||
var camZ = context.camZ() - originCoordinate.getZ();
|
||||
|
@ -109,21 +109,23 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
Textures.bindActiveTextures();
|
||||
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
||||
|
||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||
InstancedMaterial<?> material = entry.getValue();
|
||||
for (Map.Entry<Instanced<? extends InstanceData>, GPUInstancerFactory<?>> entry : factories.entrySet()) {
|
||||
Instanced<? extends InstanceData> instanceType = entry.getKey();
|
||||
GPUInstancerFactory<?> factory = entry.getValue();
|
||||
|
||||
var toRender = material.renderables.get(type);
|
||||
toRender.removeIf(Renderable::shouldRemove);
|
||||
var materials = factory.materials.get(type);
|
||||
for (Material material : materials) {
|
||||
var toRender = factory.renderables.get(material);
|
||||
toRender.removeIf(Renderable::shouldRemove);
|
||||
|
||||
if (!toRender.isEmpty()) {
|
||||
Instanced<? extends InstanceData> instanceType = entry.getKey();
|
||||
if (!toRender.isEmpty()) {
|
||||
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();
|
||||
vertexCount += material.getVertexCount();
|
||||
|
||||
toRender.forEach(Renderable::render);
|
||||
toRender.forEach(Renderable::render);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,7 +147,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
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();
|
||||
if (alphaDiscard == 0) {
|
||||
alphaDiscard = 0.0001f;
|
||||
|
@ -153,7 +155,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
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.uploadUniforms(camX, camY, camZ, viewProjection, level);
|
||||
|
@ -162,15 +164,15 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
}
|
||||
|
||||
public void clearAll() {
|
||||
materials.values().forEach(InstancedMaterial::clear);
|
||||
factories.values().forEach(GPUInstancerFactory::clear);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
materials.values()
|
||||
.forEach(InstancedMaterial::delete);
|
||||
factories.values()
|
||||
.forEach(GPUInstancerFactory::delete);
|
||||
|
||||
materials.clear();
|
||||
factories.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -193,10 +195,10 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
|
||||
MeshPool allocator = getModelAllocator();
|
||||
|
||||
for (InstancedMaterial<?> material : materials.values()) {
|
||||
material.init(allocator);
|
||||
for (GPUInstancerFactory<?> factory : factories.values()) {
|
||||
factory.init(allocator);
|
||||
|
||||
toRender.addAll(material.renderables.keySet());
|
||||
toRender.addAll(factory.materials.keySet());
|
||||
}
|
||||
|
||||
allocator.flush();
|
||||
|
@ -221,7 +223,7 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
|||
private void shiftListeners(int cX, int cY, int cZ) {
|
||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||
|
||||
materials.values().forEach(InstancedMaterial::clear);
|
||||
factories.values().forEach(GPUInstancerFactory::clear);
|
||||
|
||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import java.util.Map;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
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.ModelSupplier;
|
||||
import com.jozufozu.flywheel.util.Lazy;
|
||||
|
@ -13,31 +15,28 @@ import com.jozufozu.flywheel.util.NonNullSupplier;
|
|||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
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;
|
||||
|
||||
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.renderType = renderType;
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public BasicModelSupplier setCutout() {
|
||||
return setRenderType(RenderType.cutoutMipped());
|
||||
}
|
||||
|
||||
public BasicModelSupplier setRenderType(@NotNull RenderType renderType) {
|
||||
this.renderType = renderType;
|
||||
public BasicModelSupplier setMaterial(@NotNull Material material) {
|
||||
this.material = material;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<RenderType, Mesh> get() {
|
||||
return ImmutableMap.of(renderType, supplier.get());
|
||||
public Map<Material, Mesh> get() {
|
||||
return ImmutableMap.of(material, supplier.get());
|
||||
}
|
||||
|
||||
public int getVertexCount() {
|
||||
|
@ -47,7 +46,7 @@ public class BasicModelSupplier implements ModelSupplier {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModelSupplier{" + supplier.map(Mesh::name)
|
||||
return "BasicModelSupplier{" + supplier.map(Mesh::name)
|
||||
.orElse("Uninitialized") + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@ public class Contexts {
|
|||
FileResolution crumblingVertex = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".vert"));
|
||||
FileResolution crumblingFragment = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".frag"));
|
||||
|
||||
WORLD = ProgramCompiler.create(WorldProgram::new, Templates.INSTANCING, Templates.FRAGMENT, worldVertex, worldFragment);
|
||||
CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, Templates.INSTANCING, Templates.FRAGMENT, crumblingVertex, crumblingFragment);
|
||||
WORLD = ProgramCompiler.create(WorldProgram::new, worldVertex, worldFragment);
|
||||
CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, crumblingVertex, crumblingFragment);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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.ShaderType;
|
||||
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.source.FileIndexImpl;
|
||||
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> {
|
||||
private final Template<? extends FragmentData> template;
|
||||
private final FileResolution contextShader;
|
||||
|
||||
public FragmentCompiler(Template<? extends FragmentData> template, FileResolution contextShader) {
|
||||
this.template = template;
|
||||
public FragmentCompiler(FileResolution contextShader) {
|
||||
this.contextShader = contextShader;
|
||||
}
|
||||
|
||||
|
@ -23,21 +29,77 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
|||
protected GlShader _create(Context key) {
|
||||
StringBuilder finalSource = new StringBuilder();
|
||||
|
||||
finalSource.append(CompileUtil.generateHeader(template.getVersion(), ShaderType.FRAGMENT));
|
||||
finalSource.append(CompileUtil.generateHeader(GLSLVersion.V150, ShaderType.FRAGMENT));
|
||||
|
||||
key.getShaderConstants().writeInto(finalSource);
|
||||
finalSource.append('\n');
|
||||
|
||||
FileIndexImpl index = new FileIndexImpl();
|
||||
|
||||
contextShader.getFile().generateFinalSource(index, finalSource);
|
||||
//
|
||||
|
||||
FragmentData appliedTemplate = template.apply(contextShader.getFile());
|
||||
finalSource.append(appliedTemplate.generateFooter());
|
||||
SourceFile materialShader = key.materialShader;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
protected String generateFooter() {
|
||||
StringBuilder footer = new StringBuilder();
|
||||
|
||||
footer.append("""
|
||||
void main() {
|
||||
flw_materialFragment();
|
||||
|
||||
flw_contextFragment();
|
||||
}
|
||||
"""
|
||||
);
|
||||
|
||||
return footer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _destroy(GlShader value) {
|
||||
value.delete();
|
||||
|
@ -48,9 +110,9 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
|||
*/
|
||||
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.
|
||||
|
@ -62,7 +124,13 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
|||
*/
|
||||
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.fogType = fogType;
|
||||
this.ctx = ctx;
|
||||
|
@ -84,18 +152,17 @@ public class FragmentCompiler extends Memoizer<FragmentCompiler.Context, GlShade
|
|||
if (obj == this) return true;
|
||||
if (obj == null || obj.getClass() != this.getClass()) return false;
|
||||
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
|
||||
public int hashCode() {
|
||||
return Objects.hash(alphaDiscard, fogType, ctx);
|
||||
return Objects.hash(materialShader, alphaDiscard, fogType, ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
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.
|
||||
* @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 fragmentContextShader The context shader to use when compiling fragment shaders.
|
||||
* @param <P> The type of program to compile.
|
||||
* @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) {
|
||||
return new ProgramCompiler<>(factory, new VertexCompiler(vertexTemplate, vertexContextShader), new FragmentCompiler(fragmentTemplate, fragmentContextShader));
|
||||
public static <P extends GlProgram> ProgramCompiler<P> create(GlProgram.Factory<P> factory, FileResolution vertexContextShader, FileResolution 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
|
||||
protected P _create(ProgramContext ctx) {
|
||||
return new ProgramAssembler(ctx.instanceShader.getFileLoc())
|
||||
.attachShader(vertexCompiler.get(new VertexCompiler.Context(ctx.vertexType, ctx.instanceShader.getFile(), ctx.ctx)))
|
||||
.attachShader(fragmentCompiler.get(new FragmentCompiler.Context(ctx.alphaDiscard, ctx.fogType, 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.fragmentMaterialShader.getFile(), ctx.alphaDiscard, ctx.fogType, ctx.ctx)))
|
||||
.link()
|
||||
.build(this.factory);
|
||||
}
|
||||
|
|
|
@ -14,20 +14,26 @@ public final class ProgramContext {
|
|||
|
||||
public final VertexType vertexType;
|
||||
public final FileResolution instanceShader;
|
||||
public final FileResolution vertexMaterialShader;
|
||||
public final FileResolution fragmentMaterialShader;
|
||||
public final float alphaDiscard;
|
||||
public final FogType fogType;
|
||||
public final StateSnapshot ctx;
|
||||
|
||||
/**
|
||||
* @param vertexType The vertexType the program should be adapted for.
|
||||
* @param spec The program to use.
|
||||
* @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.
|
||||
* @param vertexType The vertexType the program should be adapted for.
|
||||
* @param instanceShader The instance shader to use.
|
||||
* @param vertexMaterialShader The vertex material shader to use.
|
||||
* @param fragmentMaterialShader The fragment material shader to use.
|
||||
* @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.instanceShader = instanceShader;
|
||||
this.vertexMaterialShader = vertexMaterialShader;
|
||||
this.fragmentMaterialShader = fragmentMaterialShader;
|
||||
this.alphaDiscard = alphaDiscard;
|
||||
this.fogType = fogType;
|
||||
this.ctx = ctx;
|
||||
|
@ -38,16 +44,16 @@ public final class ProgramContext {
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
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
|
||||
public int hashCode() {
|
||||
return Objects.hash(vertexType, instanceShader, alphaDiscard, fogType, ctx);
|
||||
return Objects.hash(vertexType, instanceShader, vertexMaterialShader, fragmentMaterialShader, alphaDiscard, fogType, ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
|
||||
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.backend.gl.GLSLVersion;
|
||||
import com.jozufozu.flywheel.backend.gl.shader.GlShader;
|
||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||
import com.jozufozu.flywheel.core.shader.StateSnapshot;
|
||||
import com.jozufozu.flywheel.core.source.FileIndexImpl;
|
||||
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.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> {
|
||||
private final Template<? extends VertexData> template;
|
||||
private final FileResolution contextShader;
|
||||
|
||||
public VertexCompiler(Template<? extends VertexData> template, FileResolution contextShader) {
|
||||
this.template = template;
|
||||
public VertexCompiler(FileResolution contextShader) {
|
||||
this.contextShader = contextShader;
|
||||
}
|
||||
|
||||
|
@ -23,24 +31,171 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
|||
protected GlShader _create(Context key) {
|
||||
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);
|
||||
finalSource.append('\n');
|
||||
|
||||
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);
|
||||
finalSource.append(appliedTemplate.generateFooter(index, key.vertexType));
|
||||
if (maybeLayoutVertex.isEmpty()) {
|
||||
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
|
||||
|
@ -59,14 +214,20 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
|||
*/
|
||||
private final SourceFile instanceShader;
|
||||
|
||||
/**
|
||||
* The vertex material shader source.
|
||||
*/
|
||||
private final SourceFile materialShader;
|
||||
|
||||
/**
|
||||
* The shader constants to apply.
|
||||
*/
|
||||
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.instanceShader = instanceShader;
|
||||
this.materialShader = materialShader;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
|
@ -75,12 +236,12 @@ public class VertexCompiler extends Memoizer<VertexCompiler.Context, GlShader> {
|
|||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
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
|
||||
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;
|
||||
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.api.InstancerManager;
|
||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||
|
||||
public class CrumblingInstanceManager extends BlockEntityInstanceManager {
|
||||
|
||||
public CrumblingInstanceManager(MaterialManager materialManager) {
|
||||
super(materialManager);
|
||||
public CrumblingInstanceManager(InstancerManager instancerManager) {
|
||||
super(instancerManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.jozufozu.flywheel.backend.Backend;
|
|||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||
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.core.Contexts;
|
||||
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
|
||||
|
@ -65,7 +65,7 @@ public class CrumblingRenderer {
|
|||
|
||||
State state = STATE.get();
|
||||
var instanceManager = state.instanceManager;
|
||||
var engine = state.materialManager;
|
||||
var engine = state.instancerManager;
|
||||
|
||||
TextureManager textureManager = Minecraft.getInstance().getTextureManager();
|
||||
Camera info = Minecraft.getInstance().gameRenderer.getMainCamera();
|
||||
|
@ -140,17 +140,17 @@ public class CrumblingRenderer {
|
|||
}
|
||||
|
||||
private static class State {
|
||||
private final CrumblingEngine materialManager;
|
||||
private final CrumblingEngine instancerManager;
|
||||
private final InstanceManager<BlockEntity> instanceManager;
|
||||
|
||||
private State() {
|
||||
materialManager = new CrumblingEngine();
|
||||
instanceManager = new CrumblingInstanceManager(materialManager);
|
||||
materialManager.addListener(instanceManager);
|
||||
instancerManager = new CrumblingEngine();
|
||||
instanceManager = new CrumblingInstanceManager(instancerManager);
|
||||
instancerManager.addListener(instanceManager);
|
||||
}
|
||||
|
||||
private void kill() {
|
||||
materialManager.delete();
|
||||
instancerManager.delete();
|
||||
instanceManager.invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -190,10 +190,10 @@ public class CrumblingRenderer {
|
|||
Textures.bindActiveTextures();
|
||||
CoreShaderInfo coreShaderInfo = getCoreShaderInfo();
|
||||
|
||||
for (Map.Entry<Instanced<? extends InstanceData>, InstancedMaterial<?>> entry : materials.entrySet()) {
|
||||
CrumblingProgram program = setup(entry.getKey(), coreShaderInfo, camX, camY, camZ, viewProjection, level);
|
||||
for (Map.Entry<Instanced<? extends InstanceData>, GPUInstancerFactory<?>> entry : factories.entrySet()) {
|
||||
//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);
|
||||
}
|
||||
|
|
|
@ -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 net.minecraft.client.renderer.RenderType;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
|
||||
public interface ModelSupplier {
|
||||
|
||||
Map<RenderType, Mesh> get();
|
||||
Map<Material, Mesh> get();
|
||||
|
||||
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.util.Color;
|
|
@ -1,4 +1,4 @@
|
|||
package com.jozufozu.flywheel.core.materials;
|
||||
package com.jozufozu.flywheel.core.structs;
|
||||
|
||||
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;
|
||||
|
|
@ -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.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.mojang.blaze3d.vertex.PoseStack;
|
||||
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.Instanced;
|
||||
|
@ -6,9 +6,9 @@ import com.jozufozu.flywheel.api.struct.StructWriter;
|
|||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
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.source.FileResolution;
|
||||
import com.jozufozu.flywheel.core.structs.InstanceShaders;
|
||||
|
||||
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.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.core.materials.BasicWriterUnsafe;
|
||||
import com.jozufozu.flywheel.core.structs.BasicWriterUnsafe;
|
||||
import com.jozufozu.flywheel.util.MatrixWrite;
|
||||
|
||||
public class ModelWriterUnsafe extends BasicWriterUnsafe<ModelData> {
|
|
@ -1,5 +1,5 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.core.materials.model;
|
||||
package com.jozufozu.flywheel.core.structs.model;
|
||||
|
||||
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.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.Instanced;
|
||||
|
@ -6,9 +6,9 @@ import com.jozufozu.flywheel.api.struct.StructWriter;
|
|||
import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
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.source.FileResolution;
|
||||
import com.jozufozu.flywheel.core.structs.InstanceShaders;
|
||||
import com.mojang.math.Quaternion;
|
||||
|
||||
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 com.jozufozu.flywheel.api.struct.StructType;
|
||||
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 OrientedWriterUnsafe(VecBuffer backingBuffer, StructType<OrientedData> vertexType) {
|
|
@ -1,5 +1,5 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.core.materials.oriented;
|
||||
package com.jozufozu.flywheel.core.structs.oriented;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.core.materials;
|
||||
package com.jozufozu.flywheel.core.structs;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
|
@ -2,13 +2,15 @@ package com.jozufozu.flywheel.vanilla;
|
|||
|
||||
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.material.Material;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.Materials;
|
||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||
import com.jozufozu.flywheel.core.structs.oriented.OrientedData;
|
||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||
import com.mojang.math.Quaternion;
|
||||
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 {
|
||||
|
||||
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 float lastRingTime = Float.NaN;
|
||||
|
||||
public BellInstance(MaterialManager materialManager, BellBlockEntity blockEntity) {
|
||||
super(materialManager, blockEntity);
|
||||
public BellInstance(InstancerManager instancerManager, BellBlockEntity blockEntity) {
|
||||
super(instancerManager, blockEntity);
|
||||
|
||||
bell = createBellInstance()
|
||||
.setPivot(0.5f, 0.75f, 0.5f)
|
||||
|
@ -63,7 +65,7 @@ public class BellInstance extends BlockEntityInstance<BellBlockEntity> implement
|
|||
}
|
||||
|
||||
private OrientedData createBellInstance() {
|
||||
return materialManager.material(Materials.ORIENTED)
|
||||
return instancerManager.factory(StructTypes.ORIENTED)
|
||||
.model(MODEL)
|
||||
.createInstance();
|
||||
}
|
||||
|
|
|
@ -5,14 +5,15 @@ import java.util.function.BiFunction;
|
|||
|
||||
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.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.Materials;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.materials.oriented.OrientedData;
|
||||
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||
import com.jozufozu.flywheel.core.structs.StructTypes;
|
||||
import com.jozufozu.flywheel.core.structs.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.structs.oriented.OrientedData;
|
||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||
import com.mojang.math.Quaternion;
|
||||
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 {
|
||||
|
||||
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> BASE = Util.memoize((type, mat) -> new BasicModelSupplier(() -> createBaseModel(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()), new com.jozufozu.flywheel.api.material.Material(Sheets.chestSheet(), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT)));
|
||||
|
||||
private final OrientedData body;
|
||||
private final ModelData lid;
|
||||
|
@ -47,8 +48,8 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
|||
|
||||
private float lastProgress = Float.NaN;
|
||||
|
||||
public ChestInstance(MaterialManager materialManager, T blockEntity) {
|
||||
super(materialManager, blockEntity);
|
||||
public ChestInstance(InstancerManager instancerManager, T blockEntity) {
|
||||
super(instancerManager, blockEntity);
|
||||
|
||||
Block block = blockState.getBlock();
|
||||
|
||||
|
@ -67,7 +68,7 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
|||
|
||||
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));
|
||||
|
||||
|
@ -115,14 +116,14 @@ public class ChestInstance<T extends BlockEntity & LidBlockEntity> extends Block
|
|||
|
||||
private OrientedData baseInstance() {
|
||||
|
||||
return materialManager.material(Materials.ORIENTED)
|
||||
return instancerManager.factory(StructTypes.ORIENTED)
|
||||
.model(BASE.apply(chestType, renderMaterial))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private ModelData lidInstance() {
|
||||
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
return instancerManager.factory(StructTypes.MODEL)
|
||||
.model(LID.apply(chestType, renderMaterial))
|
||||
.createInstance();
|
||||
}
|
||||
|
|
|
@ -2,16 +2,18 @@ package com.jozufozu.flywheel.vanilla;
|
|||
|
||||
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.TickableInstance;
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
|
||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||
import com.jozufozu.flywheel.core.Models;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.Materials;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||
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.transform.TransformStack;
|
||||
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 {
|
||||
|
||||
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();
|
||||
|
||||
|
@ -37,8 +39,8 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
|
|||
private ModelData contents;
|
||||
private BlockState blockstate;
|
||||
|
||||
public MinecartInstance(MaterialManager materialManager, T entity) {
|
||||
super(materialManager, entity);
|
||||
public MinecartInstance(InstancerManager instancerManager, T entity) {
|
||||
super(instancerManager, entity);
|
||||
|
||||
blockstate = entity.getDisplayBlockState();
|
||||
contents = getContents();
|
||||
|
@ -63,7 +65,7 @@ public class MinecartInstance<T extends AbstractMinecart> extends EntityInstance
|
|||
stack.setIdentity();
|
||||
float pt = AnimationTickHolder.getPartialTicks();
|
||||
|
||||
Vec3i originCoordinate = materialManager.getOriginCoordinate();
|
||||
Vec3i originCoordinate = instancerManager.getOriginCoordinate();
|
||||
tstack.translate(
|
||||
Mth.lerp(pt, entity.xOld, entity.getX()) - originCoordinate.getX(),
|
||||
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)
|
||||
return null;
|
||||
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
return instancerManager.factory(StructTypes.MODEL)
|
||||
.model(Models.block(blockstate))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private ModelData getBody() {
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
return instancerManager.factory(StructTypes.MODEL)
|
||||
.model(MODEL)
|
||||
.createInstance();
|
||||
}
|
||||
|
|
|
@ -2,13 +2,15 @@ package com.jozufozu.flywheel.vanilla;
|
|||
|
||||
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.material.Material;
|
||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||
import com.jozufozu.flywheel.core.BasicModelSupplier;
|
||||
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
|
||||
import com.jozufozu.flywheel.core.materials.Materials;
|
||||
import com.jozufozu.flywheel.core.materials.model.ModelData;
|
||||
import com.jozufozu.flywheel.core.material.MaterialShaders;
|
||||
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.transform.TransformStack;
|
||||
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 {
|
||||
|
||||
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> LID = Util.memoize(it -> new BasicModelSupplier(() -> makeLidModel(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), new Material(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), () -> MaterialShaders.SHADED_VERTEX, () -> MaterialShaders.DEFAULT_FRAGMENT)));
|
||||
|
||||
private final TextureAtlasSprite texture;
|
||||
|
||||
|
@ -37,8 +39,8 @@ public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntit
|
|||
|
||||
private float lastProgress = Float.NaN;
|
||||
|
||||
public ShulkerBoxInstance(MaterialManager materialManager, ShulkerBoxBlockEntity blockEntity) {
|
||||
super(materialManager, blockEntity);
|
||||
public ShulkerBoxInstance(InstancerManager instancerManager, ShulkerBoxBlockEntity blockEntity) {
|
||||
super(instancerManager, blockEntity);
|
||||
|
||||
DyeColor color = blockEntity.getColor();
|
||||
if (color == null) {
|
||||
|
@ -97,13 +99,13 @@ public class ShulkerBoxInstance extends BlockEntityInstance<ShulkerBoxBlockEntit
|
|||
}
|
||||
|
||||
private ModelData makeBaseInstance() {
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
return instancerManager.factory(StructTypes.MODEL)
|
||||
.model(BASE.apply(texture))
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
private ModelData makeLidInstance() {
|
||||
return materialManager.material(Materials.TRANSFORMED)
|
||||
return instancerManager.factory(StructTypes.MODEL)
|
||||
.model(LID.apply(texture))
|
||||
.createInstance();
|
||||
}
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
#use "flywheel:api/vertex.glsl"
|
||||
#use "flywheel:util/diffuse.glsl"
|
||||
#use "flywheel:util/fog.glsl"
|
||||
|
||||
uniform mat4 uViewProjection;
|
||||
uniform vec3 uCameraPos;
|
||||
uniform int uConstantAmbientLight;
|
||||
uniform int uFogShape;
|
||||
|
||||
out float _flw_diffuse;
|
||||
|
||||
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);
|
||||
gl_Position = uViewProjection * flw_vertexPos;
|
||||
|
||||
|
|
|
@ -8,15 +8,13 @@ uniform vec2 uTextureScale;
|
|||
uniform sampler2D uBlockAtlas;
|
||||
uniform sampler2D uCrumbling;
|
||||
|
||||
in float _flw_diffuse;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void flw_contextFragment() {
|
||||
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
||||
vec4 crumblingColor = texture(uCrumbling, flw_vertexTexCoord * uTextureScale);
|
||||
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
|
||||
if (color.a < ALPHA_DISCARD) {
|
||||
|
|
|
@ -14,14 +14,12 @@ uniform vec4 uFogColor;
|
|||
uniform sampler2D uBlockAtlas;
|
||||
uniform sampler2D uLightMap;
|
||||
|
||||
in float _flw_diffuse;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void flw_contextFragment() {
|
||||
vec4 texColor = texture(uBlockAtlas, flw_vertexTexCoord);
|
||||
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
|
||||
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