Merge remote-tracking branch 'origin/1.18/next' into 1.18/next

# Conflicts:
#	src/main/java/com/jozufozu/flywheel/api/material/Material.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java
#	src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
#	src/main/java/com/jozufozu/flywheel/core/BasicModelSupplier.java
#	src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingRenderer.java
#	src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java
#	src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
#	src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
#	src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
#	src/main/resources/flywheel.mixins.json
This commit is contained in:
Jozufozu 2022-07-22 17:33:29 -07:00
commit e43261302a
87 changed files with 463 additions and 643 deletions

View file

@ -4,8 +4,8 @@ import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.slf4j.Logger;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.ShadersModHandler;
import com.jozufozu.flywheel.backend.RenderWork;
import com.jozufozu.flywheel.backend.ShadersModHandler;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.model.MeshPool;
import com.jozufozu.flywheel.config.BackendTypeArgument;
@ -83,6 +83,7 @@ public class Flywheel {
forgeEventBus.addListener(CrumblingRenderer::onReloadRenderers);
forgeEventBus.addListener(InstancedRenderDispatcher::onReloadRenderers);
forgeEventBus.addListener(InstancedRenderDispatcher::onRenderStage);
forgeEventBus.addListener(InstancedRenderDispatcher::onBeginFrame);
forgeEventBus.addListener(InstancedRenderDispatcher::tick);

View file

@ -0,0 +1,16 @@
package com.jozufozu.flywheel.api;
public enum RenderStage {
BEFORE_SKY,
AFTER_SKY,
BEFORE_TERRAIN,
AFTER_SOLID_TERRAIN,
BEFORE_ENTITIES,
AFTER_ENTITIES,
AFTER_BLOCK_ENTITIES,
BEFORE_CRUMBLING,
AFTER_FINAL_END_BATCH,
AFTER_TRANSLUCENT_TERRAIN,
AFTER_PARTICLES,
AFTER_WEATHER;
}

View file

@ -1,7 +1,7 @@
package com.jozufozu.flywheel.api.instance;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
/**

View file

@ -1,7 +1,7 @@
package com.jozufozu.flywheel.api.instance;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
/**

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.api;
package com.jozufozu.flywheel.api.instancer;
import com.jozufozu.flywheel.api.struct.StructType;

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.api;
package com.jozufozu.flywheel.api.instancer;
/**
* An instancer is how you interact with an instanced model.

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.api;
package com.jozufozu.flywheel.api.instancer;
import com.jozufozu.flywheel.core.model.ModelSupplier;

View file

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.api;
package com.jozufozu.flywheel.api.instancer;
import com.jozufozu.flywheel.api.struct.StructType;

View file

@ -1,17 +1,17 @@
package com.jozufozu.flywheel.api.material;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.core.source.SourceFile;
import net.minecraft.client.renderer.RenderType;
public record Material(RenderType renderType, FileResolution vertexShader, FileResolution fragmentShader) {
public interface Material {
RenderStage getRenderStage();
public SourceFile getVertexShader() {
return vertexShader.getFile();
}
RenderType getRenderType();
public SourceFile getFragmentShader() {
return fragmentShader.getFile();
}
FileResolution getVertexShader();
FileResolution getFragmentShader();
}

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.api.struct;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.core.layout.BufferLayout;
import com.jozufozu.flywheel.core.model.ModelTransformer;
import com.jozufozu.flywheel.core.source.FileResolution;

View file

@ -17,7 +17,7 @@ import net.minecraft.world.level.LevelAccessor;
public class Backend {
public static final Logger LOGGER = LogUtils.getLogger();
public static boolean DUMP_SHADER_SOURCE = System.getProperty("flw.dumpShaderSource") != null;
public static final boolean DUMP_SHADER_SOURCE = System.getProperty("flw.dumpShaderSource") != null;
private static BackendType TYPE;

View file

@ -1,7 +1,5 @@
package com.jozufozu.flywheel.backend.gl;
import com.jozufozu.flywheel.backend.RenderWork;
// Utility class for safely dealing with gl object handles.
public abstract class GlObject {
private static final int INVALID_HANDLE = Integer.MIN_VALUE;

View file

@ -10,7 +10,6 @@ import org.lwjgl.opengl.GL43;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
public enum GlBufferType {
ARRAY_BUFFER(GL15C.GL_ARRAY_BUFFER),

View file

@ -22,7 +22,7 @@ public class GlShader extends GlObject {
private final List<ResourceLocation> parts;
private final ShaderConstants constants;
public GlShader(String source, ShaderType type, List<ResourceLocation> parts, ShaderConstants constants) {
public GlShader(String source, ShaderType type, List<ResourceLocation> parts, ShaderConstants constants) throws ShaderCompilationException {
this.parts = parts;
this.type = type;
this.constants = constants;

View file

@ -3,10 +3,10 @@ package com.jozufozu.flywheel.backend.instancing;
import java.util.Arrays;
import java.util.stream.Stream;
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.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
import com.jozufozu.flywheel.core.structs.FlatLit;
import com.jozufozu.flywheel.light.LightListener;

View file

@ -3,8 +3,8 @@ package com.jozufozu.flywheel.backend.instancing;
import java.util.ArrayList;
import java.util.BitSet;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.struct.StructType;
public abstract class AbstractInstancer<D extends InstancedPart> implements Instancer<D> {

View file

@ -1,9 +1,7 @@
package com.jozufozu.flywheel.backend.instancing;
import java.lang.ref.Cleaner;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.backend.FlywheelMemory;
import com.jozufozu.flywheel.backend.model.BufferBuilderExtension;
import com.jozufozu.flywheel.backend.model.DirectVertexConsumer;
import com.mojang.blaze3d.platform.MemoryTracker;

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.instancing;
import java.util.List;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
public interface Engine extends RenderDispatcher, InstancerManager {
void attachManagers(InstanceManager<?>... listener);

View file

@ -13,6 +13,7 @@ import com.jozufozu.flywheel.backend.instancing.ratelimit.BandedPrimeLimiter;
import com.jozufozu.flywheel.backend.instancing.ratelimit.DistanceUpdateLimiter;
import com.jozufozu.flywheel.backend.instancing.ratelimit.NonLimiter;
import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.light.LightUpdater;
import com.mojang.math.Vector3f;
@ -102,19 +103,21 @@ public abstract class InstanceManager<T> {
if (tick.shouldUpdate(dX, dY, dZ)) instance.tick();
}
public void beginFrame(TaskEngine taskEngine, Camera camera) {
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
frame.tick();
processQueuedAdditions();
Camera camera = context.camera();
Vector3f look = camera.getLookVector();
float lookX = look.x();
float lookY = look.y();
float lookZ = look.z();
// integer camera pos
int cX = (int) camera.getPosition().x;
int cY = (int) camera.getPosition().y;
int cZ = (int) camera.getPosition().z;
BlockPos cameraIntPos = camera.getBlockPosition();
int cX = cameraIntPos.getX();
int cY = cameraIntPos.getY();
int cZ = cameraIntPos.getZ();
var instances = getStorage().getInstancesForUpdate();
distributeWork(taskEngine, instances, instance -> updateInstance(instance, lookX, lookY, lookZ, cX, cY, cZ));

View file

@ -1,5 +1,6 @@
package com.jozufozu.flywheel.backend.instancing;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.TickableInstance;
import com.jozufozu.flywheel.backend.Backend;
@ -14,10 +15,8 @@ import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.util.ClientLevelExtension;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -91,18 +90,18 @@ public class InstanceWorld {
* </p>
*/
public void beginFrame(BeginFrameEvent event) {
Camera camera = event.getCamera();
boolean shifted = engine.maintainOriginCoordinate(camera);
RenderContext context = event.getContext();
boolean shifted = engine.maintainOriginCoordinate(context.camera());
taskEngine.syncPoint();
if (!shifted) {
blockEntities.beginFrame(taskEngine, camera);
entities.beginFrame(taskEngine, camera);
effects.beginFrame(taskEngine, camera);
blockEntities.beginFrame(taskEngine, context);
entities.beginFrame(taskEngine, context);
effects.beginFrame(taskEngine, context);
}
engine.beginFrame(taskEngine, camera);
engine.beginFrame(taskEngine, context);
}
/**
@ -130,24 +129,13 @@ public class InstanceWorld {
}
/**
* Draw the given layer.
* Draw all instances for the given stage.
*/
public void renderSpecificType(RenderContext context, RenderType type) {
public void renderStage(RenderContext context, RenderStage stage) {
taskEngine.syncPoint();
context.pushPose();
context.translateBack(context.camX(), context.camY(), context.camZ());
engine.renderSpecificType(taskEngine, context, type);
context.popPose();
}
/**
* Draw the given layer.
*/
public void renderAllRemaining(RenderContext context) {
taskEngine.syncPoint();
context.pushPose();
context.translateBack(context.camX(), context.camY(), context.camZ());
engine.renderAllRemaining(taskEngine, context);
context.translateBack(context.camera().getPosition());
engine.renderStage(taskEngine, context, stage);
context.popPose();
}

View file

@ -6,12 +6,11 @@ import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.effect.Effect;
import com.jozufozu.flywheel.config.FlwCommands;
import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.event.RenderStageEvent;
import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.WorldAttached;
import com.jozufozu.flywheel.vanilla.effect.ExampleEffect;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
@ -90,23 +89,16 @@ public class InstancedRenderDispatcher {
public static void onBeginFrame(BeginFrameEvent event) {
if (Backend.isGameActive() && Backend.isOn()) {
instanceWorlds.get(event.getWorld())
instanceWorlds.get(event.getContext().level())
.beginFrame(event);
}
}
public static void renderSpecificType(RenderContext context, RenderType type) {
ClientLevel world = context.level();
public static void onRenderStage(RenderStageEvent event) {
ClientLevel world = event.getContext().level();
if (!Backend.canUseInstancing(world)) return;
instanceWorlds.get(world).renderSpecificType(context, type);
}
public static void renderAllRemaining(RenderContext context) {
ClientLevel world = context.level();
if (!Backend.canUseInstancing(world)) return;
instanceWorlds.get(world).renderAllRemaining(context);
instanceWorlds.get(world).renderStage(event.getContext(), event.getStage());
}
public static void onReloadRenderers(ReloadRenderersEvent event) {

View file

@ -6,7 +6,7 @@ import java.util.function.Predicate;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.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;

View file

@ -4,13 +4,12 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
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.instancer.InstancerManager;
import com.jozufozu.flywheel.light.LightUpdater;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;

View file

@ -1,15 +1,13 @@
package com.jozufozu.flywheel.backend.instancing;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.core.RenderContext;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.RenderType;
public interface RenderDispatcher {
void renderAllRemaining(TaskEngine taskEngine, RenderContext context);
void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type);
void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage);
/**
* Maintain the integer origin coordinate to be within a certain distance from the camera in all directions,
@ -18,7 +16,7 @@ public interface RenderDispatcher {
*/
boolean maintainOriginCoordinate(Camera camera);
void beginFrame(TaskEngine taskEngine, Camera info);
void beginFrame(TaskEngine taskEngine, RenderContext context);
void delete();
}

View file

@ -10,7 +10,7 @@ import javax.annotation.Nonnull;
import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
import com.jozufozu.flywheel.backend.instancing.instancing.GPUInstancer;
@ -36,14 +36,14 @@ public class SadCrumbling {
// var map = modelsToParts(dataByStage);
// var stateSnapshot = GameStateRegistry.takeSnapshot();
//
//// Vec3 cameraPosition = camera.getPosition();
//// var camX = cameraPosition.x - originCoordinate.getX();
//// var camY = cameraPosition.y - originCoordinate.getY();
//// var camZ = cameraPosition.z - originCoordinate.getZ();
////
//// // don't want to mutate viewProjection
//// var vp = projectionMatrix.copy();
//// vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ);
// Vec3 cameraPosition = camera.getPosition();
// var camX = cameraPosition.x - originCoordinate.getX();
// var camY = cameraPosition.y - originCoordinate.getY();
// var camZ = cameraPosition.z - originCoordinate.getZ();
//
// // don't want to mutate viewProjection
// var vp = projectionMatrix.copy();
// vp.multiplyWithTranslation((float) -camX, (float) -camY, (float) -camZ);
//
// GlBuffer instanceBuffer = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER);
//
@ -75,17 +75,18 @@ public class SadCrumbling {
// continue;
// }
//
// material.renderType().setupRenderState();
// material.getRenderType().setupRenderState();
//
// CoreShaderInfoMap.CoreShaderInfo coreShaderInfo = CoreShaderInfoMap.CoreShaderInfo.get();
// CoreShaderInfo coreShaderInfo = CoreShaderInfo.get();
//
//
// var program = Compile.PROGRAM.getProgram(new ProgramCompiler.Context(Formats.POS_TEX_NORMAL,
// material, structType.getInstanceShader(), Components.CRUMBLING,
// CrumblingProgram program = Contexts.CRUMBLING.getProgram(new ProgramCompiler.Context(Formats.POS_TEX_NORMAL,
// structType.getInstanceShader(), material.getVertexShader(), material.getFragmentShader(),
// coreShaderInfo.getAdjustedAlphaDiscard(), coreShaderInfo.fogType(),
// GameStateRegistry.takeSnapshot()));
//
// program.bind();
// program.uploadUniforms(camX, camY, camZ, vp, level);
//
// // bufferedMesh.drawInstances();
// }
@ -107,7 +108,7 @@ public class SadCrumbling {
for (var blockEntityInstance : entry.getValue()) {
for (var part : blockEntityInstance.getCrumblingParts()) {
if (part.getOwner() instanceof GPUInstancer instancer) {
if (part.getOwner() instanceof GPUInstancer<?> instancer) {
// queue the instances for copying to the crumbling instance buffer
map.computeIfAbsent(instancer.parent.getModel(), k -> new ArrayList<>()).add(part);

View file

@ -12,6 +12,6 @@ public class BatchLists {
public final Map<RenderType, List<TransformSet<?>>> renderLists = new HashMap<>();
public void add(TransformSet<?> set) {
renderLists.computeIfAbsent(set.material.renderType(), k -> new ArrayList<>()).add(set);
renderLists.computeIfAbsent(set.material.getRenderType(), k -> new ArrayList<>()).add(set);
}
}

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.batching;
import java.util.List;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.core.model.ModelSupplier;

View file

@ -5,10 +5,14 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.ShadersModHandler;
import com.jozufozu.flywheel.backend.instancing.*;
import com.jozufozu.flywheel.backend.instancing.BatchDrawingTracker;
import com.jozufozu.flywheel.backend.instancing.Engine;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.util.FlwUtil;
import com.mojang.blaze3d.platform.Lighting;
@ -16,7 +20,6 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.world.phys.Vec3;
@ -65,13 +68,12 @@ public class BatchingEngine implements Engine {
}
@Override
public void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type) {
public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
// FIXME: properly support material stages
if (stage != RenderStage.AFTER_FINAL_END_BATCH) {
return;
}
@Override
public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) {
// FIXME: this probably breaks some vanilla stuff but it works much better for flywheel
Matrix4f mat = new Matrix4f();
mat.setIdentity();
@ -96,15 +98,15 @@ public class BatchingEngine implements Engine {
}
@Override
public void beginFrame(TaskEngine taskEngine, Camera info) {
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
for (var model : uninitializedModels) {
model.init(batchLists);
}
uninitializedModels.clear();
Vec3 cameraPos = info.getPosition();
var stack = FlwUtil.copyPoseStack(RenderContext.CURRENT.stack());
Vec3 cameraPos = context.camera().getPosition();
var stack = FlwUtil.copyPoseStack(context.stack());
stack.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
submitTasks(stack, taskEngine);
@ -118,7 +120,5 @@ public class BatchingEngine implements Engine {
@Override
public void addDebugInfo(List<String> info) {
info.add("Batching");
info.add("Instances: " + 0);
info.add("Vertices: " + 0);
}
}

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.batching;
import java.util.List;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;

View file

@ -4,9 +4,9 @@ import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.InstancerFactory;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.core.model.ModelSupplier;

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.batching;
import java.util.List;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
import com.jozufozu.flywheel.backend.model.DirectVertexConsumer;

View file

@ -3,11 +3,11 @@ package com.jozufozu.flywheel.backend.instancing.blockentity;
import java.util.ArrayList;
import java.util.List;
import com.jozufozu.flywheel.api.InstancedPart;
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.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.core.structs.StructTypes;
import com.jozufozu.flywheel.core.structs.model.TransformedPart;

View file

@ -2,11 +2,11 @@ package com.jozufozu.flywheel.backend.instancing.blockentity;
import java.util.List;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.backend.instancing.One2OneStorage;
import com.jozufozu.flywheel.backend.instancing.Storage;

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.backend.instancing.blockentity;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import net.minecraft.world.level.block.entity.BlockEntity;

View file

@ -3,7 +3,7 @@ package com.jozufozu.flywheel.backend.instancing.blockentity;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import net.minecraft.world.level.block.entity.BlockEntity;

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.effect;
import java.util.Collection;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
public interface Effect {

View file

@ -7,9 +7,9 @@ import java.util.Set;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
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.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.Storage;

View file

@ -1,8 +1,8 @@
package com.jozufozu.flywheel.backend.instancing.entity;
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.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
import com.jozufozu.flywheel.light.LightListener;

View file

@ -2,11 +2,11 @@ package com.jozufozu.flywheel.backend.instancing.entity;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
import com.jozufozu.flywheel.backend.instancing.One2OneStorage;
import net.minecraft.core.BlockPos;

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.backend.instancing.entity;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import net.minecraft.world.entity.Entity;

View file

@ -3,7 +3,7 @@ package com.jozufozu.flywheel.backend.instancing.entity;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import net.minecraft.world.entity.Entity;

View file

@ -4,7 +4,7 @@ import java.util.HashSet;
import java.util.Set;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.gl.GlVertexArray;

View file

@ -4,15 +4,13 @@ import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.InstancerFactory;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancerFactory;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
import com.jozufozu.flywheel.core.model.ModelSupplier;
import net.minecraft.client.renderer.RenderType;
/**
* A collection of Instancers that all have the same format.
* @param <D>

View file

@ -2,9 +2,8 @@ package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.List;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.instancing.AbstractInstancer;
import com.jozufozu.flywheel.core.model.ModelSupplier;
public class InstancedModel<D extends InstancedPart> {

View file

@ -8,12 +8,18 @@ import java.util.Map;
import org.jetbrains.annotations.NotNull;
import com.google.common.collect.ListMultimap;
import com.jozufozu.flywheel.api.InstancedPart;
import com.google.common.collect.Multimaps;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.gl.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.backend.instancing.Engine;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.instancing.TaskEngine;
import com.jozufozu.flywheel.backend.model.MeshPool;
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
@ -51,8 +57,6 @@ public class InstancingEngine implements Engine {
* The set of instance managers that are attached to this engine.
*/
private final WeakHashSet<InstanceManager<?>> instanceManagers;
private int vertexCount;
private int instanceCount;
public InstancingEngine(ContextShader context) {
this.context = context;
@ -73,32 +77,44 @@ public class InstancingEngine implements Engine {
}
@Override
public void renderAllRemaining(TaskEngine taskEngine, RenderContext context) {
for (RenderType renderType : renderLists.drainLayers()) {
render(renderType);
}
}
@Override
public void renderSpecificType(TaskEngine taskEngine, RenderContext context, RenderType type) {
if (!renderLists.process(type)) {
public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
if (!renderLists.process(stage)) {
return;
}
render(type);
}
protected void render(RenderType type) {
vertexCount = 0;
instanceCount = 0;
var multimap = renderLists.get(type);
var renderList = renderLists.get(stage);
for (var entry : renderList.entrySet()) {
var multimap = entry.getValue();
if (multimap.isEmpty()) {
return;
}
render(type, multimap);
render(entry.getKey(), multimap);
}
}
// TODO: Is this useful? Should it be added to the base interface? Currently it is only used for the old CrumblingRenderer.
@Deprecated
public void renderAll(TaskEngine taskEngine, RenderContext context) {
if (renderLists.isEmpty()) {
return;
}
for (RenderStage stage : renderLists.stagesToProcess) {
var renderList = renderLists.get(stage);
for (var entry : renderList.entrySet()) {
var multimap = entry.getValue();
if (multimap.isEmpty()) {
return;
}
render(entry.getKey(), multimap);
}
}
renderLists.stagesToProcess.clear();
}
protected void render(RenderType type, ListMultimap<ShaderState, DrawCall> multimap) {
@ -180,7 +196,7 @@ public class InstancingEngine implements Engine {
}
@Override
public void beginFrame(TaskEngine taskEngine, Camera info) {
public void beginFrame(TaskEngine taskEngine, RenderContext context) {
for (var model : uninitializedModels) {
model.init(renderLists);
}
@ -203,8 +219,6 @@ public class InstancingEngine implements Engine {
@Override
public void addDebugInfo(List<String> info) {
info.add("GL33 Instanced Arrays");
info.add("Instances: " + instanceCount);
info.add("Vertices: " + vertexCount);
info.add("Origin: " + originCoordinate.getX() + ", " + originCoordinate.getY() + ", " + originCoordinate.getZ());
}
}

View file

@ -1,49 +1,57 @@
package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.material.Material;
import net.minecraft.client.renderer.RenderType;
public class RenderLists {
private final Map<RenderType, ListMultimap<ShaderState, DrawCall>> renderLists = new HashMap<>();
public final Set<RenderType> layersToProcess = new HashSet<>();
private final Map<RenderStage, Map<RenderType, ListMultimap<ShaderState, DrawCall>>> renderLists = new EnumMap<>(RenderStage.class);
public final Set<RenderStage> stagesToProcess = EnumSet.noneOf(RenderStage.class);
public ListMultimap<ShaderState, DrawCall> get(RenderType type) {
return renderLists.computeIfAbsent(type, k -> ArrayListMultimap.create());
public Map<RenderType, ListMultimap<ShaderState, DrawCall>> get(RenderStage stage) {
var renderList = renderLists.get(stage);
if (renderList == null) {
return Collections.emptyMap();
}
return renderList;
}
public void add(ShaderState shaderState, DrawCall layer) {
RenderType renderType = shaderState.material()
.renderType();
Material material = shaderState.material();
get(renderType).put(shaderState, layer);
renderLists
.computeIfAbsent(material.getRenderStage(), k -> new HashMap<>())
.computeIfAbsent(material.getRenderType(), k -> ArrayListMultimap.create())
.put(shaderState, layer);
}
public void prepare() {
layersToProcess.clear();
stagesToProcess.clear();
layersToProcess.addAll(renderLists.keySet());
}
public Iterable<? extends RenderType> drainLayers() {
var out = new HashSet<>(layersToProcess);
layersToProcess.clear();
return out;
stagesToProcess.addAll(renderLists.keySet());
}
/**
* Check and mark a layer as processed.
* @param type The layer to check.
* @return {@code true} if the layer should be processed.
* Check and mark a stage as processed.
* @param stage The stage to check.
* @return {@code true} if the stage should be processed.
*/
public boolean process(RenderType type) {
return layersToProcess.remove(type);
public boolean process(RenderStage stage) {
return stagesToProcess.remove(stage);
}
public boolean isEmpty() {
return stagesToProcess.isEmpty();
}
}

View file

@ -2,7 +2,7 @@ package com.jozufozu.flywheel.backend.struct;
import java.nio.ByteBuffer;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.struct.StructWriter;

View file

@ -4,7 +4,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
/**

View file

@ -12,13 +12,8 @@ import com.jozufozu.flywheel.util.Lazy;
import com.jozufozu.flywheel.util.NonNullSupplier;
public class BasicModelSupplier implements ModelSupplier {
private Material material;
private final Lazy<Mesh> supplier;
public BasicModelSupplier(NonNullSupplier<Mesh> supplier) {
this(supplier, Materials.DEFAULT);
}
private Material material;
public BasicModelSupplier(NonNullSupplier<Mesh> supplier, Material material) {
this.supplier = Lazy.of(supplier);

View file

@ -23,7 +23,7 @@ public class ComponentRegistry {
// TODO: fill out the rest of the registry
public static Material register(Material material) {
public static <T extends Material> T register(T material) {
return material;
}

View file

@ -10,6 +10,7 @@ import java.util.Map;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.backend.ShadersModHandler;
import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo.FogType;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.renderer.ShaderInstance;

View file

@ -1,21 +0,0 @@
package com.jozufozu.flywheel.core;
import net.minecraft.client.Camera;
/**
* A class tracking which object last had {@link Camera#setup} called on it.
*
* @see com.jozufozu.flywheel.mixin.CameraMixin
*/
public class LastActiveCamera {
private static Camera camera;
public static void _setActiveCamera(Camera camera) {
LastActiveCamera.camera = camera;
}
public static Camera getActiveCamera() {
return camera;
}
}

View file

@ -1,6 +1,8 @@
package com.jozufozu.flywheel.core;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.core.material.SimpleMaterial;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
@ -8,10 +10,11 @@ import net.minecraft.resources.ResourceLocation;
public class Materials {
private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png");
public static final Material DEFAULT = ComponentRegistry.register(new Material(RenderType.solid(), Components.Files.DEFAULT_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material CHEST = ComponentRegistry.register(new Material(Sheets.chestSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material SHULKER = ComponentRegistry.register(new Material(RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material MINECART = ComponentRegistry.register(new Material(RenderType.entitySolid(MINECART_LOCATION), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material DEFAULT = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_BLOCK_ENTITIES, RenderType.solid(), Components.Files.DEFAULT_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material CHEST = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_BLOCK_ENTITIES, Sheets.chestSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material SHULKER = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_BLOCK_ENTITIES, RenderType.entityCutoutNoCull(Sheets.SHULKER_SHEET), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material BELL = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_BLOCK_ENTITIES, Sheets.solidBlockSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static final Material MINECART = ComponentRegistry.register(new SimpleMaterial(RenderStage.AFTER_ENTITIES, RenderType.entitySolid(MINECART_LOCATION), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
public static void init() {
// noop

View file

@ -14,13 +14,12 @@ import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
public class Models {
public static BasicModelSupplier block(BlockState state) {
return BLOCK_STATE.computeIfAbsent(state, it -> new BasicModelSupplier(() -> new BlockMesh(it)));
return BLOCK_STATE.computeIfAbsent(state, it -> new BasicModelSupplier(() -> new BlockMesh(it), Materials.DEFAULT));
}
public static BasicModelSupplier partial(PartialModel partial) {
return PARTIAL.computeIfAbsent(partial, it -> new BasicModelSupplier(() -> new BlockMesh(it)));
return PARTIAL.computeIfAbsent(partial, it -> new BasicModelSupplier(() -> new BlockMesh(it), Materials.DEFAULT));
}
public static BasicModelSupplier partial(PartialModel partial, Direction dir) {
@ -28,7 +27,7 @@ public class Models {
}
public static BasicModelSupplier partial(PartialModel partial, Direction dir, Supplier<PoseStack> modelTransform) {
return PARTIAL_DIR.computeIfAbsent(Pair.of(dir, partial), $ -> new BasicModelSupplier(() -> new BlockMesh(partial, modelTransform.get())));
return PARTIAL_DIR.computeIfAbsent(Pair.of(dir, partial), $ -> new BasicModelSupplier(() -> new BlockMesh(partial, modelTransform.get()), Materials.DEFAULT));
}
public static void onReload(ReloadRenderersEvent ignored) {

View file

@ -1,8 +1,6 @@
package com.jozufozu.flywheel.core;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View file

@ -1,18 +1,20 @@
package com.jozufozu.flywheel.core;
import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderBuffers;
public record RenderContext(ClientLevel level, PoseStack stack, Matrix4f viewProjection, RenderBuffers buffers,
double camX, double camY, double camZ) implements TransformStack {
public static RenderContext CURRENT;
public record RenderContext(LevelRenderer renderer, ClientLevel level, PoseStack stack, Matrix4f viewProjection,
Matrix4f projection, RenderBuffers buffers, Camera camera) implements TransformStack {
@Override
public TransformStack multiply(Quaternion quaternion) {
@ -50,4 +52,11 @@ public record RenderContext(ClientLevel level, PoseStack stack, Matrix4f viewPro
public TransformStack translate(double x, double y, double z) {
return TransformStack.cast(stack).translate(x, y, z);
}
@NotNull
public static Matrix4f createViewProjection(PoseStack view, Matrix4f projection) {
var viewProjection = projection.copy();
viewProjection.multiply(view.last().pose());
return viewProjection;
}
}

View file

@ -25,16 +25,13 @@ import com.jozufozu.flywheel.event.ReloadRenderersEvent;
public class ProgramCompiler extends Memoizer<ProgramCompiler.Context, GlProgram> {
public static final ProgramCompiler INSTANCE = new ProgramCompiler();
private static final List<ProgramCompiler> ALL_COMPILERS = new ArrayList<>();
private final VertexCompiler vertexCompiler;
private final FragmentCompiler fragmentCompiler;
public ProgramCompiler() {
private ProgramCompiler() {
this.vertexCompiler = new VertexCompiler();
this.fragmentCompiler = new FragmentCompiler();
ALL_COMPILERS.add(this);
}
/**
@ -62,10 +59,10 @@ public class ProgramCompiler extends Memoizer<ProgramCompiler.Context, GlProgram
FileResolution instanceShader = ctx.instanceShader();
ContextShader contextShader = ctx.contextShader;
var vertex = new VertexCompiler.Context(ctx.vertexType(), instanceShader.getFile(), material.getVertexShader(),
var vertex = new VertexCompiler.Context(ctx.vertexType(), instanceShader.getFile(), material.getVertexShader().getFile(),
contextShader.getVertexShader(), snapshot);
var fragment = new FragmentCompiler.Context(material.getFragmentShader(), contextShader.getFragmentShader(),
var fragment = new FragmentCompiler.Context(material.getFragmentShader().getFile(), contextShader.getFragmentShader(),
ctx.alphaDiscard(), ctx.fogType(), snapshot);
return new ProgramAssembler(instanceShader.getFileLoc())
@ -81,7 +78,7 @@ public class ProgramCompiler extends Memoizer<ProgramCompiler.Context, GlProgram
}
public static void invalidateAll(ReloadRenderersEvent ignored) {
ALL_COMPILERS.forEach(ProgramCompiler::invalidate);
INSTANCE.invalidate();
}
/**

View file

@ -1,7 +1,7 @@
package com.jozufozu.flywheel.core.crumbling;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
public class CrumblingInstanceManager extends BlockEntityInstanceManager {

View file

@ -4,24 +4,25 @@ import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import com.google.common.collect.ListMultimap;
import com.jozufozu.flywheel.backend.Backend;
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.DrawCall;
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
import com.jozufozu.flywheel.backend.instancing.instancing.ShaderState;
import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.mixin.LevelRendererAccessor;
import com.jozufozu.flywheel.util.Lazy;
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.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
@ -29,7 +30,6 @@ 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;
// TODO: merge directly into InstancingEngine for efficiency
/**
@ -43,45 +43,34 @@ public class CrumblingRenderer {
_init();
}
public static void renderCrumbling(LevelRenderer levelRenderer, ClientLevel level, PoseStack poseStack, Camera camera, Matrix4f projectionMatrix) {
public static void renderCrumbling(RenderContext context) {
// TODO: one pass base/crumbling
if (true) return;
Int2ObjectMap<List<BlockEntity>> activeStages = getActiveStageBlockEntities(levelRenderer, level);
Int2ObjectMap<List<BlockEntity>> activeStages = getActiveStageBlockEntities(context.renderer(), context.level());
if (activeStages.isEmpty()) return;
try (var restoreState = GlStateTracker.getRestoreState()) {
Matrix4f viewProjection = poseStack.last()
.pose()
.copy();
viewProjection.multiplyBackward(projectionMatrix);
State state = STATE.get();
var instanceManager = state.instanceManager;
var engine = state.instancerManager;
renderCrumblingInner(activeStages, instanceManager, engine, level, poseStack, camera, viewProjection);
renderCrumblingInner(activeStages, instanceManager, engine, context);
}
}
private static void renderCrumblingInner(Int2ObjectMap<List<BlockEntity>> activeStages, InstanceManager<BlockEntity> 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);
private static void renderCrumblingInner(Int2ObjectMap<List<BlockEntity>> activeStages, InstanceManager<BlockEntity> instanceManager, CrumblingEngine engine, RenderContext ctx) {
for (Int2ObjectMap.Entry<List<BlockEntity>> stage : activeStages.int2ObjectEntrySet()) {
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) {
engine.currentLayer = currentLayer;
stage.getValue().forEach(instanceManager::add);
instanceManager.beginFrame(SerialTaskEngine.INSTANCE, camera);
engine.beginFrame(SerialTaskEngine.INSTANCE, camera);
instanceManager.beginFrame(SerialTaskEngine.INSTANCE, ctx);
engine.beginFrame(SerialTaskEngine.INSTANCE, ctx);
engine.renderAllRemaining(SerialTaskEngine.INSTANCE, ctx);
engine.renderAll(SerialTaskEngine.INSTANCE, ctx);
instanceManager.invalidate();
}
@ -154,25 +143,17 @@ public class CrumblingRenderer {
}
private static class CrumblingEngine extends InstancingEngine {
private RenderType currentLayer;
public CrumblingEngine() {
super(Components.CRUMBLING);
}
@Override
protected void render(RenderType type) {
protected void render(RenderType type, ListMultimap<ShaderState, DrawCall> multimap) {
if (!type.affectsCrumbling()) {
return;
}
var multimap = renderLists.get(type);
if (multimap.isEmpty()) {
return;
}
render(currentLayer, multimap);
super.render(type, multimap);
}
}
}

View file

@ -9,7 +9,6 @@ import com.jozufozu.flywheel.core.model.Mesh;
import com.jozufozu.flywheel.core.vertex.Formats;
import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex;
import com.jozufozu.flywheel.core.vertex.PosTexNormalWriterUnsafe;
import com.mojang.blaze3d.platform.MemoryTracker;
public class ModelPart implements Mesh {

View file

@ -5,8 +5,8 @@ import java.util.function.Consumer;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
public class ConditionalInstance<D extends InstancedPart> {

View file

@ -5,8 +5,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
public class GroupInstance<D extends InstancedPart> extends AbstractCollection<D> {

View file

@ -6,8 +6,8 @@ import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.Instancer;
public class SelectInstance<D extends InstancedPart> {

View file

@ -0,0 +1,41 @@
package com.jozufozu.flywheel.core.material;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.core.source.FileResolution;
import net.minecraft.client.renderer.RenderType;
public class SimpleMaterial implements Material {
protected final RenderStage stage;
protected final RenderType type;
protected final FileResolution vertexShader;
protected final FileResolution fragmentShader;
public SimpleMaterial(RenderStage stage, RenderType type, FileResolution vertexShader, FileResolution fragmentShader) {
this.stage = stage;
this.type = type;
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
}
@Override
public RenderStage getRenderStage() {
return stage;
}
@Override
public RenderType getRenderType() {
return type;
}
@Override
public FileResolution getVertexShader() {
return vertexShader;
}
@Override
public FileResolution getFragmentShader() {
return fragmentShader;
}
}

View file

@ -1,7 +1,6 @@
package com.jozufozu.flywheel.core.model;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.EnumMap;
import java.util.Random;
@ -11,7 +10,6 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.core.structs;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.util.Color;

View file

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.core.structs;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockAndTintGetter;

View file

@ -71,6 +71,7 @@ public class UniformBuffer {
return;
}
// TODO: upload only changed bytes
changedBytes.clear();
buffer.upload(data);

View file

@ -14,6 +14,7 @@ import com.jozufozu.flywheel.util.MatrixWrite;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.Vec3i;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.MinecraftForge;
public class ViewProvider extends UniformProvider {
@ -23,7 +24,7 @@ public class ViewProvider extends UniformProvider {
}
public void beginFrame(BeginFrameEvent event) {
update(RenderContext.CURRENT);
update(event.getContext());
}
@Override
@ -42,10 +43,12 @@ public class ViewProvider extends UniformProvider {
.constantAmbientLight() ? 1 : 0;
Vec3i originCoordinate = InstancedRenderDispatcher.getOriginCoordinate(level);
Vec3 camera = context.camera()
.getPosition();
var camX = (float) (context.camX() - originCoordinate.getX());
var camY = (float) (context.camY() - originCoordinate.getY());
var camZ = (float) (context.camZ() - originCoordinate.getZ());
var camX = (float) (camera.x - originCoordinate.getX());
var camY = (float) (camera.y - originCoordinate.getY());
var camZ = (float) (camera.z - originCoordinate.getZ());
// don't want to mutate viewProjection
var vp = context.viewProjection().copy();

View file

@ -1,7 +1,6 @@
package com.jozufozu.flywheel.core.vertex;
import com.jozufozu.flywheel.api.vertex.ShadedVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
import com.jozufozu.flywheel.util.RenderMath;

View file

@ -1,6 +1,5 @@
package com.jozufozu.flywheel.core.vertex;
import java.lang.ref.Cleaner;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;

View file

@ -4,9 +4,7 @@ import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.FlywheelMemory;
import com.jozufozu.flywheel.util.RenderMath;
public class PosTexNormalVertexListUnsafe extends AbstractVertexList {

View file

@ -1,35 +1,17 @@
package com.jozufozu.flywheel.event;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.world.phys.Vec3;
import com.jozufozu.flywheel.core.RenderContext;
import net.minecraftforge.eventbus.api.Event;
public class BeginFrameEvent extends Event {
private final ClientLevel world;
private final Camera camera;
private final Frustum frustum;
private final RenderContext context;
public BeginFrameEvent(ClientLevel world, Camera camera, Frustum frustum) {
this.world = world;
this.camera = camera;
this.frustum = frustum;
public BeginFrameEvent(RenderContext context) {
this.context = context;
}
public ClientLevel getWorld() {
return world;
}
public Camera getCamera() {
return camera;
}
public Frustum getFrustum() {
return frustum;
}
public Vec3 getCameraPos() {
return camera.getPosition();
public RenderContext getContext() {
return context;
}
}

View file

@ -3,11 +3,8 @@ package com.jozufozu.flywheel.event;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.EntityLeaveWorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
public class EntityWorldHandler {

View file

@ -10,25 +10,21 @@ import com.jozufozu.flywheel.light.LightUpdater;
import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
public class ForgeEvents {
public static void addToDebugScreen(RenderGameOverlayEvent.Text event) {
if (Minecraft.getInstance().options.renderDebug) {
ArrayList<String> debug = event.getRight();
debug.add("");
debug.add("Flywheel: " + Flywheel.getVersion());
InstancedRenderDispatcher.getDebugString(debug);
// TODO: compress into one line
debug.add("Memory used:");
debug.add("GPU: " + FlywheelMemory.getGPUMemory());
debug.add("CPU: " + FlywheelMemory.getCPUMemory());
@ -39,8 +35,8 @@ public class ForgeEvents {
WorldAttached.invalidateWorld(event.getWorld());
}
public static void tickLight(TickEvent.ClientTickEvent e) {
if (e.phase == TickEvent.Phase.END && Backend.isGameActive()) {
public static void tickLight(TickEvent.ClientTickEvent event) {
if (event.phase == TickEvent.Phase.END && Backend.isGameActive()) {
LightUpdater.get(Minecraft.getInstance().level)
.tick();
}

View file

@ -1,69 +0,0 @@
package com.jozufozu.flywheel.event;
import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.core.RenderContext;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.RenderType;
import net.minecraftforge.eventbus.api.Event;
public class RenderLayerEvent extends Event {
public final RenderContext context;
public final RenderType type;
public RenderLayerEvent(RenderContext context, RenderType type) {
this.context = context;
this.type = type;
}
@NotNull
public static Matrix4f createViewProjection(PoseStack view) {
var viewProjection = view.last()
.pose()
.copy();
viewProjection.multiplyBackward(RenderSystem.getProjectionMatrix());
return viewProjection;
}
@Override
public String toString() {
return "RenderLayerEvent{" + context + "}";
}
public ClientLevel getWorld() {
return context.level();
}
public RenderType getType() {
return type;
}
public PoseStack getStack() {
return context.stack();
}
public Matrix4f getViewProjection() {
return context.viewProjection();
}
public RenderBuffers getBuffers() {
return context.buffers();
}
public double getCamX() {
return context.camX();
}
public double getCamY() {
return context.camY();
}
public double getCamZ() {
return context.camZ();
}
}

View file

@ -0,0 +1,54 @@
package com.jozufozu.flywheel.event;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.core.RenderContext;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraftforge.eventbus.api.Event;
public class RenderStageEvent extends Event {
private final RenderContext context;
private final RenderStage stage;
public RenderStageEvent(RenderContext context, RenderStage stage) {
this.context = context;
this.stage = stage;
}
public RenderContext getContext() {
return context;
}
public RenderStage getStage() {
return stage;
}
public ClientLevel getLevel() {
return context.level();
}
public PoseStack getStack() {
return context.stack();
}
public Matrix4f getViewProjection() {
return context.viewProjection();
}
public RenderBuffers getBuffers() {
return context.buffers();
}
public Camera getCamera() {
return context.camera();
}
@Override
public String toString() {
return "RenderStageEvent{" + context + "}";
}
}

View file

@ -1,21 +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.core.LastActiveCamera;
import net.minecraft.client.Camera;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.BlockGetter;
@Mixin(Camera.class)
public class CameraMixin {
@Inject(method = "setup", at = @At("TAIL"))
private void setup(BlockGetter level, Entity entity, boolean is3rdPerson, boolean isMirrored, float pt, CallbackInfo ci) {
LastActiveCamera._setActiveCamera((Camera)(Object) this);
}
}

View file

@ -1,28 +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.backend.ShadersModHandler;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.core.LastActiveCamera;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraftforge.common.MinecraftForge;
@Mixin(Frustum.class)
public class FrustumMixin {
@Inject(method = "prepare", at = @At("TAIL"))
private void onPrepare(double x, double y, double z, CallbackInfo ci) {
if (ShadersModHandler.isRenderingShadowPass()) {
try (var restoreState = GlStateTracker.getRestoreState()) {
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(Minecraft.getInstance().level, LastActiveCamera.getActiveCamera(), (Frustum) (Object) this));
}
}
}
}

View file

@ -1,183 +0,0 @@
package com.jozufozu.flywheel.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
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.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.event.RenderLayerEvent;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraftforge.common.MinecraftForge;
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after sodium
public class LevelRendererDispatchMixin {
@Inject(at = @At("TAIL"), method = "renderChunkLayer")
private void renderChunkLayer(RenderType pRenderType, PoseStack pPoseStack, double pCamX, double pCamY, double pCamZ, Matrix4f pProjectionMatrix, CallbackInfo ci) {
try (var restoreState = GlStateTracker.getRestoreState()) {
// TODO: Is this necessary?
InstancedRenderDispatcher.renderSpecificType(RenderContext.CURRENT, pRenderType);
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(RenderContext.CURRENT, pRenderType));
}
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V"))
private void endBatch(CallbackInfo ci) {
if (RenderContext.CURRENT != null && Backend.isGameActive() && Backend.isOn()) {
try (var restoreState = GlStateTracker.getRestoreState()) {
InstancedRenderDispatcher.renderAllRemaining(RenderContext.CURRENT);
}
}
}
@Unique
private void flywheel$dispatch(RenderType pRenderType) {
if (RenderContext.CURRENT != null && Backend.isGameActive() && Backend.isOn()) {
try (var restoreState = GlStateTracker.getRestoreState()) {
InstancedRenderDispatcher.renderSpecificType(RenderContext.CURRENT, pRenderType);
}
}
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 0, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$entitySolid(CallbackInfo ci) {
flywheel$dispatch(RenderType.entitySolid(TextureAtlas.LOCATION_BLOCKS));
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 1, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$entityCutout(CallbackInfo ci) {
flywheel$dispatch(RenderType.entityCutout(TextureAtlas.LOCATION_BLOCKS));
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 2, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$entityCutoutNoCull(CallbackInfo ci) {
flywheel$dispatch(RenderType.entityCutoutNoCull(TextureAtlas.LOCATION_BLOCKS));
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 3, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$entitySmoothCutout(CallbackInfo ci) {
flywheel$dispatch(RenderType.entitySmoothCutout(TextureAtlas.LOCATION_BLOCKS));
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 4, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$solid(CallbackInfo ci) {
flywheel$dispatch(RenderType.solid());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 5, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$endPortal(CallbackInfo ci) {
flywheel$dispatch(RenderType.endPortal());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 6, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$endGateway(CallbackInfo ci) {
flywheel$dispatch(RenderType.endGateway());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 7, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$solidBlockSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.solidBlockSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 8, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$cutoutBlockSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.cutoutBlockSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 9, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$bedSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.bedSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 10, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$shulkerBoxSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.shulkerBoxSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 11, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$signSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.signSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 12, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$chestSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.chestSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 13, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$translucentCullBlockSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.translucentCullBlockSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 14, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$bannerSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.bannerSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 15, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$shieldSheet(CallbackInfo ci) {
flywheel$dispatch(Sheets.shieldSheet());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 16, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$armorGlint(CallbackInfo ci) {
flywheel$dispatch(RenderType.armorGlint());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 17, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$armorEntityGlint(CallbackInfo ci) {
flywheel$dispatch(RenderType.armorEntityGlint());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 18, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$glint(CallbackInfo ci) {
flywheel$dispatch(RenderType.glint());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 19, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$glintDirect(CallbackInfo ci) {
flywheel$dispatch(RenderType.glintDirect());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 20, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$glintTranslucent(CallbackInfo ci) {
flywheel$dispatch(RenderType.glintTranslucent());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 21, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$entityGlint(CallbackInfo ci) {
flywheel$dispatch(RenderType.entityGlint());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 22, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$entityGlintDirect(CallbackInfo ci) {
flywheel$dispatch(RenderType.entityGlintDirect());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 23, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$waterMask(CallbackInfo ci) {
flywheel$dispatch(RenderType.waterMask());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 24, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$lines1(CallbackInfo ci) {
flywheel$dispatch(RenderType.lines());
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 25, target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch(Lnet/minecraft/client/renderer/RenderType;)V"))
private void renderLayer$lines2(CallbackInfo ci) {
flywheel$dispatch(RenderType.lines());
}
}

View file

@ -1,5 +1,6 @@
package com.jozufozu.flywheel.mixin;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -9,14 +10,14 @@ import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.core.RenderContext;
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.jozufozu.flywheel.event.RenderStageEvent;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
@ -26,13 +27,10 @@ import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.MinecraftForge;
@Mixin(value = LevelRenderer.class, priority = 1001) // Higher priority to go after sodium
public class LevelRendererMixin {
@Shadow
private ClientLevel level;
@ -40,19 +38,21 @@ public class LevelRendererMixin {
@Final
private RenderBuffers renderBuffers;
@Unique
private RenderContext renderContext;
@Inject(at = @At("HEAD"), method = "renderLevel")
private void beginRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
Vec3 position = pCamera.getPosition();
RenderContext.CURRENT = new RenderContext(level, pPoseStack, RenderLayerEvent.createViewProjection(pPoseStack), renderBuffers, position.x, position.y, position.z);
renderContext = new RenderContext((LevelRenderer) (Object) this, level, pPoseStack, RenderContext.createViewProjection(pPoseStack, pProjectionMatrix), pProjectionMatrix, renderBuffers, pCamera);
try (var restoreState = GlStateTracker.getRestoreState()) {
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(level, pCamera, null));
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(renderContext));
}
}
@Inject(at = @At("TAIL"), method = "renderLevel")
private void endRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) {
RenderContext.CURRENT = null;
renderContext = null;
}
@Inject(at = @At("TAIL"), method = "allChanged")
@ -64,7 +64,90 @@ public class LevelRendererMixin {
@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 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);
private void renderCrumbling(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
if (renderContext != null) {
CrumblingRenderer.renderCrumbling(renderContext);
}
}
// STAGE DISPATCHING
@Unique
private void flywheel$dispatch(RenderStage stage) {
if (renderContext != null) {
try (var restoreState = GlStateTracker.getRestoreState()) {
MinecraftForge.EVENT_BUS.post(new RenderStageEvent(renderContext, stage));
}
}
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=sky"))
private void onStage$beforeSky(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_SKY);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=fog"))
private void onStage$afterSky(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_SKY);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=terrain"))
private void onStage$beforeTerrain(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=entities"))
private void onStage$afterSolidTerrain(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_SOLID_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderBuffers;bufferSource()Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 0))
private void onStage$beforeEntities(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_ENTITIES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=blockentities"))
private void onStage$beforeBlockEntities(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_ENTITIES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/OutlineBufferSource;endOutlineBatch()V", ordinal = 0))
private void onStage$afterSolidBlockEntities(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_BLOCK_ENTITIES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V", ordinal = 0))
private void onStage$beforeCrumbling(CallbackInfo ci) {
flywheel$dispatch(RenderStage.BEFORE_CRUMBLING);
}
@Inject(method = "renderLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/LevelRenderer;translucentTarget:Lcom/mojang/blaze3d/pipeline/RenderTarget;", opcode = Opcodes.GETFIELD, ordinal = 0))
private void onStage$afterFinalEndBatch$fabulous(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_FINAL_END_BATCH);
}
@Inject(method = "renderLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/LevelRenderer;particlesTarget:Lcom/mojang/blaze3d/pipeline/RenderTarget;", opcode = Opcodes.GETFIELD, ordinal = 0))
private void onStage$afterTranslucentTerrain$fabulous(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_TRANSLUCENT_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;endBatch()V", ordinal = 2, shift = Shift.AFTER))
private void onStage$afterFinalEndBatch(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_FINAL_END_BATCH);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderChunkLayer(Lnet/minecraft/client/renderer/RenderType;Lcom/mojang/blaze3d/vertex/PoseStack;DDDLcom/mojang/math/Matrix4f;)V", ordinal = 6, shift = Shift.AFTER))
private void onStage$afterTranslucentTerrain(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_TRANSLUCENT_TERRAIN);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/culling/Frustum;)V", shift = Shift.AFTER))
private void onStage$afterParticles(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_PARTICLES);
}
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderSnowAndRain(Lnet/minecraft/client/renderer/LightTexture;FDDD)V", shift = Shift.AFTER))
private void onStage$afterWeather(CallbackInfo ci) {
flywheel$dispatch(RenderStage.AFTER_WEATHER);
}
}

View file

@ -5,13 +5,12 @@ import java.util.List;
import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.jozufozu.flywheel.core.BasicModelSupplier;
import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.hardcoded.ModelPart;
import com.jozufozu.flywheel.core.structs.StructTypes;
import com.jozufozu.flywheel.core.structs.oriented.OrientedPart;
@ -19,14 +18,13 @@ import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.blockentity.BellRenderer;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.entity.BellBlockEntity;
public class BellInstance extends BlockEntityInstance<BellBlockEntity> implements DynamicInstance {
private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, new Material(Sheets.solidBlockSheet(), Components.Files.SHADED_VERTEX, Components.Files.DEFAULT_FRAGMENT));
private static final BasicModelSupplier MODEL = new BasicModelSupplier(BellInstance::createBellModel, Materials.BELL);
private final OrientedPart bell;

View file

@ -7,9 +7,10 @@ import java.util.function.BiFunction;
import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.jozufozu.flywheel.core.BasicModelSupplier;
import com.jozufozu.flywheel.core.Materials;

View file

@ -2,9 +2,10 @@ package com.jozufozu.flywheel.vanilla;
import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.TickableInstance;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.entity.EntityInstance;
import com.jozufozu.flywheel.core.BasicModelSupplier;
import com.jozufozu.flywheel.core.Materials;

View file

@ -4,9 +4,9 @@ import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import com.jozufozu.flywheel.api.InstancedPart;
import com.jozufozu.flywheel.api.InstancerManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.jozufozu.flywheel.core.BasicModelSupplier;
import com.jozufozu.flywheel.core.Materials;

View file

@ -5,9 +5,9 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
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.instancer.InstancerManager;
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.backend.instancing.effect.Effect;

View file

@ -9,18 +9,15 @@
"BlockEntityTypeMixin",
"BufferBuilderMixin",
"BufferUploaderMixin",
"CameraMixin",
"ChunkRebuildHooksMixin",
"ClientLevelMixin",
"EntityTypeMixin",
"FixFabulousDepthMixin",
"FogUpdateMixin",
"FrustumMixin",
"GlStateManagerMixin",
"InstanceAddMixin",
"InstanceRemoveMixin",
"LevelRendererAccessor",
"LevelRendererDispatchMixin",
"LevelRendererInstanceUpdateMixin",
"LevelRendererMixin",
"PausedPartialTickAccessor",