mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-06 04:16:36 +01:00
Shaking things out
- Use JOML better where we can. - Inline MatrixUtil#store and #toJoml - FlwShaderUniforms keeps a scratch matrix around for mutating the viewProjection. - Directly store a Quaternion4f in OrientedInstance to avoid creating new objects in the batching transformers. - Move FrameContext creation to a functor. - We do need to check the renderDebug flag still :ioa: - Make VisualUpdatePlan's internal plan not null. - Remove ClientMainMixin :sad: - Forge's new earlywindow stuff means there's no opportunity for Flywheel the mod to inject renderdoc before the window is initialized. - The workaround for now is to breakpoint in FML's DisplayWindow#initialize and evaluate `System.loadLibrary("renderdoc")` manually.
This commit is contained in:
parent
152688a09f
commit
9ac8aea347
14 changed files with 62 additions and 124 deletions
|
@ -45,7 +45,6 @@ minecraft {
|
|||
|
||||
client {
|
||||
property 'flw.dumpShaderSource', 'true'
|
||||
property 'flw.loadRenderDoc', 'true'
|
||||
property 'flw.debugMemorySafety', 'true'
|
||||
}
|
||||
|
||||
|
|
|
@ -140,10 +140,10 @@ public class Flywheel {
|
|||
|
||||
private static void addDebugInfo(CustomizeGuiOverlayEvent.DebugText event) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
// FIXME: do we need this check anymore?
|
||||
// if (!mc.options.renderDebug) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!mc.options.renderDebug) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<String> info = event.getRight();
|
||||
info.add("");
|
||||
|
|
|
@ -2,9 +2,9 @@ package com.jozufozu.flywheel.backend.engine.batching;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.FrustumIntersection;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.lib.math.MatrixUtil;
|
||||
import com.jozufozu.flywheel.lib.util.FlwUtil;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
||||
|
@ -20,9 +20,9 @@ public record BatchContext(FrustumIntersection frustum, ClientLevel level, PoseS
|
|||
var stack = FlwUtil.copyPoseStack(context.stack());
|
||||
stack.translate(origin.getX() - cameraPos.x, origin.getY() - cameraPos.y, origin.getZ() - cameraPos.z);
|
||||
|
||||
org.joml.Matrix4f proj = MatrixUtil.toJoml(context.viewProjection());
|
||||
proj.translate((float) (origin.getX() - cameraPos.x), (float) (origin.getY() - cameraPos.y), (float) (origin.getZ() - cameraPos.z));
|
||||
Matrix4f viewProjection = new Matrix4f(context.viewProjection());
|
||||
viewProjection.translate((float) (origin.getX() - cameraPos.x), (float) (origin.getY() - cameraPos.y), (float) (origin.getZ() - cameraPos.z));
|
||||
|
||||
return new BatchContext(new FrustumIntersection(proj), context.level(), stack.last());
|
||||
return new BatchContext(new FrustumIntersection(viewProjection), context.level(), stack.last());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,26 @@
|
|||
package com.jozufozu.flywheel.impl.visualization;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.joml.FrustumIntersection;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
|
||||
import net.minecraft.core.Vec3i;
|
||||
|
||||
public record FrameContext(double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum, float partialTick) {
|
||||
@NotNull
|
||||
public static FrameContext create(RenderContext context, Vec3i renderOrigin, float partialTick) {
|
||||
var cameraPos = context.camera()
|
||||
.getPosition();
|
||||
double cameraX = cameraPos.x;
|
||||
double cameraY = cameraPos.y;
|
||||
double cameraZ = cameraPos.z;
|
||||
|
||||
Matrix4f viewProjection = new Matrix4f(context.viewProjection());
|
||||
viewProjection.translate((float) (renderOrigin.getX() - cameraX), (float) (renderOrigin.getY() - cameraY), (float) (renderOrigin.getZ() - cameraZ));
|
||||
FrustumIntersection frustum = new FrustumIntersection(viewProjection);
|
||||
|
||||
return new FrameContext(cameraX, cameraY, cameraZ, frustum, partialTick);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.jozufozu.flywheel.impl.visualization;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.FrustumIntersection;
|
||||
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.api.backend.Engine;
|
||||
|
@ -20,7 +19,6 @@ import com.jozufozu.flywheel.impl.task.FlwTaskExecutor;
|
|||
import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.EffectVisualManager;
|
||||
import com.jozufozu.flywheel.impl.visualization.manager.EntityVisualManager;
|
||||
import com.jozufozu.flywheel.lib.math.MatrixUtil;
|
||||
import com.jozufozu.flywheel.lib.task.Flag;
|
||||
import com.jozufozu.flywheel.lib.task.NamedFlag;
|
||||
import com.jozufozu.flywheel.lib.task.NestedPlan;
|
||||
|
@ -213,18 +211,7 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
if (engine.updateRenderOrigin(context.camera())) {
|
||||
recreationPlan.execute(taskExecutor, partialTick, then);
|
||||
} else {
|
||||
Vec3i renderOrigin = engine.renderOrigin();
|
||||
var cameraPos = context.camera()
|
||||
.getPosition();
|
||||
double cameraX = cameraPos.x;
|
||||
double cameraY = cameraPos.y;
|
||||
double cameraZ = cameraPos.z;
|
||||
|
||||
org.joml.Matrix4f proj = MatrixUtil.toJoml(context.viewProjection());
|
||||
proj.translate((float) (renderOrigin.getX() - cameraX), (float) (renderOrigin.getY() - cameraY), (float) (renderOrigin.getZ() - cameraZ));
|
||||
FrustumIntersection frustum = new FrustumIntersection(proj);
|
||||
|
||||
var frameContext = new FrameContext(cameraX, cameraY, cameraZ, frustum, partialTick);
|
||||
var frameContext = FrameContext.create(context, engine.renderOrigin(), partialTick);
|
||||
|
||||
normalPlan.execute(taskExecutor, frameContext, then);
|
||||
}
|
||||
|
|
|
@ -10,11 +10,12 @@ import com.jozufozu.flywheel.api.task.Plan;
|
|||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||
import com.jozufozu.flywheel.lib.task.NestedPlan;
|
||||
import com.jozufozu.flywheel.lib.task.SimplyComposedPlan;
|
||||
import com.jozufozu.flywheel.lib.task.UnitPlan;
|
||||
|
||||
public class VisualUpdatePlan<C> implements SimplyComposedPlan<C> {
|
||||
private final Supplier<List<Plan<C>>> initializer;
|
||||
@Nullable
|
||||
private Plan<C> plan;
|
||||
@NotNull
|
||||
private Plan<C> plan = UnitPlan.of();
|
||||
private boolean initialized = false;
|
||||
private boolean needsSimplify = true;
|
||||
|
||||
|
@ -28,24 +29,15 @@ public class VisualUpdatePlan<C> implements SimplyComposedPlan<C> {
|
|||
}
|
||||
|
||||
public void add(Plan<C> plan) {
|
||||
if (this.plan == null) {
|
||||
this.plan = plan;
|
||||
} else {
|
||||
this.plan = this.plan.and(plan);
|
||||
}
|
||||
this.plan = this.plan.and(plan);
|
||||
|
||||
needsSimplify = true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Plan<C> updatePlans() {
|
||||
if (!initialized) {
|
||||
Plan<C> mainPlan = new NestedPlan<>(initializer.get());
|
||||
if (plan != null) {
|
||||
plan = mainPlan.and(plan);
|
||||
} else {
|
||||
plan = mainPlan;
|
||||
}
|
||||
plan = mainPlan.and(plan);
|
||||
plan = plan.simplify();
|
||||
initialized = true;
|
||||
} else if (needsSimplify) {
|
||||
|
@ -57,7 +49,7 @@ public class VisualUpdatePlan<C> implements SimplyComposedPlan<C> {
|
|||
}
|
||||
|
||||
public void clear() {
|
||||
plan = null;
|
||||
plan = UnitPlan.of();
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.jozufozu.flywheel.api.instance.InstanceHandle;
|
|||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class OrientedInstance extends ColoredLitInstance {
|
||||
public float posX;
|
||||
|
@ -15,10 +16,7 @@ public class OrientedInstance extends ColoredLitInstance {
|
|||
public float pivotX = 0.5f;
|
||||
public float pivotY = 0.5f;
|
||||
public float pivotZ = 0.5f;
|
||||
public float qX;
|
||||
public float qY;
|
||||
public float qZ;
|
||||
public float qW = 1;
|
||||
public final Quaternionf rotation = new Quaternionf();
|
||||
|
||||
public OrientedInstance(InstanceType<? extends OrientedInstance> type, InstanceHandle handle) {
|
||||
super(type, handle);
|
||||
|
@ -49,11 +47,11 @@ public class OrientedInstance extends ColoredLitInstance {
|
|||
}
|
||||
|
||||
public OrientedInstance setPivot(Vector3f pos) {
|
||||
return setPosition(pos.x(), pos.y(), pos.z());
|
||||
return setPivot(pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
|
||||
public OrientedInstance setPivot(net.minecraft.world.phys.Vec3 pos) {
|
||||
return setPosition((float) pos.x(), (float) pos.y(), (float) pos.z());
|
||||
public OrientedInstance setPivot(Vec3 pos) {
|
||||
return setPivot((float) pos.x(), (float) pos.y(), (float) pos.z());
|
||||
}
|
||||
|
||||
public OrientedInstance setPivot(float x, float y, float z) {
|
||||
|
@ -65,23 +63,19 @@ public class OrientedInstance extends ColoredLitInstance {
|
|||
}
|
||||
|
||||
public OrientedInstance setRotation(Quaternionf q) {
|
||||
return setRotation(q.x, q.y, q.z, q.w);
|
||||
rotation.set(q);
|
||||
setChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
public OrientedInstance setRotation(float x, float y, float z, float w) {
|
||||
this.qX = x;
|
||||
this.qY = y;
|
||||
this.qZ = z;
|
||||
this.qW = w;
|
||||
rotation.set(x, y, z, w);
|
||||
setChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
public OrientedInstance resetRotation() {
|
||||
this.qX = 0;
|
||||
this.qY = 0;
|
||||
this.qZ = 0;
|
||||
this.qW = 1;
|
||||
rotation.identity();
|
||||
setChanged();
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -48,15 +48,13 @@ public class OrientedType implements InstanceType<OrientedInstance> {
|
|||
@Override
|
||||
public InstanceVertexTransformer<OrientedInstance> getVertexTransformer() {
|
||||
return (vertexList, instance) -> {
|
||||
Quaternionf q = new Quaternionf(instance.qX, instance.qY, instance.qZ, instance.qW);
|
||||
|
||||
Matrix4f modelMatrix = new Matrix4f();
|
||||
modelMatrix.translate(instance.posX + instance.pivotX, instance.posY + instance.pivotY, instance.posZ + instance.pivotZ);
|
||||
modelMatrix.rotate(q);
|
||||
modelMatrix.rotate(instance.rotation);
|
||||
modelMatrix.translate(-instance.pivotX, -instance.pivotY, -instance.pivotZ);
|
||||
|
||||
Matrix3f normalMatrix = new Matrix3f();
|
||||
normalMatrix.set(q);
|
||||
normalMatrix.set(instance.rotation);
|
||||
|
||||
float r = RenderMath.uf(instance.r);
|
||||
float g = RenderMath.uf(instance.g);
|
||||
|
@ -81,7 +79,7 @@ public class OrientedType implements InstanceType<OrientedInstance> {
|
|||
public InstanceBoundingSphereTransformer<OrientedInstance> getBoundingSphereTransformer() {
|
||||
return (boundingSphere, instance) -> {
|
||||
boundingSphere.sub(instance.pivotX, instance.pivotY, instance.pivotZ, 0);
|
||||
boundingSphere.rotate(new Quaternionf(instance.qX, instance.qY, instance.qZ, instance.qW));
|
||||
boundingSphere.rotate(instance.rotation);
|
||||
boundingSphere.add(instance.posX + instance.pivotX, instance.posY + instance.pivotY, instance.posZ + instance.pivotZ, 0);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@ public class OrientedWriter extends ColoredLitWriter<OrientedInstance> {
|
|||
MemoryUtil.memPutFloat(ptr + 20, instance.pivotX);
|
||||
MemoryUtil.memPutFloat(ptr + 24, instance.pivotY);
|
||||
MemoryUtil.memPutFloat(ptr + 28, instance.pivotZ);
|
||||
MemoryUtil.memPutFloat(ptr + 32, instance.qX);
|
||||
MemoryUtil.memPutFloat(ptr + 36, instance.qY);
|
||||
MemoryUtil.memPutFloat(ptr + 40, instance.qZ);
|
||||
MemoryUtil.memPutFloat(ptr + 44, instance.qW);
|
||||
MemoryUtil.memPutFloat(ptr + 32, instance.rotation.x);
|
||||
MemoryUtil.memPutFloat(ptr + 36, instance.rotation.y);
|
||||
MemoryUtil.memPutFloat(ptr + 40, instance.rotation.z);
|
||||
MemoryUtil.memPutFloat(ptr + 44, instance.rotation.w);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public class TransformedType implements InstanceType<TransformedInstance> {
|
|||
return (boundingSphere, instance) -> {
|
||||
var radius = boundingSphere.w;
|
||||
boundingSphere.w = 1;
|
||||
boundingSphere.mul(MatrixUtil.toJoml(instance.model));
|
||||
boundingSphere.mul(instance.model);
|
||||
boundingSphere.w = radius * MatrixUtil.extractScale(instance.model);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -73,22 +73,6 @@ public final class MatrixUtil {
|
|||
MemoryUtil.memPutFloat(ptr + 32, matrix.m22());
|
||||
}
|
||||
|
||||
public static void store(Matrix4f matrix, Matrix4f jomlMatrix) {
|
||||
jomlMatrix.set(matrix);
|
||||
}
|
||||
|
||||
public static Matrix4f toJoml(Matrix4f matrix) {
|
||||
return new Matrix4f(matrix);
|
||||
}
|
||||
|
||||
public static void store(Matrix3f matrix, org.joml.Matrix3f jomlMatrix) {
|
||||
jomlMatrix.set(matrix);
|
||||
}
|
||||
|
||||
public static Matrix3f toJoml(Matrix3f matrix) {
|
||||
return new Matrix3f(matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the greatest scale factor across all axes from the given matrix.
|
||||
*
|
||||
|
|
|
@ -49,6 +49,8 @@ public class FlwShaderUniforms implements ShaderUniforms {
|
|||
|
||||
private boolean dirty;
|
||||
|
||||
private final Matrix4f viewProjection = new Matrix4f();
|
||||
|
||||
public Active(long ptr) {
|
||||
this.ptr = ptr;
|
||||
MinecraftForge.EVENT_BUS.addListener(this);
|
||||
|
@ -83,18 +85,20 @@ public class FlwShaderUniforms implements ShaderUniforms {
|
|||
var camY = (float) (camera.y - renderOrigin.getY());
|
||||
var camZ = (float) (camera.z - renderOrigin.getZ());
|
||||
|
||||
// don't want to mutate viewProjection
|
||||
var vp = new Matrix4f(context.viewProjection());
|
||||
vp.translate(-camX, -camY, -camZ);
|
||||
viewProjection.set(context.viewProjection());
|
||||
viewProjection.translate(-camX, -camY, -camZ);
|
||||
|
||||
MatrixUtil.writeUnsafe(vp, ptr + 32);
|
||||
MatrixUtil.writeUnsafe(viewProjection, ptr + 32);
|
||||
MemoryUtil.memPutFloat(ptr + 96, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 100, camY);
|
||||
MemoryUtil.memPutFloat(ptr + 104, camZ);
|
||||
MemoryUtil.memPutFloat(ptr + 108, 0f); // vec4 alignment
|
||||
MemoryUtil.memPutInt(ptr + 112, getConstantAmbientLightFlag(context));
|
||||
|
||||
updateFrustum(context, camX, camY, camZ);
|
||||
if (!FRUSTUM_PAUSED || FRUSTUM_CAPTURE) {
|
||||
MoreMath.writePackedFrustumPlanes(ptr + 128, viewProjection);
|
||||
FRUSTUM_CAPTURE = false;
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
@ -127,17 +131,5 @@ public class FlwShaderUniforms implements ShaderUniforms {
|
|||
return true;
|
||||
}
|
||||
|
||||
private void updateFrustum(RenderContext context, float camX, float camY, float camZ) {
|
||||
if (FRUSTUM_PAUSED && !FRUSTUM_CAPTURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
var projection = MatrixUtil.toJoml(context.viewProjection());
|
||||
projection.translate(-camX, -camY, -camZ);
|
||||
|
||||
MoreMath.writePackedFrustumPlanes(ptr + 128, projection);
|
||||
|
||||
FRUSTUM_CAPTURE = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +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 net.minecraft.client.main.Main;
|
||||
|
||||
@Mixin(Main.class)
|
||||
public class ClientMainMixin {
|
||||
@Inject(method = "main([Ljava/lang/String;)V", at = @At("HEAD"))
|
||||
private static void flywheel$injectRenderDoc(CallbackInfo ci) {
|
||||
// Only try to load RenderDoc if a system property is set to true.
|
||||
if (System.getProperty("flw.loadRenderDoc") == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
System.loadLibrary("renderdoc");
|
||||
} catch (Throwable ignored) {
|
||||
// Oh well, we tried.
|
||||
// On Windows, RenderDoc installs to "C:\Program Files\RenderDoc\"
|
||||
System.err.println("Is RenderDoc in your PATH?");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
"BlockEntityTypeMixin",
|
||||
"BufferBuilderMixin",
|
||||
"ClientLevelMixin",
|
||||
"ClientMainMixin",
|
||||
"EntityTypeMixin",
|
||||
"FogUpdateMixin",
|
||||
"GlStateManagerMixin",
|
||||
|
|
Loading…
Reference in a new issue