mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-13 21:55:01 +01:00
Next level
- Rename all appropriate occurrences of "world" to "level" - Simplify uniform buffers - Fix indirect cull dispatch only binding frame uniforms - Fix level renderer reload resetting debug mode - Properly register backend argument
This commit is contained in:
parent
2f7fce29c3
commit
2365687950
33 changed files with 456 additions and 623 deletions
|
@ -34,7 +34,6 @@ import com.jozufozu.flywheel.vanilla.VanillaVisuals;
|
|||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.commands.synchronization.ArgumentTypeInfos;
|
||||
import net.minecraft.commands.synchronization.SingletonArgumentInfo;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
@ -50,6 +49,8 @@ import net.minecraftforge.fml.common.Mod;
|
|||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegisterEvent;
|
||||
|
||||
@Mod(Flywheel.ID)
|
||||
public class Flywheel {
|
||||
|
@ -69,6 +70,7 @@ public class Flywheel {
|
|||
IEventBus modEventBus = FMLJavaModLoadingContext.get()
|
||||
.getModEventBus();
|
||||
modEventBus.addListener(Flywheel::onCommonSetup);
|
||||
modEventBus.addListener(Flywheel::onRegister);
|
||||
|
||||
FlwConfig.get().registerSpecs(modLoadingContext);
|
||||
|
||||
|
@ -137,8 +139,11 @@ public class Flywheel {
|
|||
}
|
||||
|
||||
private static void onCommonSetup(FMLCommonSetupEvent event) {
|
||||
// FIXME: argument types also need to be registered to BuiltInRegistries.COMMAND_ARGUMENT_TYPE
|
||||
ArgumentTypeInfos.registerByClass(BackendArgument.class, SingletonArgumentInfo.contextFree(() -> BackendArgument.INSTANCE));
|
||||
ArgumentTypeInfos.registerByClass(BackendArgument.class, BackendArgument.INFO);
|
||||
}
|
||||
|
||||
private static void onRegister(RegisterEvent event) {
|
||||
event.register(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES, rl("backend"), () -> BackendArgument.INFO);
|
||||
}
|
||||
|
||||
private static void addDebugInfo(CustomizeGuiOverlayEvent.DebugText event) {
|
||||
|
|
|
@ -15,8 +15,8 @@ import com.jozufozu.flywheel.api.BackendImplemented;
|
|||
* When you call {@link #createInstance()} you are given an Instance object that you can manipulate however
|
||||
* you want. The changes you make to the Instance object are automatically made visible, and persistent.
|
||||
* Changing the position of your Instance object every frame means that that copy of the model will be in a
|
||||
* different position in the world each frame. Setting the position of your Instance once and not touching it
|
||||
* again means that your model will be in the same position in the world every frame. This persistence is useful
|
||||
* different position in the level each frame. Setting the position of your Instance once and not touching it
|
||||
* again means that your model will be in the same position in the level every frame. This persistence is useful
|
||||
* because it means the properties of your model don't have to be re-evaluated every frame.
|
||||
* </p>
|
||||
*
|
||||
|
|
|
@ -7,7 +7,7 @@ import net.minecraft.core.SectionPos;
|
|||
/**
|
||||
* A visual that listens to light updates.
|
||||
*
|
||||
* <p>If your visual moves around in the world at all, you should use {@link TickableVisual} or {@link DynamicVisual},
|
||||
* <p>If your visual moves around in the level at all, you should use {@link TickableVisual} or {@link DynamicVisual},
|
||||
* and poll for light yourself along with listening for updates. When your visual moves to a different section, call
|
||||
* {@link Notifier#notifySectionsChanged}.</p>
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,7 @@ public interface VisualizationContext {
|
|||
/**
|
||||
* All models render as if this position is (0, 0, 0).
|
||||
*
|
||||
* @return The origin of the renderer as a world position.
|
||||
* @return The origin of the renderer as a level position.
|
||||
*/
|
||||
Vec3i renderOrigin();
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ public class EngineImpl implements Engine {
|
|||
|
||||
private void flush(RenderContext ctx) {
|
||||
try (var state = GlStateTracker.getRestoreState()) {
|
||||
Uniforms.updateContext(ctx);
|
||||
Uniforms.update(ctx);
|
||||
drawManager.flush();
|
||||
environmentStorage.flush();
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
return;
|
||||
}
|
||||
|
||||
Uniforms.bindFrame();
|
||||
Uniforms.bindAll();
|
||||
cullProgram.bind();
|
||||
|
||||
environment.setupCull(cullProgram);
|
||||
|
|
|
@ -84,7 +84,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
|||
TextureBinder.bindLightAndOverlay();
|
||||
|
||||
vertexArray.bindForDraw();
|
||||
Uniforms.bindForDraw();
|
||||
Uniforms.bindAll();
|
||||
|
||||
for (var group : cullingGroups.values()) {
|
||||
group.submit(stage);
|
||||
|
@ -152,7 +152,7 @@ public class IndirectDrawManager extends DrawManager<IndirectInstancer<?>> {
|
|||
TextureBinder.bindLightAndOverlay();
|
||||
|
||||
vertexArray.bindForDraw();
|
||||
Uniforms.bindForDraw();
|
||||
Uniforms.bindAll();
|
||||
|
||||
var crumblingMaterial = SimpleMaterial.builder();
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
|
|||
}
|
||||
|
||||
try (var state = GlStateTracker.getRestoreState()) {
|
||||
Uniforms.bindForDraw();
|
||||
Uniforms.bindAll();
|
||||
vao.bindForDraw();
|
||||
TextureBinder.bindLightAndOverlay();
|
||||
|
||||
|
@ -154,7 +154,7 @@ public class InstancedDrawManager extends DrawManager<InstancedInstancer<?>> {
|
|||
var crumblingMaterial = SimpleMaterial.builder();
|
||||
|
||||
try (var state = GlStateTracker.getRestoreState()) {
|
||||
Uniforms.bindForDraw();
|
||||
Uniforms.bindAll();
|
||||
vao.bindForDraw();
|
||||
TextureBinder.bindLightAndOverlay();
|
||||
|
||||
|
|
|
@ -1,27 +1,25 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
public class FogUniforms implements UniformProvider {
|
||||
public static final int SIZE = 28;
|
||||
public final class FogUniforms extends UniformWriter {
|
||||
private static final int SIZE = 4 * 7;
|
||||
static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.FOG_INDEX, SIZE);
|
||||
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
}
|
||||
public static void update() {
|
||||
long ptr = BUFFER.ptr();
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
var color = RenderSystem.getShaderFogColor();
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, color[0]);
|
||||
MemoryUtil.memPutFloat(ptr + 4, color[1]);
|
||||
MemoryUtil.memPutFloat(ptr + 8, color[2]);
|
||||
MemoryUtil.memPutFloat(ptr + 12, color[3]);
|
||||
MemoryUtil.memPutFloat(ptr + 16, RenderSystem.getShaderFogStart());
|
||||
MemoryUtil.memPutFloat(ptr + 20, RenderSystem.getShaderFogEnd());
|
||||
MemoryUtil.memPutInt(ptr + 24, RenderSystem.getShaderFogShape()
|
||||
ptr = writeFloat(ptr, color[0]);
|
||||
ptr = writeFloat(ptr + 4, color[1]);
|
||||
ptr = writeFloat(ptr + 8, color[2]);
|
||||
ptr = writeFloat(ptr + 12, color[3]);
|
||||
ptr = writeFloat(ptr + 16, RenderSystem.getShaderFogStart());
|
||||
ptr = writeFloat(ptr + 20, RenderSystem.getShaderFogEnd());
|
||||
ptr = writeInt(ptr + 24, RenderSystem.getShaderFogShape()
|
||||
.getIndex());
|
||||
|
||||
BUFFER.markDirty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||
import com.jozufozu.flywheel.config.DebugMode;
|
||||
import com.jozufozu.flywheel.lib.math.MatrixMath;
|
||||
|
||||
import net.minecraft.client.Camera;
|
||||
|
@ -17,162 +16,160 @@ import net.minecraft.core.Vec3i;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class FrameUniforms implements UniformProvider {
|
||||
public static final int SIZE = 800;
|
||||
public int debugMode;
|
||||
public final class FrameUniforms extends UniformWriter {
|
||||
private static final int SIZE = 96 + 64 * 9 + 16 * 4 + 8 * 2 + 8 + 4 * 10;
|
||||
static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.FRAME_INDEX, SIZE);
|
||||
|
||||
@Nullable
|
||||
private RenderContext context;
|
||||
private static final Matrix4f VIEW = new Matrix4f();
|
||||
private static final Matrix4f VIEW_INVERSE = new Matrix4f();
|
||||
private static final Matrix4f VIEW_PREV = new Matrix4f();
|
||||
private static final Matrix4f PROJECTION = new Matrix4f();
|
||||
private static final Matrix4f PROJECTION_INVERSE = new Matrix4f();
|
||||
private static final Matrix4f PROJECTION_PREV = new Matrix4f();
|
||||
private static final Matrix4f VIEW_PROJECTION = new Matrix4f();
|
||||
private static final Matrix4f VIEW_PROJECTION_INVERSE = new Matrix4f();
|
||||
private static final Matrix4f VIEW_PROJECTION_PREV = new Matrix4f();
|
||||
|
||||
private final Matrix4f view = new Matrix4f();
|
||||
private final Matrix4f viewInverse = new Matrix4f();
|
||||
private final Matrix4f viewPrev = new Matrix4f();
|
||||
private final Matrix4f projection = new Matrix4f();
|
||||
private final Matrix4f projectionInverse = new Matrix4f();
|
||||
private final Matrix4f projectionPrev = new Matrix4f();
|
||||
private final Matrix4f viewProjection = new Matrix4f();
|
||||
private final Matrix4f viewProjectionInverse = new Matrix4f();
|
||||
private final Matrix4f viewProjectionPrev = new Matrix4f();
|
||||
private static final Vector3f CAMERA_POS = new Vector3f();
|
||||
private static final Vector3f CAMERA_POS_PREV = new Vector3f();
|
||||
private static final Vector3f CAMERA_LOOK = new Vector3f();
|
||||
private static final Vector3f CAMERA_LOOK_PREV = new Vector3f();
|
||||
private static final Vector2f CAMERA_ROT = new Vector2f();
|
||||
private static final Vector2f CAMERA_ROT_PREV = new Vector2f();
|
||||
|
||||
private final Vector3f cameraPositionPrev = new Vector3f();
|
||||
private final Vector3f cameraLookPrev = new Vector3f();
|
||||
private final Vector2f cameraRotPrev = new Vector2f();
|
||||
private static boolean firstWrite = true;
|
||||
|
||||
private boolean lastInit = false;
|
||||
private static int debugMode = DebugMode.OFF.ordinal();
|
||||
private static boolean frustumPaused = false;
|
||||
private static boolean frustumCapture = false;
|
||||
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
private FrameUniforms() {
|
||||
}
|
||||
|
||||
public void setContext(RenderContext context) {
|
||||
this.context = context;
|
||||
public static void debugMode(DebugMode mode) {
|
||||
debugMode = mode.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
public static void captureFrustum() {
|
||||
frustumPaused = true;
|
||||
frustumCapture = true;
|
||||
}
|
||||
|
||||
public static void unpauseFrustum() {
|
||||
frustumPaused = false;
|
||||
}
|
||||
|
||||
public static void update(RenderContext context) {
|
||||
long ptr = BUFFER.ptr();
|
||||
setPrev();
|
||||
|
||||
Vec3i renderOrigin = VisualizationManager.getOrThrow(context.level())
|
||||
.getRenderOrigin();
|
||||
var camera = context.camera();
|
||||
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
var camX = (float) (cameraPos.x - renderOrigin.getX());
|
||||
var camY = (float) (cameraPos.y - renderOrigin.getY());
|
||||
var camZ = (float) (cameraPos.z - renderOrigin.getZ());
|
||||
|
||||
view.set(context.stack().last().pose());
|
||||
view.translate(-camX, -camY, -camZ);
|
||||
projection.set(context.projection());
|
||||
viewProjection.set(context.viewProjection());
|
||||
viewProjection.translate(-camX, -camY, -camZ);
|
||||
VIEW.set(context.stack().last().pose());
|
||||
VIEW.translate(-camX, -camY, -camZ);
|
||||
PROJECTION.set(context.projection());
|
||||
VIEW_PROJECTION.set(context.viewProjection());
|
||||
VIEW_PROJECTION.translate(-camX, -camY, -camZ);
|
||||
|
||||
if (!Uniforms.frustumPaused || Uniforms.frustumCapture) {
|
||||
MatrixMath.writePackedFrustumPlanes(ptr, viewProjection);
|
||||
Uniforms.frustumCapture = false;
|
||||
CAMERA_POS.set(camX, camY, camZ);
|
||||
CAMERA_LOOK.set(camera.getLookVector());
|
||||
CAMERA_ROT.set(camera.getXRot(), camera.getYRot());
|
||||
|
||||
if (firstWrite) {
|
||||
setPrev();
|
||||
}
|
||||
|
||||
if (firstWrite || !frustumPaused || frustumCapture) {
|
||||
MatrixMath.writePackedFrustumPlanes(ptr, VIEW_PROJECTION);
|
||||
frustumCapture = false;
|
||||
}
|
||||
|
||||
ptr += 96;
|
||||
|
||||
// manage last values of matrices
|
||||
if (!lastInit) {
|
||||
viewPrev.set(view);
|
||||
projectionPrev.set(projection);
|
||||
viewProjectionPrev.set(viewProjectionPrev);
|
||||
}
|
||||
ptr = writeMatrices(ptr);
|
||||
viewPrev.set(view);
|
||||
projectionPrev.set(projection);
|
||||
viewProjectionPrev.set(viewProjection);
|
||||
|
||||
// last values for camera
|
||||
if (!lastInit) {
|
||||
cameraPositionPrev.set(camX, camY, camZ);
|
||||
cameraLookPrev.set(camera.getLookVector());
|
||||
cameraRotPrev.set(camera.getXRot(), camera.getYRot());
|
||||
}
|
||||
ptr = writeCamera(ptr, camX, camY, camZ);
|
||||
cameraPositionPrev.set(camX, camY, camZ);
|
||||
cameraLookPrev.set(camera.getLookVector());
|
||||
cameraRotPrev.set(camera.getXRot(), camera.getYRot());
|
||||
ptr = writeCamera(ptr);
|
||||
|
||||
var window = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
ptr = Uniforms.writeVec2(ptr, window.getWidth(), window.getHeight());
|
||||
|
||||
ptr = writeVec2(ptr, window.getWidth(), window.getHeight());
|
||||
ptr = writeFloat(ptr, (float) window.getWidth() / (float) window.getHeight());
|
||||
// default line width: net.minecraft.client.renderer.RenderStateShard.LineStateShard
|
||||
MemoryUtil.memPutFloat(ptr, Math.max(2.5F, (float) window.getWidth() / 1920.0F * 2.5F));
|
||||
ptr += 4;
|
||||
ptr = writeFloat(ptr, Math.max(2.5F, (float) window.getWidth() / 1920.0F * 2.5F));
|
||||
ptr = writeFloat(ptr, Minecraft.getInstance().gameRenderer.getDepthFar());
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, (float) window.getWidth() / (float) window.getHeight());
|
||||
ptr += 4;
|
||||
ptr = writeTime(ptr, context);
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, Minecraft.getInstance().gameRenderer.getDepthFar());
|
||||
ptr += 4;
|
||||
ptr = writeCameraIn(ptr, camera);
|
||||
|
||||
ptr = writeTime(ptr);
|
||||
ptr = writeInt(ptr, debugMode);
|
||||
|
||||
ptr = writeCameraIn(ptr);
|
||||
|
||||
MemoryUtil.memPutInt(ptr, debugMode);
|
||||
|
||||
lastInit = true;
|
||||
firstWrite = false;
|
||||
BUFFER.markDirty();
|
||||
}
|
||||
|
||||
private long writeMatrices(long ptr) {
|
||||
MatrixMath.writeUnsafe(view, ptr);
|
||||
MatrixMath.writeUnsafe(view.invert(viewInverse), ptr + 64);
|
||||
MatrixMath.writeUnsafe(viewPrev, ptr + 64 * 2);
|
||||
MatrixMath.writeUnsafe(projection, ptr + 64 * 3);
|
||||
MatrixMath.writeUnsafe(projection.invert(projectionInverse), ptr + 64 * 4);
|
||||
MatrixMath.writeUnsafe(projectionPrev, ptr + 64 * 5);
|
||||
MatrixMath.writeUnsafe(viewProjection, ptr + 64 * 6);
|
||||
MatrixMath.writeUnsafe(viewProjection.invert(viewProjectionInverse), ptr + 64 * 7);
|
||||
MatrixMath.writeUnsafe(viewProjectionPrev, ptr + 64 * 8);
|
||||
return ptr + 64 * 9;
|
||||
private static void setPrev() {
|
||||
VIEW_PREV.set(VIEW);
|
||||
PROJECTION_PREV.set(PROJECTION);
|
||||
VIEW_PROJECTION_PREV.set(VIEW_PROJECTION);
|
||||
CAMERA_POS_PREV.set(CAMERA_POS);
|
||||
CAMERA_LOOK_PREV.set(CAMERA_LOOK);
|
||||
CAMERA_ROT_PREV.set(CAMERA_ROT);
|
||||
}
|
||||
|
||||
private long writeCamera(long ptr, float camX, float camY, float camZ) {
|
||||
Camera camera = context.camera();
|
||||
Vector3f lookVector = camera.getLookVector();
|
||||
|
||||
ptr = Uniforms.writeVec3(ptr, camX, camY, camZ);
|
||||
ptr = Uniforms.writeVec3(ptr, cameraPositionPrev.x, cameraPositionPrev.y, cameraPositionPrev.z);
|
||||
|
||||
ptr = Uniforms.writeVec3(ptr, lookVector.x, lookVector.y, lookVector.z);
|
||||
ptr = Uniforms.writeVec3(ptr, cameraLookPrev.x, cameraLookPrev.y, cameraLookPrev.z);
|
||||
|
||||
ptr = Uniforms.writeVec2(ptr, camera.getXRot(), camera.getYRot());
|
||||
ptr = Uniforms.writeVec2(ptr, cameraRotPrev.x, cameraRotPrev.y);
|
||||
private static long writeMatrices(long ptr) {
|
||||
ptr = writeMat4(ptr, VIEW);
|
||||
ptr = writeMat4(ptr, VIEW.invert(VIEW_INVERSE));
|
||||
ptr = writeMat4(ptr, VIEW_PREV);
|
||||
ptr = writeMat4(ptr, PROJECTION);
|
||||
ptr = writeMat4(ptr, PROJECTION.invert(PROJECTION_INVERSE));
|
||||
ptr = writeMat4(ptr, PROJECTION_PREV);
|
||||
ptr = writeMat4(ptr, VIEW_PROJECTION);
|
||||
ptr = writeMat4(ptr, VIEW_PROJECTION.invert(VIEW_PROJECTION_INVERSE));
|
||||
ptr = writeMat4(ptr, VIEW_PROJECTION_PREV);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private long writeTime(long ptr) {
|
||||
private static long writeCamera(long ptr) {
|
||||
ptr = writeVec3(ptr, CAMERA_POS.x, CAMERA_POS.y, CAMERA_POS.z);
|
||||
ptr = writeVec3(ptr, CAMERA_POS_PREV.x, CAMERA_POS_PREV.y, CAMERA_POS_PREV.z);
|
||||
ptr = writeVec3(ptr, CAMERA_LOOK.x, CAMERA_LOOK.y, CAMERA_LOOK.z);
|
||||
ptr = writeVec3(ptr, CAMERA_LOOK_PREV.x, CAMERA_LOOK_PREV.y, CAMERA_LOOK_PREV.z);
|
||||
ptr = writeVec2(ptr, CAMERA_ROT.x, CAMERA_ROT.y);
|
||||
ptr = writeVec2(ptr, CAMERA_ROT_PREV.x, CAMERA_ROT_PREV.y);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private static long writeTime(long ptr, RenderContext context) {
|
||||
int ticks = context.renderer()
|
||||
.getTicks();
|
||||
float partialTick = context.partialTick();
|
||||
float renderTicks = ticks + partialTick;
|
||||
float renderSeconds = renderTicks / 20f;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, ticks);
|
||||
MemoryUtil.memPutFloat(ptr + 4, partialTick);
|
||||
MemoryUtil.memPutFloat(ptr + 8, renderTicks);
|
||||
MemoryUtil.memPutFloat(ptr + 12, renderSeconds);
|
||||
return ptr + 16;
|
||||
ptr = writeInt(ptr, ticks);
|
||||
ptr = writeFloat(ptr, partialTick);
|
||||
ptr = writeFloat(ptr, renderTicks);
|
||||
ptr = writeFloat(ptr, renderSeconds);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private long writeCameraIn(long ptr) {
|
||||
Camera camera = context.camera();
|
||||
private static long writeCameraIn(long ptr, Camera camera) {
|
||||
if (!camera.isInitialized()) {
|
||||
MemoryUtil.memPutInt(ptr, 0);
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
return ptr + 8;
|
||||
ptr = writeInt(ptr, 0);
|
||||
ptr = writeInt(ptr, 0);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Level level = camera.getEntity().level();
|
||||
BlockPos blockPos = camera.getBlockPosition();
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
return Uniforms.writeInFluidAndBlock(ptr, level, blockPos, cameraPos);
|
||||
return writeInFluidAndBlock(ptr, level, blockPos, cameraPos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
@ -10,72 +7,45 @@ import net.minecraft.resources.ResourceKey;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class LevelUniforms implements UniformProvider {
|
||||
public static final int SIZE = 13 * 4 + 2 * 16;
|
||||
public final class LevelUniforms extends UniformWriter {
|
||||
private static final int SIZE = 16 * 2 + 4 * 13;
|
||||
static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.LEVEL_INDEX, SIZE);
|
||||
|
||||
@Nullable
|
||||
private RenderContext context;
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
private LevelUniforms() {
|
||||
}
|
||||
|
||||
public void setContext(RenderContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
if (context == null) {
|
||||
MemoryUtil.memSet(ptr, 0, SIZE);
|
||||
return;
|
||||
}
|
||||
public static void update(RenderContext context) {
|
||||
long ptr = BUFFER.ptr();
|
||||
|
||||
ClientLevel level = context.level();
|
||||
float ptick = context.partialTick();
|
||||
float partialTick = context.partialTick();
|
||||
|
||||
Vec3 skyColor = level.getSkyColor(context.camera().getPosition(), ptick);
|
||||
ptr = Uniforms.writeVec4(ptr, (float) skyColor.x, (float) skyColor.y, (float) skyColor.z, 1f);
|
||||
|
||||
Vec3 cloudColor = level.getCloudColor(ptick);
|
||||
ptr = Uniforms.writeVec4(ptr, (float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 1f);
|
||||
Vec3 skyColor = level.getSkyColor(context.camera().getPosition(), partialTick);
|
||||
Vec3 cloudColor = level.getCloudColor(partialTick);
|
||||
ptr = writeVec4(ptr, (float) skyColor.x, (float) skyColor.y, (float) skyColor.z, 1f);
|
||||
ptr = writeVec4(ptr, (float) cloudColor.x, (float) cloudColor.y, (float) cloudColor.z, 1f);
|
||||
|
||||
long dayTime = level.getDayTime();
|
||||
long levelDay = dayTime / 24000L;
|
||||
long timeOfDay = dayTime - levelDay * 24000L;
|
||||
MemoryUtil.memPutInt(ptr, (int) (levelDay % 0x7FFFFFFFL));
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutFloat(ptr, (float) timeOfDay / 24000f);
|
||||
ptr += 4;
|
||||
float timeOfDay = (float) (dayTime - levelDay * 24000L) / 24000f;
|
||||
ptr = writeInt(ptr, (int) (levelDay % 0x7FFFFFFFL));
|
||||
ptr = writeFloat(ptr, timeOfDay);
|
||||
|
||||
MemoryUtil.memPutInt(ptr, level.dimensionType().hasSkyLight() ? 1 : 0);
|
||||
ptr += 4;
|
||||
ptr = writeInt(ptr, level.dimensionType().hasSkyLight() ? 1 : 0);
|
||||
|
||||
float sunAngle = level.getSunAngle(ptick);
|
||||
MemoryUtil.memPutFloat(ptr, sunAngle);
|
||||
ptr += 4;
|
||||
ptr = writeFloat(ptr, level.getSunAngle(partialTick));
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, level.getMoonBrightness());
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, level.getMoonPhase());
|
||||
ptr += 4;
|
||||
ptr = writeFloat(ptr, level.getMoonBrightness());
|
||||
ptr = writeInt(ptr, level.getMoonPhase());
|
||||
|
||||
MemoryUtil.memPutInt(ptr, level.isRaining() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutFloat(ptr, level.getRainLevel(ptick));
|
||||
ptr += 4;
|
||||
ptr = writeInt(ptr, level.isRaining() ? 1 : 0);
|
||||
ptr = writeFloat(ptr, level.getRainLevel(partialTick));
|
||||
ptr = writeInt(ptr, level.isThundering() ? 1 : 0);
|
||||
ptr = writeFloat(ptr, level.getThunderLevel(partialTick));
|
||||
|
||||
MemoryUtil.memPutInt(ptr, level.isThundering() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutFloat(ptr, level.getThunderLevel(ptick));
|
||||
ptr += 4;
|
||||
ptr = writeFloat(ptr, level.getSkyDarken(partialTick));
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, level.getSkyDarken(ptick));
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, getConstantAmbientLightFlag(context));
|
||||
ptr += 4;
|
||||
ptr = writeInt(ptr, level.effects().constantAmbientLight() ? 1 : 0);
|
||||
|
||||
// TODO: use defines for custom dimension ids
|
||||
int dimensionId;
|
||||
|
@ -89,13 +59,8 @@ public class LevelUniforms implements UniformProvider {
|
|||
} else {
|
||||
dimensionId = -1;
|
||||
}
|
||||
MemoryUtil.memPutInt(ptr, dimensionId);
|
||||
}
|
||||
ptr = writeInt(ptr, dimensionId);
|
||||
|
||||
private static int getConstantAmbientLightFlag(RenderContext context) {
|
||||
var constantAmbientLight = context.level()
|
||||
.effects()
|
||||
.constantAmbientLight();
|
||||
return constantAmbientLight ? 1 : 0;
|
||||
}
|
||||
BUFFER.markDirty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,61 +1,29 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.Options;
|
||||
|
||||
public class OptionsUniforms implements UniformProvider {
|
||||
public static final int SIZE = 4 * 14;
|
||||
public final class OptionsUniforms extends UniformWriter {
|
||||
private static final int SIZE = 4 * 14;
|
||||
static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.OPTIONS_INDEX, SIZE);
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
}
|
||||
public static void update(Options options) {
|
||||
long ptr = BUFFER.ptr();
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
Options options = Minecraft.getInstance().options;
|
||||
ptr = writeFloat(ptr, options.gamma().get().floatValue());
|
||||
ptr = writeInt(ptr, options.fov().get());
|
||||
ptr = writeFloat(ptr, options.screenEffectScale().get().floatValue());
|
||||
ptr = writeFloat(ptr, options.glintSpeed().get().floatValue());
|
||||
ptr = writeFloat(ptr, options.glintStrength().get().floatValue());
|
||||
ptr = writeInt(ptr, options.biomeBlendRadius().get());
|
||||
ptr = writeInt(ptr, options.ambientOcclusion().get() ? 1 : 0);
|
||||
ptr = writeInt(ptr, options.bobView().get() ? 1 : 0);
|
||||
ptr = writeInt(ptr, options.highContrast().get() ? 1 : 0);
|
||||
ptr = writeFloat(ptr, options.textBackgroundOpacity().get().floatValue());
|
||||
ptr = writeInt(ptr, options.backgroundForChatOnly().get() ? 1 : 0);
|
||||
ptr = writeFloat(ptr, options.darknessEffectScale().get().floatValue());
|
||||
ptr = writeFloat(ptr, options.damageTiltStrength().get().floatValue());
|
||||
ptr = writeInt(ptr, options.hideLightningFlash().get() ? 1 : 0);
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.gamma().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.fov().get());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.screenEffectScale().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.glintSpeed().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.glintStrength().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.biomeBlendRadius().get());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.ambientOcclusion().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.bobView().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.highContrast().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.textBackgroundOpacity().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.backgroundForChatOnly().get() ? 1 : 0);
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.darknessEffectScale().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, options.damageTiltStrength().get().floatValue());
|
||||
ptr += 4;
|
||||
|
||||
MemoryUtil.memPutInt(ptr, options.hideLightningFlash().get() ? 1 : 0);
|
||||
BUFFER.markDirty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.backend.mixin.AbstractClientPlayerAccessor;
|
||||
|
@ -20,108 +19,94 @@ import net.minecraft.world.level.block.Block;
|
|||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
|
||||
public class PlayerUniforms implements UniformProvider {
|
||||
public static final int SIZE = 9 * 4 + 8 + 2 * 16;
|
||||
public final class PlayerUniforms extends UniformWriter {
|
||||
private static final int SIZE = 16 * 2 + 8 + 4 * 9;
|
||||
static final UniformBuffer BUFFER = new UniformBuffer(Uniforms.PLAYER_INDEX, SIZE);
|
||||
|
||||
@Nullable
|
||||
private RenderContext context;
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return SIZE;
|
||||
private PlayerUniforms() {
|
||||
}
|
||||
|
||||
public void setContext(RenderContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(long ptr) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
LocalPlayer player = mc.player;
|
||||
if (context == null || player == null) {
|
||||
MemoryUtil.memSet(ptr, 0, SIZE);
|
||||
public static void update(RenderContext context) {
|
||||
LocalPlayer player = Minecraft.getInstance().player;
|
||||
if (player == null) {
|
||||
BUFFER.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
long ptr = BUFFER.ptr();
|
||||
|
||||
PlayerInfo info = ((AbstractClientPlayerAccessor) player).flywheel$getPlayerInfo();
|
||||
|
||||
Vec3 eyePos = player.getEyePosition(context.partialTick());
|
||||
ptr = Uniforms.writeVec3(ptr, (float) eyePos.x, (float) eyePos.y, (float) eyePos.z);
|
||||
ptr = writeVec3(ptr, (float) eyePos.x, (float) eyePos.y, (float) eyePos.z);
|
||||
|
||||
ptr = writeTeamColor(ptr, info);
|
||||
ptr = writeTeamColor(ptr, info.getTeam());
|
||||
|
||||
ptr = writeEyeBrightness(ptr, player);
|
||||
|
||||
ptr = writeHeldLight(ptr, player);
|
||||
|
||||
ptr = writeEyeIn(ptr, player);
|
||||
|
||||
MemoryUtil.memPutInt(ptr, player.isCrouching() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, player.isSleeping() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, player.isSwimming() ? 1 : 0);
|
||||
ptr += 4;
|
||||
MemoryUtil.memPutInt(ptr, player.isFallFlying() ? 1 : 0);
|
||||
ptr += 4;
|
||||
ptr = writeInt(ptr, player.isCrouching() ? 1 : 0);
|
||||
ptr = writeInt(ptr, player.isSleeping() ? 1 : 0);
|
||||
ptr = writeInt(ptr, player.isSwimming() ? 1 : 0);
|
||||
ptr = writeInt(ptr, player.isFallFlying() ? 1 : 0);
|
||||
|
||||
MemoryUtil.memPutInt(ptr, player.isShiftKeyDown() ? 1 : 0);
|
||||
ptr += 4;
|
||||
ptr = writeInt(ptr, player.isShiftKeyDown() ? 1 : 0);
|
||||
|
||||
MemoryUtil.memPutInt(ptr, info.getGameMode().getId());
|
||||
ptr += 4;
|
||||
ptr = writeInt(ptr, info.getGameMode().getId());
|
||||
|
||||
BUFFER.markDirty();
|
||||
}
|
||||
|
||||
private static long writeTeamColor(long ptr, PlayerInfo info) {
|
||||
int red = 255, green = 255, blue = 255, alpha = 0;
|
||||
PlayerTeam team = info.getTeam();
|
||||
private static long writeTeamColor(long ptr, @Nullable PlayerTeam team) {
|
||||
if (team != null) {
|
||||
alpha = 255;
|
||||
Integer color = team.getColor().getColor();
|
||||
if (color != null) {
|
||||
int icolor = color;
|
||||
red = FastColor.ARGB32.red(icolor);
|
||||
green = FastColor.ARGB32.green(icolor);
|
||||
blue = FastColor.ARGB32.blue(icolor);
|
||||
}
|
||||
}
|
||||
|
||||
return Uniforms.writeVec4(ptr, (float) red / 255f, (float) blue / 255f, (float) green / 255f,
|
||||
(float) alpha / 255f);
|
||||
if (color != null) {
|
||||
int red = FastColor.ARGB32.red(color);
|
||||
int green = FastColor.ARGB32.green(color);
|
||||
int blue = FastColor.ARGB32.blue(color);
|
||||
return writeVec4(ptr, red / 255f, green / 255f, blue / 255f, 1f);
|
||||
} else {
|
||||
return writeVec4(ptr, 1f, 1f, 1f, 1f);
|
||||
}
|
||||
} else {
|
||||
return writeVec4(ptr, 1f, 1f, 1f, 0f);
|
||||
}
|
||||
}
|
||||
|
||||
private static long writeEyeBrightness(long ptr, LocalPlayer player) {
|
||||
int blockBrightness = player.clientLevel.getBrightness(LightLayer.BLOCK, player.blockPosition());
|
||||
int skyBrightness = player.clientLevel.getBrightness(LightLayer.SKY, player.blockPosition());
|
||||
int maxBrightness = player.clientLevel.getMaxLightLevel();
|
||||
ClientLevel level = player.clientLevel;
|
||||
int blockBrightness = level.getBrightness(LightLayer.BLOCK, player.blockPosition());
|
||||
int skyBrightness = level.getBrightness(LightLayer.SKY, player.blockPosition());
|
||||
int maxBrightness = level.getMaxLightLevel();
|
||||
|
||||
ptr = Uniforms.writeVec2(ptr, (float) blockBrightness / (float) maxBrightness,
|
||||
return writeVec2(ptr, (float) blockBrightness / (float) maxBrightness,
|
||||
(float) skyBrightness / (float) maxBrightness);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private static long writeHeldLight(long ptr, LocalPlayer player) {
|
||||
int luminance = 0;
|
||||
int heldLight = 0;
|
||||
|
||||
for (InteractionHand hand : InteractionHand.values()) {
|
||||
Item handItem = player.getItemInHand(hand).getItem();
|
||||
if (handItem instanceof BlockItem bitem) {
|
||||
Block block = bitem.getBlock();
|
||||
int blockLight = block.defaultBlockState().getLightEmission(player.clientLevel, BlockPos.ZERO);
|
||||
if (luminance < blockLight) {
|
||||
luminance = blockLight;
|
||||
int blockLight = block.defaultBlockState().getLightEmission(player.clientLevel, player.blockPosition());
|
||||
if (heldLight < blockLight) {
|
||||
heldLight = blockLight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemoryUtil.memPutFloat(ptr, (float) luminance / 15);
|
||||
return ptr + 4;
|
||||
return writeFloat(ptr, (float) heldLight / 15);
|
||||
}
|
||||
|
||||
private static long writeEyeIn(long ptr, LocalPlayer player) {
|
||||
ClientLevel level = player.clientLevel;
|
||||
Vec3 eyePos = player.getEyePosition();
|
||||
BlockPos blockPos = BlockPos.containing(eyePos);
|
||||
return Uniforms.writeInFluidAndBlock(ptr, level, blockPos, eyePos);
|
||||
return writeInFluidAndBlock(ptr, level, blockPos, eyePos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||
|
@ -7,35 +8,53 @@ import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
|
|||
import com.jozufozu.flywheel.lib.math.MoreMath;
|
||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||
|
||||
public class UniformBuffer<T extends UniformProvider> {
|
||||
public class UniformBuffer {
|
||||
private final int index;
|
||||
private final GlBuffer buffer;
|
||||
public final T provider;
|
||||
private final MemoryBlock data;
|
||||
private final MemoryBlock clientBuffer;
|
||||
@Nullable
|
||||
private GlBuffer buffer;
|
||||
private boolean needsUpload;
|
||||
|
||||
public UniformBuffer(int index, T provider) {
|
||||
public UniformBuffer(int index, int size) {
|
||||
this.index = index;
|
||||
this.buffer = new GlBuffer(GlBufferUsage.DYNAMIC_DRAW);
|
||||
this.provider = provider;
|
||||
|
||||
// renderdoc complains if the size of the buffer is not 16-byte aligned,
|
||||
// though things work fine on my machine if we're short a few bytes
|
||||
var actualBytes = MoreMath.align16(provider.byteSize());
|
||||
this.data = MemoryBlock.mallocTracked(actualBytes);
|
||||
this.data.clear();
|
||||
clientBuffer = MemoryBlock.malloc(MoreMath.align16(size));
|
||||
clientBuffer.clear();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
provider.write(data.ptr());
|
||||
buffer.upload(data);
|
||||
public long ptr() {
|
||||
return clientBuffer.ptr();
|
||||
}
|
||||
|
||||
public void markDirty() {
|
||||
needsUpload = true;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
clientBuffer.clear();
|
||||
markDirty();
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
GL32.glBindBufferRange(GL32.GL_UNIFORM_BUFFER, index, buffer.handle(), 0, data.size());
|
||||
if (buffer == null) {
|
||||
buffer = new GlBuffer(GlBufferUsage.DYNAMIC_DRAW);
|
||||
needsUpload = true;
|
||||
}
|
||||
|
||||
if (needsUpload) {
|
||||
buffer.upload(clientBuffer);
|
||||
needsUpload = false;
|
||||
}
|
||||
|
||||
GL32.glBindBufferRange(GL32.GL_UNIFORM_BUFFER, index, buffer.handle(), 0, clientBuffer.size());
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
data.free();
|
||||
buffer.delete();
|
||||
if (buffer != null) {
|
||||
buffer.delete();
|
||||
buffer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
public interface UniformProvider {
|
||||
void write(long ptr);
|
||||
|
||||
int byteSize();
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.lib.math.MatrixMath;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
class UniformWriter {
|
||||
static long writeInt(long ptr, int value) {
|
||||
MemoryUtil.memPutInt(ptr, value);
|
||||
return ptr + 4;
|
||||
}
|
||||
|
||||
static long writeFloat(long ptr, float value) {
|
||||
MemoryUtil.memPutFloat(ptr, value);
|
||||
return ptr + 4;
|
||||
}
|
||||
|
||||
static long writeVec2(long ptr, float x, float y) {
|
||||
MemoryUtil.memPutFloat(ptr, x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||
return ptr + 8;
|
||||
}
|
||||
|
||||
static long writeVec3(long ptr, float x, float y, float z) {
|
||||
MemoryUtil.memPutFloat(ptr, x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||
MemoryUtil.memPutFloat(ptr + 8, z);
|
||||
MemoryUtil.memPutFloat(ptr + 12, 0f); // empty component of vec4 because we don't trust std140
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
static long writeVec4(long ptr, float x, float y, float z, float w) {
|
||||
MemoryUtil.memPutFloat(ptr, x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||
MemoryUtil.memPutFloat(ptr + 8, z);
|
||||
MemoryUtil.memPutFloat(ptr + 12, w);
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
static long writeMat4(long ptr, Matrix4f mat) {
|
||||
MatrixMath.writeUnsafe(mat, ptr);
|
||||
return ptr + 64;
|
||||
}
|
||||
|
||||
static long writeInFluidAndBlock(long ptr, Level level, BlockPos blockPos, Vec3 pos) {
|
||||
FluidState fluidState = level.getFluidState(blockPos);
|
||||
BlockState blockState = level.getBlockState(blockPos);
|
||||
float height = fluidState.getHeight(level, blockPos);
|
||||
|
||||
if (fluidState.isEmpty()) {
|
||||
MemoryUtil.memPutInt(ptr, 0);
|
||||
} else if (pos.y < blockPos.getY() + height) {
|
||||
// TODO: handle custom fluids via defines
|
||||
if (fluidState.is(FluidTags.WATER)) {
|
||||
MemoryUtil.memPutInt(ptr, 1);
|
||||
} else if (fluidState.is(FluidTags.LAVA)) {
|
||||
MemoryUtil.memPutInt(ptr, 2);
|
||||
} else {
|
||||
MemoryUtil.memPutInt(ptr, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (blockState.isAir()) {
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
} else {
|
||||
// TODO: handle custom blocks via defines
|
||||
if (blockState.is(Blocks.POWDER_SNOW)) {
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
} else {
|
||||
MemoryUtil.memPutInt(ptr + 4, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return ptr + 8;
|
||||
}
|
||||
}
|
|
@ -1,221 +1,39 @@
|
|||
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||
import com.jozufozu.flywheel.config.DebugMode;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class Uniforms {
|
||||
public final class Uniforms {
|
||||
public static final int FRAME_INDEX = 0;
|
||||
public static final int FOG_INDEX = 1;
|
||||
public static final int OPTIONS_INDEX = 2;
|
||||
public static final int PLAYER_INDEX = 3;
|
||||
public static final int LEVEL_INDEX = 4;
|
||||
public static boolean frustumPaused = false;
|
||||
public static boolean frustumCapture = false;
|
||||
private static @Nullable UniformBuffer<FrameUniforms> frame;
|
||||
private static @Nullable UniformBuffer<FogUniforms> fog;
|
||||
private static @Nullable UniformBuffer<OptionsUniforms> options;
|
||||
private static @Nullable UniformBuffer<PlayerUniforms> player;
|
||||
private static @Nullable UniformBuffer<LevelUniforms> level;
|
||||
private static boolean optionsRequiresUpdate = false;
|
||||
|
||||
public static UniformBuffer<FrameUniforms> frame() {
|
||||
if (frame == null) {
|
||||
frame = new UniformBuffer<>(FRAME_INDEX, new FrameUniforms());
|
||||
}
|
||||
return frame;
|
||||
private static final UniformBuffer[] ALL_BUFFERS = { FrameUniforms.BUFFER, FogUniforms.BUFFER, OptionsUniforms.BUFFER, PlayerUniforms.BUFFER, LevelUniforms.BUFFER };
|
||||
|
||||
private Uniforms() {
|
||||
}
|
||||
|
||||
public static UniformBuffer<FogUniforms> fog() {
|
||||
if (fog == null) {
|
||||
fog = new UniformBuffer<>(FOG_INDEX, new FogUniforms());
|
||||
}
|
||||
return fog;
|
||||
public static void update(RenderContext context) {
|
||||
FrameUniforms.update(context);
|
||||
PlayerUniforms.update(context);
|
||||
LevelUniforms.update(context);
|
||||
}
|
||||
|
||||
public static UniformBuffer<OptionsUniforms> options() {
|
||||
if (options == null) {
|
||||
options = new UniformBuffer<>(OPTIONS_INDEX, new OptionsUniforms());
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
public static UniformBuffer<PlayerUniforms> player() {
|
||||
if (player == null) {
|
||||
player = new UniformBuffer<>(PLAYER_INDEX, new PlayerUniforms());
|
||||
}
|
||||
return player;
|
||||
}
|
||||
|
||||
public static UniformBuffer<LevelUniforms> level() {
|
||||
if (level == null) {
|
||||
level = new UniformBuffer<>(LEVEL_INDEX, new LevelUniforms());
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
public static void bindForDraw() {
|
||||
bindFrame();
|
||||
bindFog();
|
||||
bindOptions();
|
||||
bindPlayer();
|
||||
bindLevel();
|
||||
}
|
||||
|
||||
public static void bindFrame() {
|
||||
if (frame != null) {
|
||||
frame.bind();
|
||||
public static void bindAll() {
|
||||
for (UniformBuffer buffer : ALL_BUFFERS) {
|
||||
buffer.bind();
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindFog() {
|
||||
if (fog != null) {
|
||||
fog.bind();
|
||||
private static void deleteAll() {
|
||||
for (UniformBuffer buffer : ALL_BUFFERS) {
|
||||
buffer.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindOptions() {
|
||||
if (options != null) {
|
||||
options.bind();
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindPlayer() {
|
||||
if (player != null) {
|
||||
player.bind();
|
||||
}
|
||||
}
|
||||
|
||||
public static void bindLevel() {
|
||||
if (level != null) {
|
||||
level.bind();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onFogUpdate() {
|
||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||
fog().update();
|
||||
}
|
||||
}
|
||||
|
||||
public static void onOptionsUpdate() {
|
||||
// this is sometimes called too early to do an actual update
|
||||
optionsRequiresUpdate = true;
|
||||
}
|
||||
|
||||
public static void updateContext(RenderContext ctx) {
|
||||
var ubo = frame();
|
||||
ubo.provider.setContext(ctx);
|
||||
ubo.update();
|
||||
|
||||
if (optionsRequiresUpdate) {
|
||||
options().update();
|
||||
optionsRequiresUpdate = false;
|
||||
}
|
||||
|
||||
var player = player();
|
||||
player.provider.setContext(ctx);
|
||||
player.update();
|
||||
|
||||
var level = level();
|
||||
level.provider.setContext(ctx);
|
||||
level.update();
|
||||
}
|
||||
|
||||
public static void setDebugMode(DebugMode mode) {
|
||||
frame().provider.debugMode = mode.ordinal();
|
||||
}
|
||||
|
||||
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
|
||||
if (frame != null) {
|
||||
frame.delete();
|
||||
frame = null;
|
||||
}
|
||||
|
||||
if (fog != null) {
|
||||
fog.delete();
|
||||
fog = null;
|
||||
}
|
||||
|
||||
if (options != null) {
|
||||
options.delete();
|
||||
options = null;
|
||||
}
|
||||
|
||||
if (player != null) {
|
||||
player.delete();
|
||||
player = null;
|
||||
}
|
||||
|
||||
if (level != null) {
|
||||
level.delete();
|
||||
level = null;
|
||||
}
|
||||
}
|
||||
|
||||
static long writeVec4(long ptr, float x, float y, float z, float w) {
|
||||
MemoryUtil.memPutFloat(ptr, x);
|
||||
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||
MemoryUtil.memPutFloat(ptr + 8, z);
|
||||
MemoryUtil.memPutFloat(ptr + 12, w);
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
static long writeVec3(long ptr, float camX, float camY, float camZ) {
|
||||
MemoryUtil.memPutFloat(ptr, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 4, camY);
|
||||
MemoryUtil.memPutFloat(ptr + 8, camZ);
|
||||
MemoryUtil.memPutFloat(ptr + 12, 0f); // empty component of vec4 because we don't trust std140
|
||||
return ptr + 16;
|
||||
}
|
||||
|
||||
static long writeVec2(long ptr, float camX, float camY) {
|
||||
MemoryUtil.memPutFloat(ptr, camX);
|
||||
MemoryUtil.memPutFloat(ptr + 4, camY);
|
||||
return ptr + 8;
|
||||
}
|
||||
|
||||
static long writeInFluidAndBlock(long ptr, Level level, BlockPos blockPos, Vec3 pos) {
|
||||
FluidState fState = level.getFluidState(blockPos);
|
||||
BlockState bState = level.getBlockState(blockPos);
|
||||
float height = fState.getHeight(level, blockPos);
|
||||
|
||||
if (fState.isEmpty()) {
|
||||
MemoryUtil.memPutInt(ptr, 0);
|
||||
} else if (pos.y < blockPos.getY() + height) {
|
||||
// TODO: handle custom fluids via defines
|
||||
if (fState.is(FluidTags.WATER)) {
|
||||
MemoryUtil.memPutInt(ptr, 1);
|
||||
} else if (fState.is(FluidTags.LAVA)) {
|
||||
MemoryUtil.memPutInt(ptr, 2);
|
||||
} else {
|
||||
MemoryUtil.memPutInt(ptr, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (bState.isAir()) {
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
} else {
|
||||
// TODO: handle custom blocks via defines
|
||||
if (bState.is(Blocks.POWDER_SNOW)) {
|
||||
MemoryUtil.memPutInt(ptr + 4, 0);
|
||||
} else {
|
||||
MemoryUtil.memPutInt(ptr + 4, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return ptr + 8;
|
||||
deleteAll();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ public class GlBuffer extends GlObject {
|
|||
public void upload(MemoryBlock memoryBlock) {
|
||||
upload(memoryBlock.ptr(), memoryBlock.size());
|
||||
}
|
||||
|
||||
public void upload(long ptr, long size) {
|
||||
FlwMemoryTracker._freeGPUMemory(this.size);
|
||||
Buffer.IMPL.data(handle(), size, ptr, usage.glEnum);
|
||||
|
|
|
@ -5,7 +5,7 @@ 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.engine.uniform.Uniforms;
|
||||
import com.jozufozu.flywheel.backend.engine.uniform.OptionsUniforms;
|
||||
|
||||
import net.minecraft.client.Options;
|
||||
|
||||
|
@ -13,11 +13,11 @@ import net.minecraft.client.Options;
|
|||
public class OptionsMixin {
|
||||
@Inject(method = "load()V", at = @At("RETURN"))
|
||||
private void flywheel$onLoad(CallbackInfo ci) {
|
||||
Uniforms.onOptionsUpdate();
|
||||
OptionsUniforms.update((Options) (Object) this);
|
||||
}
|
||||
|
||||
@Inject(method = "save", at = @At("HEAD"))
|
||||
private void flywheel$onSave(CallbackInfo ci) {
|
||||
Uniforms.onOptionsUpdate();
|
||||
OptionsUniforms.update((Options) (Object) this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ 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.engine.uniform.Uniforms;
|
||||
import com.jozufozu.flywheel.backend.engine.uniform.FogUniforms;
|
||||
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
|
@ -18,21 +18,21 @@ abstract class RenderSystemMixin {
|
|||
|
||||
@Inject(method = "setShaderFogStart(F)V", at = @At("RETURN"))
|
||||
private static void flywheel$onSetFogStart(CallbackInfo ci) {
|
||||
Uniforms.onFogUpdate();
|
||||
FogUniforms.update();
|
||||
}
|
||||
|
||||
@Inject(method = "setShaderFogEnd(F)V", at = @At("RETURN"))
|
||||
private static void flywheel$onSetFogEnd(CallbackInfo ci) {
|
||||
Uniforms.onFogUpdate();
|
||||
FogUniforms.update();
|
||||
}
|
||||
|
||||
@Inject(method = "setShaderFogShape(Lcom/mojang/blaze3d/shaders/FogShape;)V", at = @At("RETURN"))
|
||||
private static void flywheel$onSetFogShape(CallbackInfo ci) {
|
||||
Uniforms.onFogUpdate();
|
||||
FogUniforms.update();
|
||||
}
|
||||
|
||||
@Inject(method = "setShaderFogColor(FFFF)V", at = @At("RETURN"))
|
||||
private static void flywheel$onSetFogColor(CallbackInfo ci) {
|
||||
Uniforms.onFogUpdate();
|
||||
FogUniforms.update();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.mojang.brigadier.suggestion.Suggestions;
|
|||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import net.minecraft.commands.SharedSuggestionProvider;
|
||||
import net.minecraft.commands.synchronization.SingletonArgumentInfo;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
|
@ -27,6 +28,7 @@ public class BackendArgument implements ArgumentType<Backend> {
|
|||
});
|
||||
|
||||
public static final BackendArgument INSTANCE = new BackendArgument();
|
||||
public static final SingletonArgumentInfo<BackendArgument> INFO = SingletonArgumentInfo.contextFree(() -> INSTANCE);
|
||||
|
||||
@Override
|
||||
public Backend parse(StringReader reader) throws CommandSyntaxException {
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.function.BiConsumer;
|
|||
|
||||
import com.jozufozu.flywheel.api.backend.Backend;
|
||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||
import com.jozufozu.flywheel.backend.engine.uniform.FrameUniforms;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
|
@ -78,27 +78,6 @@ public final class FlwCommands {
|
|||
}
|
||||
));
|
||||
|
||||
command.then(Commands.literal("debug")
|
||||
.then(Commands.argument("mode", EnumArgument.enumArgument(DebugMode.class))
|
||||
.executes(context -> {
|
||||
DebugMode mode = context.getArgument("mode", DebugMode.class);
|
||||
Uniforms.setDebugMode(mode);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
command.then(Commands.literal("frustum")
|
||||
.then(Commands.literal("unpause")
|
||||
.executes(context -> {
|
||||
Uniforms.frustumPaused = false;
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}))
|
||||
.then(Commands.literal("capture")
|
||||
.executes(context -> {
|
||||
Uniforms.frustumPaused = true;
|
||||
Uniforms.frustumCapture = true;
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
command.then(Commands.literal("crumbling")
|
||||
.then(Commands.argument("pos", BlockPosArgument.blockPos())
|
||||
.then(Commands.argument("stage", IntegerArgumentType.integer(0, 9))
|
||||
|
@ -119,6 +98,26 @@ public final class FlwCommands {
|
|||
return Command.SINGLE_SUCCESS;
|
||||
}))));
|
||||
|
||||
command.then(Commands.literal("debug")
|
||||
.then(Commands.argument("mode", EnumArgument.enumArgument(DebugMode.class))
|
||||
.executes(context -> {
|
||||
DebugMode mode = context.getArgument("mode", DebugMode.class);
|
||||
FrameUniforms.debugMode(mode);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
command.then(Commands.literal("frustum")
|
||||
.then(Commands.literal("capture")
|
||||
.executes(context -> {
|
||||
FrameUniforms.captureFrustum();
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}))
|
||||
.then(Commands.literal("unpause")
|
||||
.executes(context -> {
|
||||
FrameUniforms.unpauseFrustum();
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})));
|
||||
|
||||
event.getDispatcher().register(command);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ import net.minecraft.world.level.LevelAccessor;
|
|||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
/**
|
||||
* A manager class for a single world where visualization is supported.
|
||||
* A manager class for a single level where visualization is supported.
|
||||
*/
|
||||
public class VisualizationManagerImpl implements VisualizationManager {
|
||||
private static final LevelAttached<VisualizationManagerImpl> MANAGERS = new LevelAttached<>(VisualizationManagerImpl::new, VisualizationManagerImpl::delete);
|
||||
|
@ -212,7 +212,7 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
/**
|
||||
* Tick the visuals after the game has ticked:
|
||||
* <p>
|
||||
* Call {@link TickableVisual#tick} on all visuals in this world.
|
||||
* Call {@link TickableVisual#tick} on all visuals in this level.
|
||||
* </p>
|
||||
*/
|
||||
public void tick() {
|
||||
|
@ -231,7 +231,7 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
*
|
||||
* <p>Check and update the render origin.
|
||||
* <br>
|
||||
* Call {@link DynamicVisual#beginFrame} on all visuals in this world.</p>
|
||||
* Call {@link DynamicVisual#beginFrame} on all visuals in this level.</p>
|
||||
*/
|
||||
public void beginFrame(RenderContext context) {
|
||||
// Make sure we're done with the last tick.
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
package com.jozufozu.flywheel.lib.instance;
|
||||
|
||||
import com.jozufozu.flywheel.api.instance.Instance;
|
||||
import com.jozufozu.flywheel.lib.visual.AbstractVisual;
|
||||
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
|
||||
/**
|
||||
* An interface that implementors of {@link Instance} should also implement
|
||||
* if they wish to make use of Flywheel's provided light update methods.
|
||||
* if they wish to make use of the relighting utilities in {@link AbstractVisual}.
|
||||
*/
|
||||
public interface FlatLit extends Instance {
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,6 @@ import net.minecraft.world.level.BlockAndTintGetter;
|
|||
import net.minecraft.world.level.LightLayer;
|
||||
|
||||
public class LightVolume implements Box {
|
||||
|
||||
protected final BlockAndTintGetter level;
|
||||
protected final MutableBox box = new MutableBox();
|
||||
protected MemoryBlock lightData;
|
||||
|
@ -68,7 +67,7 @@ public class LightVolume implements Box {
|
|||
|
||||
public short getPackedLight(int x, int y, int z) {
|
||||
if (box.contains(x, y, z)) {
|
||||
return MemoryUtil.memGetShort(worldPosToPtr(x, y, z));
|
||||
return MemoryUtil.memGetShort(levelPosToPtr(x, y, z));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -106,18 +105,18 @@ public class LightVolume implements Box {
|
|||
}
|
||||
|
||||
/**
|
||||
* Copy all light from the world into this volume.
|
||||
* Copy all light from the level into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
* @param levelVolume the region in the level to copy data from.
|
||||
*/
|
||||
public void copyLight(Box worldVolume) {
|
||||
public void copyLight(Box levelVolume) {
|
||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
levelVolume.forEachContained((x, y, z) -> {
|
||||
pos.set(x, y, z);
|
||||
|
||||
int block = this.level.getBrightness(LightLayer.BLOCK, pos);
|
||||
|
@ -137,18 +136,18 @@ public class LightVolume implements Box {
|
|||
}
|
||||
|
||||
/**
|
||||
* Copy block light from the world into this volume.
|
||||
* Copy block light from the level into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
* @param levelVolume the region in the level to copy data from.
|
||||
*/
|
||||
public void copyBlock(Box worldVolume) {
|
||||
public void copyBlock(Box levelVolume) {
|
||||
var pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
levelVolume.forEachContained((x, y, z) -> {
|
||||
int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z));
|
||||
|
||||
writeBlock(x - xShift, y - yShift, z - zShift, light);
|
||||
|
@ -162,18 +161,18 @@ public class LightVolume implements Box {
|
|||
}
|
||||
|
||||
/**
|
||||
* Copy sky light from the world into this volume.
|
||||
* Copy sky light from the level into this volume.
|
||||
*
|
||||
* @param worldVolume the region in the world to copy data from.
|
||||
* @param levelVolume the region in the level to copy data from.
|
||||
*/
|
||||
public void copySky(Box worldVolume) {
|
||||
public void copySky(Box levelVolume) {
|
||||
var pos = new BlockPos.MutableBlockPos();
|
||||
|
||||
int xShift = box.getMinX();
|
||||
int yShift = box.getMinY();
|
||||
int zShift = box.getMinZ();
|
||||
|
||||
worldVolume.forEachContained((x, y, z) -> {
|
||||
levelVolume.forEachContained((x, y, z) -> {
|
||||
int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z));
|
||||
|
||||
writeSky(x - xShift, y - yShift, z - zShift, light);
|
||||
|
@ -186,15 +185,15 @@ public class LightVolume implements Box {
|
|||
MemoryUtil.memPutByte(boxPosToPtr(x, y, z) + 1, s);
|
||||
}
|
||||
|
||||
protected long worldPosToPtr(int x, int y, int z) {
|
||||
return lightData.ptr() + worldPosToPtrOffset(x, y, z);
|
||||
protected long levelPosToPtr(int x, int y, int z) {
|
||||
return lightData.ptr() + levelPosToPtrOffset(x, y, z);
|
||||
}
|
||||
|
||||
protected long boxPosToPtr(int x, int y, int z) {
|
||||
return lightData.ptr() + boxPosToPtrOffset(x, y, z);
|
||||
}
|
||||
|
||||
protected int worldPosToPtrOffset(int x, int y, int z) {
|
||||
protected int levelPosToPtrOffset(int x, int y, int z) {
|
||||
x -= box.getMinX();
|
||||
y -= box.getMinY();
|
||||
z -= box.getMinZ();
|
||||
|
@ -216,5 +215,4 @@ public class LightVolume implements Box {
|
|||
else if (type == LightLayer.SKY) copySky(vol);
|
||||
markDirty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ public final class Models {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a usable model for a given blockstate.
|
||||
* Get a usable model for a given block state.
|
||||
*
|
||||
* @param state The blockstate you wish to render.
|
||||
* @return A model corresponding to how the given blockstate would appear in the world.
|
||||
* @param state The block state you wish to render.
|
||||
* @return A model corresponding to how the given block state would appear in the level.
|
||||
*/
|
||||
public static Model block(BlockState state) {
|
||||
return BLOCK_STATE.get(state);
|
||||
|
|
|
@ -33,7 +33,7 @@ final class BakedModelBufferer {
|
|||
private BakedModelBufferer() {
|
||||
}
|
||||
|
||||
public static void bufferSingle(ModelBlockRenderer blockRenderer, BlockAndTintGetter renderWorld, BakedModel model, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
|
||||
public static void bufferSingle(ModelBlockRenderer blockRenderer, BlockAndTintGetter level, BakedModel model, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
|
||||
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
|
||||
if (poseStack == null) {
|
||||
poseStack = objects.identityPoseStack;
|
||||
|
@ -41,7 +41,7 @@ final class BakedModelBufferer {
|
|||
RandomSource random = objects.random;
|
||||
var consumers = objects.emitters;
|
||||
|
||||
modelData = model.getModelData(renderWorld, BlockPos.ZERO, state, modelData);
|
||||
modelData = model.getModelData(level, BlockPos.ZERO, state, modelData);
|
||||
random.setSeed(42L);
|
||||
ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData);
|
||||
|
||||
|
@ -52,22 +52,22 @@ final class BakedModelBufferer {
|
|||
consumer.begin(resultConsumer);
|
||||
|
||||
poseStack.pushPose();
|
||||
blockRenderer.tesselateBlock(renderWorld, model, state, BlockPos.ZERO, poseStack, consumer, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, renderType);
|
||||
blockRenderer.tesselateBlock(level, model, state, BlockPos.ZERO, poseStack, consumer, false, random, 42L, OverlayTexture.NO_OVERLAY, modelData, renderType);
|
||||
poseStack.popPose();
|
||||
|
||||
consumer.end();
|
||||
}
|
||||
}
|
||||
|
||||
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, BlockAndTintGetter renderWorld, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
|
||||
public static void bufferBlock(BlockRenderDispatcher renderDispatcher, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, ModelData modelData, ResultConsumer resultConsumer) {
|
||||
if (state.getRenderShape() != RenderShape.MODEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
bufferSingle(renderDispatcher.getModelRenderer(), renderWorld, renderDispatcher.getBlockModel(state), state, poseStack, modelData, resultConsumer);
|
||||
bufferSingle(renderDispatcher.getModelRenderer(), level, renderDispatcher.getBlockModel(state), state, poseStack, modelData, resultConsumer);
|
||||
}
|
||||
|
||||
public static void bufferMultiBlock(BlockRenderDispatcher renderDispatcher, Iterator<BlockPos> posIterator, BlockAndTintGetter renderWorld, @Nullable PoseStack poseStack, Function<BlockPos, ModelData> modelDataLookup, boolean renderFluids, ResultConsumer resultConsumer) {
|
||||
public static void bufferMultiBlock(BlockRenderDispatcher renderDispatcher, Iterator<BlockPos> posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, Function<BlockPos, ModelData> modelDataLookup, boolean renderFluids, ResultConsumer resultConsumer) {
|
||||
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
|
||||
if (poseStack == null) {
|
||||
poseStack = objects.identityPoseStack;
|
||||
|
@ -86,7 +86,7 @@ final class BakedModelBufferer {
|
|||
|
||||
while (posIterator.hasNext()) {
|
||||
BlockPos pos = posIterator.next();
|
||||
BlockState state = renderWorld.getBlockState(pos);
|
||||
BlockState state = level.getBlockState(pos);
|
||||
|
||||
if (renderFluids) {
|
||||
FluidState fluidState = state.getFluidState();
|
||||
|
@ -99,7 +99,7 @@ final class BakedModelBufferer {
|
|||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF));
|
||||
renderDispatcher.renderLiquid(pos, renderWorld, transformingWrapper, state, fluidState);
|
||||
renderDispatcher.renderLiquid(pos, level, transformingWrapper, state, fluidState);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ final class BakedModelBufferer {
|
|||
long seed = state.getSeed(pos);
|
||||
BakedModel model = renderDispatcher.getBlockModel(state);
|
||||
ModelData modelData = modelDataLookup.apply(pos);
|
||||
modelData = model.getModelData(renderWorld, pos, state, modelData);
|
||||
modelData = model.getModelData(level, pos, state, modelData);
|
||||
random.setSeed(seed);
|
||||
ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData);
|
||||
|
||||
|
@ -117,7 +117,7 @@ final class BakedModelBufferer {
|
|||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
|
||||
blockRenderer.tesselateBlock(renderWorld, model, state, pos, poseStack, emitters[layerIndex], true, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType);
|
||||
blockRenderer.tesselateBlock(level, model, state, pos, poseStack, emitters[layerIndex], true, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import net.minecraftforge.client.model.data.ModelData;
|
|||
public class BakedModelBuilder {
|
||||
private final BakedModel bakedModel;
|
||||
@Nullable
|
||||
private BlockAndTintGetter renderWorld;
|
||||
private BlockAndTintGetter level;
|
||||
@Nullable
|
||||
private BlockState blockState;
|
||||
@Nullable
|
||||
|
@ -40,8 +40,8 @@ public class BakedModelBuilder {
|
|||
this.bakedModel = bakedModel;
|
||||
}
|
||||
|
||||
public BakedModelBuilder renderWorld(BlockAndTintGetter renderWorld) {
|
||||
this.renderWorld = renderWorld;
|
||||
public BakedModelBuilder level(BlockAndTintGetter level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,8 @@ public class BakedModelBuilder {
|
|||
}
|
||||
|
||||
public SimpleModel build() {
|
||||
if (renderWorld == null) {
|
||||
renderWorld = VirtualEmptyBlockGetter.INSTANCE;
|
||||
if (level == null) {
|
||||
level = VirtualEmptyBlockGetter.INSTANCE;
|
||||
}
|
||||
if (blockState == null) {
|
||||
blockState = Blocks.AIR.defaultBlockState();
|
||||
|
@ -90,7 +90,7 @@ public class BakedModelBuilder {
|
|||
out.add(new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
};
|
||||
BakedModelBufferer.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, modelData, resultConsumer);
|
||||
BakedModelBufferer.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), level, bakedModel, blockState, poseStack, modelData, resultConsumer);
|
||||
|
||||
return new SimpleModel(out.build());
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import net.minecraftforge.client.model.data.ModelData;
|
|||
public class BlockModelBuilder {
|
||||
private final BlockState state;
|
||||
@Nullable
|
||||
private BlockAndTintGetter renderWorld;
|
||||
private BlockAndTintGetter level;
|
||||
@Nullable
|
||||
private PoseStack poseStack;
|
||||
@Nullable
|
||||
|
@ -36,8 +36,8 @@ public class BlockModelBuilder {
|
|||
this.state = state;
|
||||
}
|
||||
|
||||
public BlockModelBuilder renderWorld(BlockAndTintGetter renderWorld) {
|
||||
this.renderWorld = renderWorld;
|
||||
public BlockModelBuilder level(BlockAndTintGetter level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -57,8 +57,8 @@ public class BlockModelBuilder {
|
|||
}
|
||||
|
||||
public SimpleModel build() {
|
||||
if (renderWorld == null) {
|
||||
renderWorld = VirtualEmptyBlockGetter.INSTANCE;
|
||||
if (level == null) {
|
||||
level = VirtualEmptyBlockGetter.INSTANCE;
|
||||
}
|
||||
if (modelData == null) {
|
||||
modelData = ModelData.EMPTY;
|
||||
|
@ -78,7 +78,7 @@ public class BlockModelBuilder {
|
|||
out.add(new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
};
|
||||
BakedModelBufferer.bufferBlock(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, modelData, resultConsumer);
|
||||
BakedModelBufferer.bufferBlock(ModelUtil.VANILLA_RENDERER, level, state, poseStack, modelData, resultConsumer);
|
||||
|
||||
return new SimpleModel(out.build());
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import net.minecraft.world.level.BlockAndTintGetter;
|
|||
import net.minecraftforge.client.model.data.ModelData;
|
||||
|
||||
public class MultiBlockModelBuilder {
|
||||
private final BlockAndTintGetter renderWorld;
|
||||
private final BlockAndTintGetter level;
|
||||
private final Iterable<BlockPos> positions;
|
||||
@Nullable
|
||||
private PoseStack poseStack;
|
||||
|
@ -33,8 +33,8 @@ public class MultiBlockModelBuilder {
|
|||
@Nullable
|
||||
private BiFunction<RenderType, Boolean, Material> materialFunc;
|
||||
|
||||
public MultiBlockModelBuilder(BlockAndTintGetter renderWorld, Iterable<BlockPos> positions) {
|
||||
this.renderWorld = renderWorld;
|
||||
public MultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||
this.level = level;
|
||||
this.positions = positions;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public class MultiBlockModelBuilder {
|
|||
out.add(new Model.ConfiguredMesh(material, mesh));
|
||||
}
|
||||
};
|
||||
BakedModelBufferer.bufferMultiBlock(ModelUtil.VANILLA_RENDERER, positions.iterator(), renderWorld, poseStack, modelDataLookup, renderFluids, resultConsumer);
|
||||
BakedModelBufferer.bufferMultiBlock(ModelUtil.VANILLA_RENDERER, positions.iterator(), level, poseStack, modelDataLookup, renderFluids, resultConsumer);
|
||||
|
||||
return new SimpleModel(out.build());
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public abstract class AbstractBlockEntityVisual<T extends BlockEntity> extends A
|
|||
/**
|
||||
* In order to accommodate for floating point precision errors at high coordinates,
|
||||
* {@link VisualManager}s are allowed to arbitrarily adjust the origin, and
|
||||
* shift the world matrix provided as a shader uniform accordingly.
|
||||
* shift the level matrix provided as a shader uniform accordingly.
|
||||
*
|
||||
* @return The {@link BlockPos position} of the {@link BlockEntity} this visual
|
||||
* represents should be rendered at to appear in the correct location.
|
||||
|
|
|
@ -43,7 +43,7 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate the distance squared between this visual and the given <em>world</em> position.
|
||||
* Calculate the distance squared between this visual and the given <em>level</em> position.
|
||||
*
|
||||
* @param x The x coordinate.
|
||||
* @param y The y coordinate.
|
||||
|
@ -57,7 +57,7 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
|||
/**
|
||||
* In order to accommodate for floating point precision errors at high coordinates,
|
||||
* {@link VisualizationManager}s are allowed to arbitrarily adjust the origin, and
|
||||
* shift the world matrix provided as a shader uniform accordingly.
|
||||
* shift the level matrix provided as a shader uniform accordingly.
|
||||
*
|
||||
* @return The position this visual should be rendered at to appear in the correct location.
|
||||
*/
|
||||
|
@ -71,7 +71,7 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
|||
/**
|
||||
* In order to accommodate for floating point precision errors at high coordinates,
|
||||
* {@link VisualizationManager}s are allowed to arbitrarily adjust the origin, and
|
||||
* shift the world matrix provided as a shader uniform accordingly.
|
||||
* shift the level matrix provided as a shader uniform accordingly.
|
||||
*
|
||||
* @return The position this visual should be rendered at to appear in the correct location.
|
||||
*/
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
struct FrustumPlanes {
|
||||
vec4 xyX;// <nx.x, px.x, ny.x, py.x>
|
||||
vec4 xyY;// <nx.y, px.y, ny.y, py.y>
|
||||
vec4 xyZ;// <nx.z, px.z, ny.z, py.z>
|
||||
vec4 xyW;// <nx.w, px.w, ny.w, py.w>
|
||||
vec2 zX;// <nz.x, pz.x>
|
||||
vec2 zY;// <nz.y, pz.y>
|
||||
vec2 zZ;// <nz.z, pz.z>
|
||||
vec2 zW;// <nz.w, pz.w>
|
||||
vec4 xyX; // <nx.x, px.x, ny.x, py.x>
|
||||
vec4 xyY; // <nx.y, px.y, ny.y, py.y>
|
||||
vec4 xyZ; // <nx.z, px.z, ny.z, py.z>
|
||||
vec4 xyW; // <nx.w, px.w, ny.w, py.w>
|
||||
vec2 zX; // <nz.x, pz.x>
|
||||
vec2 zY; // <nz.y, pz.y>
|
||||
vec2 zZ; // <nz.z, pz.z>
|
||||
vec2 zW; // <nz.w, pz.w>
|
||||
};
|
||||
|
||||
layout(std140) uniform _FlwFrameUniforms {
|
||||
|
@ -30,13 +30,12 @@ layout(std140) uniform _FlwFrameUniforms {
|
|||
vec2 flw_cameraRotPrev;
|
||||
|
||||
vec2 flw_viewportSize;
|
||||
float flw_defaultLineWidth;
|
||||
float flw_aspectRatio;
|
||||
float flw_defaultLineWidth;
|
||||
float flw_viewDistance;
|
||||
|
||||
uint flw_ticks;
|
||||
float flw_partialTick;
|
||||
|
||||
float flw_renderTicks;
|
||||
float flw_renderSeconds;
|
||||
|
||||
|
|
Loading…
Reference in a new issue