diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/Batched.java b/src/main/java/com/jozufozu/flywheel/api/struct/BatchedStructType.java similarity index 71% rename from src/main/java/com/jozufozu/flywheel/api/struct/Batched.java rename to src/main/java/com/jozufozu/flywheel/api/struct/BatchedStructType.java index 239e088ca..52eeacf85 100644 --- a/src/main/java/com/jozufozu/flywheel/api/struct/Batched.java +++ b/src/main/java/com/jozufozu/flywheel/api/struct/BatchedStructType.java @@ -2,7 +2,6 @@ package com.jozufozu.flywheel.api.struct; import com.jozufozu.flywheel.core.model.ModelTransformer; -public interface Batched extends StructType { - +public interface BatchedStructType extends StructType { void transform(S d, ModelTransformer.Params b); } diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/Instanced.java b/src/main/java/com/jozufozu/flywheel/api/struct/InstancedStructType.java similarity index 87% rename from src/main/java/com/jozufozu/flywheel/api/struct/Instanced.java rename to src/main/java/com/jozufozu/flywheel/api/struct/InstancedStructType.java index c7d2b8f45..3a6ac7440 100644 --- a/src/main/java/com/jozufozu/flywheel/api/struct/Instanced.java +++ b/src/main/java/com/jozufozu/flywheel/api/struct/InstancedStructType.java @@ -3,7 +3,7 @@ package com.jozufozu.flywheel.api.struct; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.source.FileResolution; -public interface Instanced extends StructType { +public interface InstancedStructType extends StructType { /** * Create a {@link StructWriter} that will consume instances of S and write them to the given buffer. * diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java index feadbdc6f..a925d903d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlShader.java @@ -30,6 +30,7 @@ public class GlShader extends GlObject { GlCompat.safeShaderSource(handle, source); GL20.glCompileShader(handle); + // TODO: control this via a JVM flag or other dumpSource(source, type); // String log = GL20.glGetShaderInfoLog(handle); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java index b4f7b561f..4e7452984 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java @@ -141,19 +141,19 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift if (tick.shouldUpdate(dX, dY, dZ)) instance.tick(); } - public void beginFrame(TaskEngine taskEngine, Camera info) { + public void beginFrame(TaskEngine taskEngine, Camera camera) { frame.tick(); processQueuedAdditions(); - Vector3f look = info.getLookVector(); + Vector3f look = camera.getLookVector(); float lookX = look.x(); float lookY = look.y(); float lookZ = look.z(); // integer camera pos - int cX = (int) info.getPosition().x; - int cY = (int) info.getPosition().y; - int cZ = (int) info.getPosition().z; + int cX = (int) camera.getPosition().x; + int cY = (int) camera.getPosition().y; + int cZ = (int) camera.getPosition().z; ArrayList instances = new ArrayList<>(dynamicInstances.values()); int incr = 500; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index b162990d6..d324b953f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -5,7 +5,7 @@ import java.util.Map; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.MaterialGroup; -import com.jozufozu.flywheel.api.struct.Batched; +import com.jozufozu.flywheel.api.struct.BatchedStructType; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker; import com.jozufozu.flywheel.backend.instancing.TaskEngine; @@ -17,7 +17,7 @@ public class BatchedMaterialGroup implements MaterialGroup { protected final RenderType state; - private final Map, CPUInstancerFactory> materials = new HashMap<>(); + private final Map, CPUInstancerFactory> materials = new HashMap<>(); private int vertexCount; private int instanceCount; @@ -28,7 +28,7 @@ public class BatchedMaterialGroup implements MaterialGroup { @SuppressWarnings("unchecked") @Override public CPUInstancerFactory material(StructType type) { - if (type instanceof Batched batched) { + if (type instanceof BatchedStructType batched) { return (CPUInstancerFactory) materials.computeIfAbsent(batched, CPUInstancerFactory::new); } else { throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing."); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java index ddc5f949a..1049bb041 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Map; import com.jozufozu.flywheel.api.InstanceData; -import com.jozufozu.flywheel.api.struct.Batched; +import com.jozufozu.flywheel.api.struct.BatchedStructType; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker; import com.jozufozu.flywheel.backend.instancing.Engine; @@ -21,13 +21,13 @@ import net.minecraft.core.Vec3i; public class BatchingEngine implements Engine { - private final Map, CPUInstancerFactory> factories = new HashMap<>(); + private final Map, CPUInstancerFactory> factories = new HashMap<>(); private final BatchDrawingTracker batchTracker = new BatchDrawingTracker(); @SuppressWarnings("unchecked") @Override public CPUInstancerFactory factory(StructType type) { - if (type instanceof Batched batched) { + if (type instanceof BatchedStructType batched) { return (CPUInstancerFactory) factories.computeIfAbsent(batched, CPUInstancerFactory::new); } else { throw new ClassCastException("Cannot use type '" + type + "' with CPU instancing."); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java index e625a7f9f..2807e55f8 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.backend.instancing.batching; import com.jozufozu.flywheel.api.InstanceData; -import com.jozufozu.flywheel.api.struct.Batched; +import com.jozufozu.flywheel.api.struct.BatchedStructType; import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; @@ -14,7 +14,7 @@ public class CPUInstancer extends AbstractInstancer { // // final ModelTransformer sbb; - public CPUInstancer(Batched type) { + public CPUInstancer(BatchedStructType type) { super(type::create); // batchingType = type; // diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancerFactory.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancerFactory.java index 65413245f..00a9ded88 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancerFactory.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancerFactory.java @@ -6,7 +6,7 @@ import java.util.Map; import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.InstancerFactory; -import com.jozufozu.flywheel.api.struct.Batched; +import com.jozufozu.flywheel.api.struct.BatchedStructType; import com.jozufozu.flywheel.core.model.ModelSupplier; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -14,9 +14,9 @@ import com.mojang.blaze3d.vertex.VertexConsumer; public class CPUInstancerFactory implements InstancerFactory { protected final Map> models; - private final Batched type; + private final BatchedStructType type; - public CPUInstancerFactory(Batched type) { + public CPUInstancerFactory(BatchedStructType type) { this.type = type; this.models = new HashMap<>(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index d30d9183f..2886260cd 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -7,7 +7,7 @@ import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.InstanceData; -import com.jozufozu.flywheel.api.struct.Instanced; +import com.jozufozu.flywheel.api.struct.InstancedStructType; import com.jozufozu.flywheel.api.struct.StructWriter; import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; @@ -19,7 +19,7 @@ import com.jozufozu.flywheel.core.layout.BufferLayout; public class GPUInstancer extends AbstractInstancer { final BufferLayout instanceFormat; - final Instanced instancedType; + final InstancedStructType instancedType; GlBuffer vbo; int attributeBaseIndex; @@ -27,7 +27,7 @@ public class GPUInstancer extends AbstractInstancer { boolean anyToUpdate; - public GPUInstancer(Instanced type) { + public GPUInstancer(InstancedStructType type) { super(type::create); this.instanceFormat = type.getLayout(); instancedType = type; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancerFactory.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancerFactory.java index 161bb12dd..3783e815c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancerFactory.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancerFactory.java @@ -12,7 +12,7 @@ import com.jozufozu.flywheel.api.InstanceData; import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.InstancerFactory; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.api.struct.Instanced; +import com.jozufozu.flywheel.api.struct.InstancedStructType; import com.jozufozu.flywheel.backend.model.MeshPool; import com.jozufozu.flywheel.core.model.ModelSupplier; @@ -25,14 +25,15 @@ import net.minecraft.client.renderer.RenderType; public class GPUInstancerFactory implements InstancerFactory { protected final Map> models = new HashMap<>(); - protected final Instanced type; + protected final InstancedStructType type; protected final List> uninitialized = new ArrayList<>(); - protected final Multimap materials = HashMultimap.create(); - protected final Multimap renderables = ArrayListMultimap.create(); + // FIXME: these should not be public + public final Multimap materials = HashMultimap.create(); + public final Multimap renderables = ArrayListMultimap.create(); - public GPUInstancerFactory(Instanced type) { + public GPUInstancerFactory(InstancedStructType type) { this.type = type; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java index 75d3573ec..254f1330f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java @@ -10,7 +10,7 @@ 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.InstancedStructType; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.TaskEngine; @@ -44,7 +44,7 @@ public class InstancingEngine

implements Engine { protected final ProgramCompiler

context; private MeshPool allocator; - protected final Map, GPUInstancerFactory> factories = new HashMap<>(); + protected final Map, GPUInstancerFactory> factories = new HashMap<>(); protected final Set toRender = new HashSet<>(); @@ -62,7 +62,7 @@ public class InstancingEngine

implements Engine { @NotNull @Override public GPUInstancerFactory factory(StructType type) { - if (type instanceof Instanced instanced) { + if (type instanceof InstancedStructType instanced) { return (GPUInstancerFactory) factories.computeIfAbsent(instanced, GPUInstancerFactory::new); } else { throw new ClassCastException("Cannot use type '" + type + "' with GPU instancing."); @@ -108,8 +108,8 @@ public class InstancingEngine

implements Engine { Textures.bindActiveTextures(); CoreShaderInfo coreShaderInfo = getCoreShaderInfo(); - for (Map.Entry, GPUInstancerFactory> entry : factories.entrySet()) { - Instanced instanceType = entry.getKey(); + for (Map.Entry, GPUInstancerFactory> entry : factories.entrySet()) { + InstancedStructType instanceType = entry.getKey(); GPUInstancerFactory factory = entry.getValue(); var materials = factory.materials.get(type); @@ -146,7 +146,7 @@ public class InstancingEngine

implements Engine { return coreShaderInfo; } - protected P setup(Instanced instanceType, Material material, CoreShaderInfo coreShaderInfo, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) { + protected P setup(InstancedStructType 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; @@ -201,7 +201,6 @@ public class InstancingEngine

implements Engine { } allocator.flush(); - } private void checkOriginDistance(Camera info) { diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java index ed135bf6e..60d53a657 100644 --- a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java @@ -69,6 +69,7 @@ public class ProgramCompiler

extends Memoizer sheetData = new HashMap<>(); - - @Nullable - public static TextureAtlas getAtlas(ResourceLocation name) { - AbstractTexture texture = Minecraft.getInstance().getTextureManager().getTexture(name); - - if (texture instanceof TextureAtlas atlas) - return atlas; - else - return null; - } - - @Nullable - public static SheetSize getSheetSize(@Nullable ResourceLocation loc) { - return sheetData.get(loc); - } - - /** - * FOR USE IN MIXIN - */ - public static void _setAtlasData(ResourceLocation atlas, SheetDataAccessor accessor) { - sheetData.put(atlas, new SheetSize(accessor.flywheel$getWidth(), accessor.flywheel$getHeight())); - } - - public record SheetSize(int width, int height) { - } -} diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java index fddee3b91..029eda031 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingProgram.java @@ -1,42 +1,18 @@ package com.jozufozu.flywheel.core.crumbling; -import static org.lwjgl.opengl.GL20.glUniform2f; - import com.jozufozu.flywheel.core.shader.WorldProgram; -import net.minecraft.client.renderer.texture.TextureAtlas; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.inventory.InventoryMenu; public class CrumblingProgram extends WorldProgram { - protected final int uTextureScale; - protected int uCrumbling; + protected int uCrumblingTex; public CrumblingProgram(ResourceLocation name, int handle) { super(name, handle); - - uTextureScale = getUniformLocation("uTextureScale"); } @Override protected void registerSamplers() { - super.registerSamplers(); - uCrumbling = setSamplerBinding("uCrumbling", 4); + uCrumblingTex = setSamplerBinding("uCrumblingTex", 0); } - - public void setTextureScale(float x, float y) { - glUniform2f(uTextureScale, x, y); - } - - public void setAtlasSize(int width, int height) { - TextureAtlas blockAtlas = AtlasInfo.getAtlas(InventoryMenu.BLOCK_ATLAS); - if (blockAtlas == null) return; - - TextureAtlasSprite sprite = blockAtlas.getSprite(ModelBakery.BREAKING_LOCATIONS.get(0)); - - setTextureScale(width / (float) sprite.getWidth(), height / (float) sprite.getHeight()); - } - } diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java index 50a8a480d..5a9906a34 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java @@ -6,13 +6,15 @@ import java.util.Map; import java.util.SortedSet; import com.jozufozu.flywheel.api.InstanceData; -import com.jozufozu.flywheel.api.struct.Instanced; +import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.struct.InstancedStructType; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.gl.GlTextureUnit; +import com.jozufozu.flywheel.backend.gl.GlStateTracker; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.SerialTaskEngine; import com.jozufozu.flywheel.backend.instancing.instancing.GPUInstancerFactory; import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine; +import com.jozufozu.flywheel.backend.instancing.instancing.Renderable; import com.jozufozu.flywheel.core.Contexts; import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo; import com.jozufozu.flywheel.core.RenderContext; @@ -20,101 +22,110 @@ import com.jozufozu.flywheel.event.ReloadRenderersEvent; import com.jozufozu.flywheel.mixin.LevelRendererAccessor; import com.jozufozu.flywheel.util.Lazy; import com.jozufozu.flywheel.util.Textures; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import net.minecraft.client.Camera; -import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.AbstractTexture; -import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.core.BlockPos; import net.minecraft.server.level.BlockDestructionProgress; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +// TODO: merge directly into InstancingEngine for efficiency /** - * Responsible for rendering the block breaking overlay for instanced block entities. + * Responsible for rendering the crumbling overlay for instanced block entities. */ @Mod.EventBusSubscriber(Dist.CLIENT) public class CrumblingRenderer { - static RenderType _currentLayer; - private static Lazy STATE; static { _init(); } - public static void renderBreaking(ClientLevel level, PoseStack stack, double x, double y, double z, Matrix4f viewProjection) { - + public static void renderCrumbling(LevelRenderer levelRenderer, ClientLevel level, PoseStack poseStack, Camera camera, Matrix4f projectionMatrix) { if (!Backend.canUseInstancing(level)) return; - Int2ObjectMap> activeStages = getActiveStageBlockEntities(level); - + Int2ObjectMap> activeStages = getActiveStageBlockEntities(levelRenderer, level); if (activeStages.isEmpty()) return; + GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); + + Matrix4f viewProjection = poseStack.last() + .pose() + .copy(); + viewProjection.multiplyBackward(projectionMatrix); + State state = STATE.get(); var instanceManager = state.instanceManager; var engine = state.instancerManager; - TextureManager textureManager = Minecraft.getInstance().getTextureManager(); - Camera info = Minecraft.getInstance().gameRenderer.getMainCamera(); + renderCrumblingInner(activeStages, instanceManager, engine, level, poseStack, camera, viewProjection); + + restoreState.restore(); + } + + private static void renderCrumblingInner(Int2ObjectMap> activeStages, InstanceManager instanceManager, CrumblingEngine engine, ClientLevel level, PoseStack stack, Camera camera, Matrix4f viewProjection) { + Vec3 cameraPos = camera.getPosition(); + RenderContext ctx = new RenderContext(level, stack, viewProjection, null, cameraPos.x, cameraPos.y, cameraPos.z); for (Int2ObjectMap.Entry> stage : activeStages.int2ObjectEntrySet()) { - _currentLayer = ModelBakery.DESTROY_TYPES.get(stage.getIntKey()); + RenderType currentLayer = ModelBakery.DESTROY_TYPES.get(stage.getIntKey()); // something about when we call this means that the textures are not ready for use on the first frame they should appear - if (_currentLayer != null) { + if (currentLayer != null) { + engine.currentLayer = currentLayer; + stage.getValue().forEach(instanceManager::add); - instanceManager.beginFrame(SerialTaskEngine.INSTANCE, info); - engine.beginFrame(info); - - var ctx = new RenderContext(level, stack, viewProjection, null, x, y, z); + instanceManager.beginFrame(SerialTaskEngine.INSTANCE, camera); + engine.beginFrame(camera); engine.renderAllRemaining(SerialTaskEngine.INSTANCE, ctx); instanceManager.invalidate(); } - } - - GlTextureUnit.T0.makeActive(); - AbstractTexture breaking = textureManager.getTexture(ModelBakery.BREAKING_LOCATIONS.get(0)); - if (breaking != null) RenderSystem.bindTexture(breaking.getId()); } /** * Associate each breaking stage with a list of all block entities at that stage. */ - private static Int2ObjectMap> getActiveStageBlockEntities(ClientLevel world) { + private static Int2ObjectMap> getActiveStageBlockEntities(LevelRenderer levelRenderer, ClientLevel level) { + Long2ObjectMap> destructionProgress = ((LevelRendererAccessor) levelRenderer).flywheel$getDestructionProgress(); + if (destructionProgress.isEmpty()) { + return Int2ObjectMaps.emptyMap(); + } Int2ObjectMap> breakingEntities = new Int2ObjectArrayMap<>(); + BlockPos.MutableBlockPos breakingPos = new BlockPos.MutableBlockPos(); - for (Long2ObjectMap.Entry> entry : ((LevelRendererAccessor) Minecraft.getInstance().levelRenderer).flywheel$getDestructionProgress() - .long2ObjectEntrySet()) { - BlockPos breakingPos = BlockPos.of(entry.getLongKey()); + for (Long2ObjectMap.Entry> entry : destructionProgress.long2ObjectEntrySet()) { + breakingPos.set(entry.getLongKey()); SortedSet progresses = entry.getValue(); if (progresses != null && !progresses.isEmpty()) { - int blockDamage = progresses.last() + int progress = progresses.last() .getProgress(); + if (progress >= 0) { + BlockEntity blockEntity = level.getBlockEntity(breakingPos); - BlockEntity blockEntity = world.getBlockEntity(breakingPos); - - if (blockEntity != null) { - List blockEntities = breakingEntities.computeIfAbsent(blockDamage, $ -> new ArrayList<>()); - blockEntities.add(blockEntity); + if (blockEntity != null) { + List blockEntities = breakingEntities.computeIfAbsent(progress, $ -> new ArrayList<>()); + blockEntities.add(blockEntity); + } } } } @@ -156,6 +167,7 @@ public class CrumblingRenderer { } private static class CrumblingEngine extends InstancingEngine { + private RenderType currentLayer; public CrumblingEngine() { super(Contexts.CRUMBLING); @@ -163,42 +175,32 @@ public class CrumblingRenderer { @Override protected void render(RenderType type, double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) { - type.setupRenderState(); - - int renderTex = RenderSystem.getShaderTexture(0); - - AtlasInfo.SheetSize sheetSize = AtlasInfo.getSheetSize(Textures.getShaderTexture(0)); - - int width; - int height; - if (sheetSize != null) { - width = sheetSize.width(); - height = sheetSize.height(); - } else { - width = height = 256; + if (!type.affectsCrumbling()) { + return; } - type.clearRenderState(); - - CrumblingRenderer._currentLayer.setupRenderState(); - - int breakingTex = RenderSystem.getShaderTexture(0); - - RenderSystem.setShaderTexture(0, renderTex); - RenderSystem.setShaderTexture(4, breakingTex); - + currentLayer.setupRenderState(); Textures.bindActiveTextures(); CoreShaderInfo coreShaderInfo = getCoreShaderInfo(); - for (Map.Entry, GPUInstancerFactory> entry : factories.entrySet()) { - //CrumblingProgram program = setup(entry.getKey(), coreShaderInfo, camX, camY, camZ, viewProjection, level); + for (Map.Entry, GPUInstancerFactory> entry : factories.entrySet()) { + InstancedStructType instanceType = entry.getKey(); + GPUInstancerFactory factory = entry.getValue(); - //program.setAtlasSize(width, height); + var materials = factory.materials.get(type); + for (Material material : materials) { + var toRender = factory.renderables.get(material); + toRender.removeIf(Renderable::shouldRemove); - //entry.getValue().getAllRenderables().forEach(Renderable::draw); + if (!toRender.isEmpty()) { + setup(instanceType, material, coreShaderInfo, camX, camY, camZ, viewProjection, level); + + toRender.forEach(Renderable::render); + } + } } - CrumblingRenderer._currentLayer.clearRenderState(); + currentLayer.clearRenderState(); } } } diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java b/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java index bd650eca2..0fe6eb734 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/WorldProgram.java @@ -40,6 +40,7 @@ public class WorldProgram extends GlProgram { uLightMap = setSamplerBinding("uLightMap", 2); } + // TODO: create uniform registry public void uploadUniforms(double camX, double camY, double camZ, Matrix4f viewProjection, ClientLevel level) { fog.uploadUniforms(); uploadTime(AnimationTickHolder.getRenderTime()); diff --git a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java index 56aa16e06..7332ae7cf 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java @@ -246,6 +246,7 @@ public class SourceFile { String fileName = file.get(); if (importedFiles.add(fileName)) { + // FIXME: creating imports after the first resource reload crashes the game var checked = Import.create(errorReporter, use, file); if (checked != null) { imports.add(checked); diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/model/ModelType.java b/src/main/java/com/jozufozu/flywheel/core/structs/model/ModelType.java index af0da82bf..e6547a3eb 100644 --- a/src/main/java/com/jozufozu/flywheel/core/structs/model/ModelType.java +++ b/src/main/java/com/jozufozu/flywheel/core/structs/model/ModelType.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.core.structs.model; -import com.jozufozu.flywheel.api.struct.Batched; -import com.jozufozu.flywheel.api.struct.Instanced; +import com.jozufozu.flywheel.api.struct.BatchedStructType; +import com.jozufozu.flywheel.api.struct.InstancedStructType; import com.jozufozu.flywheel.api.struct.StructWriter; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.layout.BufferLayout; @@ -10,7 +10,7 @@ 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, Batched { +public class ModelType implements InstancedStructType, BatchedStructType { public static final BufferLayout FORMAT = BufferLayout.builder() .addItems(CommonItems.LIGHT, CommonItems.RGBA) diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java index f11d2218e..07428287b 100644 --- a/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java +++ b/src/main/java/com/jozufozu/flywheel/core/structs/oriented/OrientedType.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.core.structs.oriented; -import com.jozufozu.flywheel.api.struct.Batched; -import com.jozufozu.flywheel.api.struct.Instanced; +import com.jozufozu.flywheel.api.struct.BatchedStructType; +import com.jozufozu.flywheel.api.struct.InstancedStructType; import com.jozufozu.flywheel.api.struct.StructWriter; import com.jozufozu.flywheel.backend.gl.buffer.VecBuffer; import com.jozufozu.flywheel.core.layout.BufferLayout; @@ -11,7 +11,7 @@ import com.jozufozu.flywheel.core.source.FileResolution; import com.jozufozu.flywheel.core.structs.InstanceShaders; import com.mojang.math.Quaternion; -public class OrientedType implements Instanced, Batched { +public class OrientedType implements InstancedStructType, BatchedStructType { public static final BufferLayout FORMAT = BufferLayout.builder() .addItems(CommonItems.LIGHT, CommonItems.RGBA) diff --git a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java index 53d1bcd7d..f730bd77e 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java @@ -4,6 +4,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -15,7 +16,6 @@ import com.jozufozu.flywheel.core.crumbling.CrumblingRenderer; import com.jozufozu.flywheel.event.BeginFrameEvent; import com.jozufozu.flywheel.event.ReloadRenderersEvent; import com.jozufozu.flywheel.event.RenderLayerEvent; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; @@ -74,22 +74,10 @@ public class LevelRendererMixin { MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(level)); } - - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;checkPoseStack(Lcom/mojang/blaze3d/vertex/PoseStack;)V", ordinal = 2 // after the game renders the breaking overlay normally + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;crumblingBufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 2, shift = Shift.BY, by = 2 // after the game renders the breaking overlay normally ), method = "renderLevel") - private void renderBlockBreaking(PoseStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, Camera info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) { - if (!Backend.isOn()) return; - - Vec3 cameraPos = info.getPosition(); - - Matrix4f viewProjection = stack.last() - .pose() - .copy(); - viewProjection.multiplyBackward(RenderSystem.getProjectionMatrix()); - - GlStateTracker.State restoreState = GlStateTracker.getRestoreState(); - CrumblingRenderer.renderBreaking(level, stack, cameraPos.x, cameraPos.y, cameraPos.z, viewProjection); - restoreState.restore(); + private void renderBlockBreaking(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) { + CrumblingRenderer.renderCrumbling((LevelRenderer) (Object) this, level, poseStack, camera, projectionMatrix); } // Instancing diff --git a/src/main/java/com/jozufozu/flywheel/mixin/RenderTexturesMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/RenderTexturesMixin.java deleted file mode 100644 index 083d2050f..000000000 --- a/src/main/java/com/jozufozu/flywheel/mixin/RenderTexturesMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.jozufozu.flywheel.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import com.jozufozu.flywheel.util.Textures; -import com.mojang.blaze3d.systems.RenderSystem; - -import net.minecraft.resources.ResourceLocation; - -@Mixin(RenderSystem.class) -public class RenderTexturesMixin { - - @Inject(method = "_setShaderTexture(ILnet/minecraft/resources/ResourceLocation;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/texture/AbstractTexture;getId()I")) - private static void storeTextureLoc(int pShaderTexture, ResourceLocation pTextureId, CallbackInfo ci) { - Textures._setShaderTexture(pShaderTexture, pTextureId); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/atlas/AtlasDataMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/atlas/AtlasDataMixin.java deleted file mode 100644 index 0df35f618..000000000 --- a/src/main/java/com/jozufozu/flywheel/mixin/atlas/AtlasDataMixin.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.jozufozu.flywheel.mixin.atlas; - -import java.util.stream.Stream; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import com.jozufozu.flywheel.core.crumbling.AtlasInfo; - -import net.minecraft.client.renderer.texture.TextureAtlas; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.util.profiling.ProfilerFiller; - -@Mixin(TextureAtlas.class) -public abstract class AtlasDataMixin { - - @Shadow - public abstract ResourceLocation location(); - - @Inject(method = "prepareToStitch", at = @At("RETURN")) - public void stealAtlasData(ResourceManager resourceManager, Stream locationStream, ProfilerFiller profiler, int mipMapLevels, CallbackInfoReturnable cir) { - AtlasInfo._setAtlasData(location(), (SheetDataAccessor) cir.getReturnValue()); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/atlas/SheetDataAccessor.java b/src/main/java/com/jozufozu/flywheel/mixin/atlas/SheetDataAccessor.java deleted file mode 100644 index a1914724b..000000000 --- a/src/main/java/com/jozufozu/flywheel/mixin/atlas/SheetDataAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.jozufozu.flywheel.mixin.atlas; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import net.minecraft.client.renderer.texture.TextureAtlas; - -@Mixin(TextureAtlas.Preparations.class) -public interface SheetDataAccessor { - - @Accessor("width") - int flywheel$getWidth(); - - @Accessor("height") - int flywheel$getHeight(); - -} diff --git a/src/main/java/com/jozufozu/flywheel/util/Textures.java b/src/main/java/com/jozufozu/flywheel/util/Textures.java index ea111cf87..f6292e966 100644 --- a/src/main/java/com/jozufozu/flywheel/util/Textures.java +++ b/src/main/java/com/jozufozu/flywheel/util/Textures.java @@ -1,33 +1,12 @@ package com.jozufozu.flywheel.util; -import org.jetbrains.annotations.Nullable; import org.lwjgl.opengl.GL32; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.renderer.RenderType; -import net.minecraft.resources.ResourceLocation; -/** - * Helper class to keep track of what texture atlases are bound to what texture units. - * - *

- * Works with {@link com.jozufozu.flywheel.mixin.RenderTexturesMixin}. - *

- */ public class Textures { - - private static final ResourceLocation[] shaderTextures = new ResourceLocation[12]; - - @Nullable - public static ResourceLocation getShaderTexture(int pShaderTexture) { - return shaderTextures[pShaderTexture]; - } - - public static void _setShaderTexture(int pShaderTexture, ResourceLocation pTextureId) { - shaderTextures[pShaderTexture] = pTextureId; - } - /** * Call this after calling {@link RenderType#setupRenderState()}. */ diff --git a/src/main/resources/assets/flywheel/flywheel/context/common.vert b/src/main/resources/assets/flywheel/flywheel/context/common.vert index 0cd5ab05f..d9e0807ea 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/common.vert +++ b/src/main/resources/assets/flywheel/flywheel/context/common.vert @@ -6,11 +6,12 @@ uniform vec3 uCameraPos; uniform int uFogShape; void flw_contextVertex() { - flw_distance = fog_distance(flw_vertexPos.xyz, uCameraPos, uFogShape); - gl_Position = uViewProjection * flw_vertexPos; - // TODO: remove this #ifdef DEBUG_NORMAL flw_vertexColor = vec4(flw_vertexNormal, 1.0); #endif + + flw_distance = fog_distance(flw_vertexPos.xyz, uCameraPos, uFogShape); + gl_Position = uViewProjection * flw_vertexPos; + flw_vertexNormal = normalize(flw_vertexNormal); } diff --git a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag index f8affbfe2..a7dffc948 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag +++ b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag @@ -3,18 +3,31 @@ uniform vec2 uFogRange; uniform vec4 uFogColor; -uniform vec2 uTextureScale; -uniform sampler2D uBlockAtlas; -uniform sampler2D uCrumbling; +uniform sampler2D uCrumblingTex; out vec4 fragColor; +vec2 flattenedPos(vec3 pos, vec3 normal) { + pos -= floor(pos) + vec3(0.5); + + float sinYRot = -normal.x; + float sqLength = normal.x * normal.x + normal.z * normal.z; + if (sqLength > 0) { + sinYRot /= sqrt(sqLength); + sinYRot = clamp(sinYRot, -1, 1); + } + + vec3 tangent = vec3(sqrt(1 - sinYRot * sinYRot) * (normal.z < 0 ? -1 : 1), 0, sinYRot); + vec3 bitangent = cross(tangent, normal); + mat3 tbn = mat3(tangent, bitangent, normal); + + // transpose is the same as inverse for orthonormal matrices + return (transpose(tbn) * pos).xy + vec2(0.5); +} + 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, crumblingColor.a); + vec4 color = texture(uCrumblingTex, flattenedPos(flw_vertexPos.xyz, flw_vertexNormal)); #ifdef ALPHA_DISCARD if (color.a < ALPHA_DISCARD) { diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json index d138c4efd..0f9d0df2e 100644 --- a/src/main/resources/flywheel.mixins.json +++ b/src/main/resources/flywheel.mixins.json @@ -22,10 +22,7 @@ "LevelRendererMixin", "MultiBufferSourceMixin", "PausedPartialTickAccessor", - "RenderTexturesMixin", "RenderTypeMixin", - "atlas.AtlasDataMixin", - "atlas.SheetDataAccessor", "light.LightUpdateMixin", "light.NetworkLightUpdateMixin", "matrix.Matrix3fMixin",