From 1e9e4e005466aa7f2be92814c23e228dc15b17d5 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Fri, 24 Dec 2021 23:26:18 -0800 Subject: [PATCH 1/5] Clean up - Use Flywheel.rl and Flywheel.ID where ever possible - Rename Flywheel.log to LOGGER - Don't add namespace to network channel version - Use counter for packet IDs --- src/main/java/com/jozufozu/flywheel/Flywheel.java | 6 +++--- .../java/com/jozufozu/flywheel/FlywheelClient.java | 2 +- .../jozufozu/flywheel/backend/gl/error/GlError.java | 2 +- .../backend/instancing/ParallelTaskEngine.java | 2 +- .../backend/instancing/instancing/GPUInstancer.java | 6 +++--- .../com/jozufozu/flywheel/backend/model/ModelPool.java | 4 ++-- .../com/jozufozu/flywheel/backend/model/VBOModel.java | 2 +- .../java/com/jozufozu/flywheel/config/FlwPackets.java | 10 ++++++---- src/main/java/com/jozufozu/flywheel/core/Contexts.java | 4 ++-- .../com/jozufozu/flywheel/core/FullscreenQuad.java | 2 +- .../java/com/jozufozu/flywheel/core/Materials.java | 5 +++-- src/main/java/com/jozufozu/flywheel/core/Programs.java | 4 ++-- .../core/shader/extension/UnitExtensionInstance.java | 2 +- .../flywheel/core/shader/extension/WorldFog.java | 6 +++--- .../shader/gamestate/NormalDebugStateProvider.java | 2 +- 15 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index aeb110dc4..6214f67f5 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -18,11 +18,11 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -@Mod("flywheel") +@Mod(Flywheel.ID) public class Flywheel { public static final String ID = "flywheel"; - public static final Logger log = LogManager.getLogger(Flywheel.class); + public static final Logger LOGGER = LogManager.getLogger(Flywheel.class); public Flywheel() { FMLJavaModLoadingContext.get() @@ -42,6 +42,6 @@ public class Flywheel { private void setup(final FMLCommonSetupEvent event) { FlwPackets.registerPackets(); - ArgumentTypes.register("flywheel:engine", EngineArgument.class, new EmptyArgumentSerializer<>(EngineArgument::getInstance)); + ArgumentTypes.register(rl("engine").toString(), EngineArgument.class, new EmptyArgumentSerializer<>(EngineArgument::getInstance)); } } diff --git a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java index dc0e7b4e4..3ec94f352 100644 --- a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java +++ b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java @@ -33,6 +33,6 @@ public class FlywheelClient { // Only thing I've seen that's close to a fix is to force the class to load before trying to use it. // From the SpongePowered discord: // https://discord.com/channels/142425412096491520/626802111455297538/675007581168599041 - Flywheel.log.info("Successfully loaded {}", PausedPartialTickAccessor.class.getName()); + Flywheel.LOGGER.info("Successfully loaded {}", PausedPartialTickAccessor.class.getName()); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/error/GlError.java b/src/main/java/com/jozufozu/flywheel/backend/gl/error/GlError.java index 115ca765d..41b9ddf46 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/error/GlError.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/error/GlError.java @@ -44,7 +44,7 @@ public enum GlError { // TODO: build flag? to enable or disable this function GlError err = GlError.poll(); if (err != null) { - Flywheel.log.error("{}: {}", err.name(), context.get()); + Flywheel.LOGGER.error("{}: {}", err.name(), context.get()); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java index 937567853..316bed471 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java @@ -139,7 +139,7 @@ public class ParallelTaskEngine implements TaskEngine { try { job.run(); } catch (Exception e) { - Flywheel.log.error(e); + Flywheel.LOGGER.error(e); } finally { ParallelTaskEngine.this.wg.done(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index ae9cb845d..1c7f0eb74 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -137,7 +137,7 @@ public class GPUInstancer extends AbstractInstancer { try (MappedBuffer buf = instanceVBO.getBuffer(offset, length)) { MemoryUtil.memSet(MemoryUtil.memAddress(buf.unwrap()), 0, length); } catch (Exception e) { - Flywheel.log.error("Error clearing buffer tail:", e); + Flywheel.LOGGER.error("Error clearing buffer tail:", e); } } } @@ -159,7 +159,7 @@ public class GPUInstancer extends AbstractInstancer { } } } catch (Exception e) { - Flywheel.log.error("Error updating GPUInstancer:", e); + Flywheel.LOGGER.error("Error updating GPUInstancer:", e); } } @@ -175,7 +175,7 @@ public class GPUInstancer extends AbstractInstancer { writer.write(datum); } } catch (Exception e) { - Flywheel.log.error("Error reallocating GPUInstancer:", e); + Flywheel.LOGGER.error("Error reallocating GPUInstancer:", e); } glInstanceCount = size; diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java index feb5815ab..4561577bf 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java @@ -121,7 +121,7 @@ public class ModelPool implements ModelAllocator { } } catch (Exception e) { - Flywheel.log.error("Error uploading pooled models:", e); + Flywheel.LOGGER.error("Error uploading pooled models:", e); } } @@ -133,7 +133,7 @@ public class ModelPool implements ModelAllocator { } pendingUpload.clear(); } catch (Exception e) { - Flywheel.log.error("Error uploading pooled models:", e); + Flywheel.LOGGER.error("Error uploading pooled models:", e); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java index 06c8d1066..dcc26d234 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java @@ -35,7 +35,7 @@ public class VBOModel implements BufferedModel { try (MappedBuffer buffer = vbo.getBuffer()) { model.writeInto(buffer.unwrap()); } catch (Exception e) { - Flywheel.log.error(String.format("Error uploading model '%s':", model.name()), e); + Flywheel.LOGGER.error(String.format("Error uploading model '%s':", model.name()), e); } vbo.unbind(); diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwPackets.java b/src/main/java/com/jozufozu/flywheel/config/FlwPackets.java index eb968aa52..c3fa59234 100644 --- a/src/main/java/com/jozufozu/flywheel/config/FlwPackets.java +++ b/src/main/java/com/jozufozu/flywheel/config/FlwPackets.java @@ -8,8 +8,8 @@ import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.simple.SimpleChannel; public class FlwPackets { - public static final ResourceLocation CHANNEL_NAME = new ResourceLocation(Flywheel.ID, "network"); - public static final String NETWORK_VERSION = new ResourceLocation(Flywheel.ID, "1").toString(); + public static final ResourceLocation CHANNEL_NAME = Flywheel.rl("main"); + public static final String NETWORK_VERSION = String.valueOf(1); public static SimpleChannel channel; public static void registerPackets() { @@ -19,13 +19,15 @@ public class FlwPackets { .networkProtocolVersion(() -> NETWORK_VERSION) .simpleChannel(); - channel.messageBuilder(SConfigureBooleanPacket.class, 0, NetworkDirection.PLAY_TO_CLIENT) + int id = 0; + + channel.messageBuilder(SConfigureBooleanPacket.class, id++, NetworkDirection.PLAY_TO_CLIENT) .decoder(SConfigureBooleanPacket::new) .encoder(SConfigureBooleanPacket::encode) .consumer(SConfigureBooleanPacket::execute) .add(); - channel.messageBuilder(SConfigureEnginePacket.class, 1, NetworkDirection.PLAY_TO_CLIENT) + channel.messageBuilder(SConfigureEnginePacket.class, id++, NetworkDirection.PLAY_TO_CLIENT) .decoder(SConfigureEnginePacket::new) .encoder(SConfigureEnginePacket::encode) .consumer(SConfigureEnginePacket::execute) diff --git a/src/main/java/com/jozufozu/flywheel/core/Contexts.java b/src/main/java/com/jozufozu/flywheel/core/Contexts.java index 5c702124a..744ef5ae6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Contexts.java +++ b/src/main/java/com/jozufozu/flywheel/core/Contexts.java @@ -40,7 +40,7 @@ public class Contexts { } public static class Names { - public static final ResourceLocation CRUMBLING = new ResourceLocation(Flywheel.ID, "context/crumbling"); - public static final ResourceLocation WORLD = new ResourceLocation(Flywheel.ID, "context/world"); + public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling"); + public static final ResourceLocation WORLD = Flywheel.rl("context/world"); } } diff --git a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java index d319a2656..fbabefe94 100644 --- a/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java +++ b/src/main/java/com/jozufozu/flywheel/core/FullscreenQuad.java @@ -36,7 +36,7 @@ public class FullscreenQuad { try (MappedBuffer buffer = vbo.getBuffer()) { buffer.putFloatArray(vertices); } catch (Exception e) { - Flywheel.log.error("Could not create fullscreen quad.", e); + Flywheel.LOGGER.error("Could not create fullscreen quad.", e); } vao = new GlVertexArray(); diff --git a/src/main/java/com/jozufozu/flywheel/core/Materials.java b/src/main/java/com/jozufozu/flywheel/core/Materials.java index 3de4d5f1b..f5470dc83 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Materials.java +++ b/src/main/java/com/jozufozu/flywheel/core/Materials.java @@ -1,5 +1,6 @@ package com.jozufozu.flywheel.core; +import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.core.materials.model.ModelData; @@ -25,7 +26,7 @@ public class Materials { } public static class Names { - public static final ResourceLocation MODEL = new ResourceLocation("create", "model"); - public static final ResourceLocation ORIENTED = new ResourceLocation("create", "oriented"); + public static final ResourceLocation MODEL = Flywheel.rl("model"); + public static final ResourceLocation ORIENTED = Flywheel.rl("oriented"); } } diff --git a/src/main/java/com/jozufozu/flywheel/core/Programs.java b/src/main/java/com/jozufozu/flywheel/core/Programs.java index 5ed04b767..8a00ca79b 100644 --- a/src/main/java/com/jozufozu/flywheel/core/Programs.java +++ b/src/main/java/com/jozufozu/flywheel/core/Programs.java @@ -5,6 +5,6 @@ import com.jozufozu.flywheel.Flywheel; import net.minecraft.resources.ResourceLocation; public class Programs { - public static final ResourceLocation TRANSFORMED = new ResourceLocation(Flywheel.ID, "model"); - public static final ResourceLocation ORIENTED = new ResourceLocation(Flywheel.ID, "oriented"); + public static final ResourceLocation TRANSFORMED = Flywheel.rl("model"); + public static final ResourceLocation ORIENTED = Flywheel.rl("oriented"); } diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java b/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java index 7b5773aa2..ac3dcc36e 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/extension/UnitExtensionInstance.java @@ -7,7 +7,7 @@ import net.minecraft.resources.ResourceLocation; public class UnitExtensionInstance implements IExtensionInstance { - public static final ResourceLocation NAME = new ResourceLocation(Flywheel.ID, "unit"); + public static final ResourceLocation NAME = Flywheel.rl("unit"); public UnitExtensionInstance(GlProgram program) { } diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java b/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java index 0aba10b1e..b76c370eb 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/extension/WorldFog.java @@ -10,7 +10,7 @@ import net.minecraft.resources.ResourceLocation; public class WorldFog implements IExtensionInstance { - public static final ResourceLocation NAME = new ResourceLocation(Flywheel.ID, "fog"); + public static final ResourceLocation NAME = Flywheel.rl("fog"); private final int uFogColor; private final int uFogRange; @@ -28,6 +28,6 @@ public class WorldFog implements IExtensionInstance { @Override public ResourceLocation name() { - return NAME; - } + return NAME; + } } diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/NormalDebugStateProvider.java b/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/NormalDebugStateProvider.java index a1efdbf5f..f7ddbbea0 100644 --- a/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/NormalDebugStateProvider.java +++ b/src/main/java/com/jozufozu/flywheel/core/shader/gamestate/NormalDebugStateProvider.java @@ -9,7 +9,7 @@ import net.minecraft.resources.ResourceLocation; public class NormalDebugStateProvider implements IBooleanStateProvider { public static final NormalDebugStateProvider INSTANCE = new NormalDebugStateProvider(); - public static final ResourceLocation NAME = new ResourceLocation(Flywheel.ID, "normal_debug"); + public static final ResourceLocation NAME = Flywheel.rl("normal_debug"); protected NormalDebugStateProvider() { From c15399512104ff1a798022eae80b305b994ab861 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sat, 25 Dec 2021 01:01:47 -0800 Subject: [PATCH 2/5] No more diffuse divide - Move PlacementSimulationWorld to Flywheel as VirtualRenderWorld - Simplify ModelTransformer - Model doesn't need #configure --- build.gradle | 2 +- .../batching/BatchedMaterialGroup.java | 8 +- .../instancing/batching/CPUInstancer.java | 11 - .../flywheel/core/model/BlockModel.java | 7 +- .../jozufozu/flywheel/core/model/Model.java | 8 +- .../flywheel/core/model/ModelTransformer.java | 42 +-- .../flywheel/core/model/ModelUtil.java | 12 +- .../flywheel/core/model/WorldModel.java | 5 +- .../flywheel/core/virtual/VirtualChunk.java | 240 ++++++++++++++++ .../core/virtual/VirtualChunkSection.java | 39 +++ .../core/virtual/VirtualChunkSource.java | 65 +++++ .../virtual}/VirtualEmptyBlockGetter.java | 4 +- .../virtual}/VirtualEmptyModelData.java | 2 +- .../virtual/VirtualLevelEntityGetter.java | 41 +++ .../core/virtual/VirtualRenderWorld.java | 265 ++++++++++++++++++ .../flywheel/core/virtual/package-info.java | 6 + .../flywheel/flywheel/shaders/block.frag | 6 - 17 files changed, 679 insertions(+), 84 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java rename src/main/java/com/jozufozu/flywheel/{util => core/virtual}/VirtualEmptyBlockGetter.java (97%) rename src/main/java/com/jozufozu/flywheel/{util => core/virtual}/VirtualEmptyModelData.java (94%) create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java create mode 100644 src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java diff --git a/build.gradle b/build.gradle index a45bf118b..759b5e7f0 100644 --- a/build.gradle +++ b/build.gradle @@ -17,10 +17,10 @@ plugins { } apply plugin: 'net.minecraftforge.gradle' +apply plugin: 'org.parchmentmc.librarian.forgegradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' apply plugin: 'org.spongepowered.mixin' -apply plugin: 'org.parchmentmc.librarian.forgegradle' boolean dev = System.getenv('RELEASE') == null || System.getenv('RELEASE').equalsIgnoreCase('false'); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java index cbeaf7c60..890dce0e1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchedMaterialGroup.java @@ -51,13 +51,7 @@ public class BatchedMaterialGroup implements MaterialGroup { for (BatchedMaterial material : materials.values()) { for (CPUInstancer instancer : material.models.values()) { - if (consumer.hasOverlay()) { - instancer.sbb.context.fullNormalTransform = false; - instancer.sbb.context.outputColorDiffuse = false; - } else { - instancer.sbb.context.fullNormalTransform = false; - instancer.sbb.context.outputColorDiffuse = true; - } + instancer.sbb.context.outputColorDiffuse = !consumer.hasOverlay(); instancer.submitTasks(stack, pool, consumer); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java index 1486ef14e..d16f4a4d2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java @@ -7,7 +7,6 @@ import com.jozufozu.flywheel.backend.instancing.TaskEngine; import com.jozufozu.flywheel.backend.model.DirectVertexConsumer; import com.jozufozu.flywheel.core.model.Model; import com.jozufozu.flywheel.core.model.ModelTransformer; -import com.jozufozu.flywheel.util.Color; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -22,7 +21,6 @@ public class CPUInstancer extends AbstractInstancer { batchingType = type; sbb = new ModelTransformer(modelData); - modelData.configure(sbb.context); } void submitTasks(PoseStack stack, TaskEngine pool, DirectVertexConsumer consumer) { @@ -44,15 +42,11 @@ public class CPUInstancer extends AbstractInstancer { private void drawRange(PoseStack stack, VertexConsumer buffer, int from, int to) { ModelTransformer.Params params = new ModelTransformer.Params(); - // Color color = Color.generateFromLong(from); - for (D d : data.subList(from, to)) { params.loadDefault(); batchingType.transform(d, params); - //params.color(color.getRGB()); - sbb.renderInto(params, stack, buffer); } } @@ -73,11 +67,6 @@ public class CPUInstancer extends AbstractInstancer { data.removeIf(InstanceData::isRemoved); anyToRemove = false; } - - if (false) { - this.sbb.context.outputColorDiffuse = false; - this.sbb.context.fullNormalTransform = false; - } } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java index bfb01f00b..8c527bea6 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/BlockModel.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.core.model; -import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.core.Formats; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; @@ -33,11 +33,6 @@ public class BlockModel implements Model { name = referenceState.toString(); } - @Override - public void configure(ModelTransformer.Context ctx) { - ctx.inputHasDiffuse = true; - } - @Override public String name() { return name; diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Model.java b/src/main/java/com/jozufozu/flywheel/core/model/Model.java index e505ba74b..6d1c2c0c5 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Model.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Model.java @@ -2,11 +2,11 @@ package com.jozufozu.flywheel.core.model; import java.nio.ByteBuffer; +import com.jozufozu.flywheel.api.vertex.VertexList; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.model.ElementBuffer; import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.core.QuadConverter; -import com.jozufozu.flywheel.api.vertex.VertexList; -import com.jozufozu.flywheel.api.vertex.VertexType; /** * A model that can be rendered by flywheel. @@ -42,10 +42,6 @@ public interface Model { */ int vertexCount(); - default void configure(ModelTransformer.Context ctx) { - - } - default VertexType getType() { return Formats.POS_TEX_NORMAL; } diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java index fc2223da5..d856b5020 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelTransformer.java @@ -5,7 +5,11 @@ import com.jozufozu.flywheel.util.RenderMath; import com.jozufozu.flywheel.util.transform.Transform; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.*; +import com.mojang.math.Matrix3f; +import com.mojang.math.Matrix4f; +import com.mojang.math.Quaternion; +import com.mojang.math.Vector3f; +import com.mojang.math.Vector4f; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.OverlayTexture; @@ -75,34 +79,11 @@ public class ModelTransformer { builder.color(params.r, params.g, params.b, params.a); } } else { - if (context.inputHasDiffuse) { - int r = Byte.toUnsignedInt(reader.getR(i)); - int g = Byte.toUnsignedInt(reader.getG(i)); - int b = Byte.toUnsignedInt(reader.getB(i)); - int a = Byte.toUnsignedInt(reader.getA(i)); - - float undoStaticDiffuse = 1 / LightUtil.diffuseLight(normalX, normalY, normalZ); - float diffuse; - if (context.outputColorDiffuse) { - diffuse = LightUtil.diffuseLight(nx, ny, nz) * undoStaticDiffuse; - } else { - diffuse = undoStaticDiffuse; - } - - if (diffuse != 1) { - r = transformColor(r, diffuse); - g = transformColor(g, diffuse); - b = transformColor(b, diffuse); - } - - builder.color(r, g, b, a); + if (context.outputColorDiffuse) { + int d = RenderMath.unb(LightUtil.diffuseLight(nx, ny, nz)); + builder.color(d, d, d, 0xFF); } else { - if (context.outputColorDiffuse) { - int d = RenderMath.unb(LightUtil.diffuseLight(nx, ny, nz)); - builder.color(d, d, d, 0xFF); - } else { - builder.color(reader.getR(i), reader.getG(i), reader.getB(i), reader.getA(i)); - } + builder.color(reader.getR(i), reader.getG(i), reader.getB(i), reader.getA(i)); } } @@ -152,11 +133,6 @@ public class ModelTransformer { */ public boolean fullNormalTransform = false; - /** - * Does the model we're transforming have diffuse light baked into its colors? - */ - public boolean inputHasDiffuse = false; - /** * Do we need to bake diffuse lighting into the output colors? */ diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java index 921b1f4df..a34d1f4d8 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -5,9 +5,9 @@ import java.util.Collection; import java.util.Random; import java.util.function.Supplier; +import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter; +import com.jozufozu.flywheel.core.virtual.VirtualEmptyModelData; import com.jozufozu.flywheel.util.Lazy; -import com.jozufozu.flywheel.util.VirtualEmptyBlockGetter; -import com.jozufozu.flywheel.util.VirtualEmptyModelData; import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; @@ -45,14 +45,6 @@ public class ModelUtil { public static BufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack ms) { ModelBlockRenderer blockRenderer = Minecraft.getInstance().getBlockRenderer().getModelRenderer(); BufferBuilder builder = new BufferBuilder(512); - - // BakedQuadWrapper quadReader = new BakedQuadWrapper(); - // - // IModelData modelData = model.getModelData(VirtualEmptyBlockGetter.INSTANCE, BlockPos.ZERO, referenceState, VirtualEmptyModelData.INSTANCE); - // List quads = Arrays.stream(CULL_FACES) - // .flatMap(dir -> model.getQuads(referenceState, dir, new Random(), modelData).stream()) - // .collect(Collectors.toList()); - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK); blockRenderer.tesselateBlock(VirtualEmptyBlockGetter.INSTANCE, model, referenceState, BlockPos.ZERO, ms, builder, false, new Random(), 42, OverlayTexture.NO_OVERLAY, VirtualEmptyModelData.INSTANCE); diff --git a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java index b910de2a6..b3e96aa7d 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/WorldModel.java @@ -2,9 +2,9 @@ package com.jozufozu.flywheel.core.model; import java.util.Collection; -import com.jozufozu.flywheel.core.Formats; import com.jozufozu.flywheel.api.vertex.VertexList; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.core.Formats; import net.minecraft.client.renderer.RenderType; import net.minecraft.world.level.BlockAndTintGetter; @@ -15,6 +15,9 @@ public class WorldModel implements Model { private final VertexList reader; private final String name; + /** + * It is expected that renderWorld.getShade(...) returns a constant. + */ public WorldModel(BlockAndTintGetter renderWorld, RenderType layer, Collection blocks, String name) { reader = Formats.BLOCK.createReader(ModelUtil.getBufferBuilderFromTemplate(renderWorld, layer, blocks)); this.name = name; diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java new file mode 100644 index 000000000..925d7516a --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java @@ -0,0 +1,240 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import javax.annotation.Nullable; + +import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.shorts.ShortList; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.structure.StructureStart; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.ticks.BlackholeTickAccess; +import net.minecraft.world.ticks.TickContainerAccess; + +public class VirtualChunk extends ChunkAccess { + + final VirtualRenderWorld world; + boolean needsLight; + final int x; + final int z; + + private final LevelChunkSection[] sections; + + public VirtualChunk(VirtualRenderWorld world, int x, int z) { + super(new ChunkPos(x, z), UpgradeData.EMPTY, world, world.registryAccess() + .registry(Registry.BIOME_REGISTRY) + .orElseThrow(), 0L, null, null); + + this.world = world; + this.needsLight = true; + this.x = x; + this.z = z; + + this.sections = new LevelChunkSection[16]; + + for (int i = 0; i < 16; i++) { + sections[i] = new VirtualChunkSection(this, i << 4); + } + } + + @Override + public Stream getLights() { + return world.blocksAdded.entrySet() + .stream() + .filter(it -> { + BlockPos blockPos = it.getKey(); + boolean chunkContains = blockPos.getX() >> 4 == x && blockPos.getZ() >> 4 == z; + return chunkContains && it.getValue() + .getLightEmission(world, blockPos) != 0; + }) + .map(Map.Entry::getKey); + } + + @Override + public LevelChunkSection[] getSections() { + return sections; + } + + @Override + public ChunkStatus getStatus() { + return ChunkStatus.LIGHT; + } + + @Nullable + @Override + public BlockState setBlockState(BlockPos p_177436_1_, BlockState p_177436_2_, boolean p_177436_3_) { + return null; + } + + @Override + public void setBlockEntity(BlockEntity p_177426_2_) {} + + @Override + public void addEntity(Entity p_76612_1_) {} + + @Override + public Set getBlockEntitiesPos() { + return null; + } + + @Override + public Collection> getHeightmaps() { + return null; + } + + @Override + public void setHeightmap(Heightmap.Types p_201607_1_, long[] p_201607_2_) {} + + @Override + public Heightmap getOrCreateHeightmapUnprimed(Heightmap.Types p_217303_1_) { + return null; + } + + @Override + public int getHeight(Heightmap.Types p_201576_1_, int p_201576_2_, int p_201576_3_) { + return 0; + } + + @Override + public void setUnsaved(boolean p_177427_1_) {} + + @Override + public boolean isUnsaved() { + return false; + } + + @Override + public void removeBlockEntity(BlockPos p_177425_1_) {} + + @Override + public ShortList[] getPostProcessing() { + return new ShortList[0]; + } + + @Nullable + @Override + public CompoundTag getBlockEntityNbt(BlockPos p_201579_1_) { + return null; + } + + @Nullable + @Override + public CompoundTag getBlockEntityNbtForSaving(BlockPos p_223134_1_) { + return null; + } + + @Override + public UpgradeData getUpgradeData() { + return null; + } + + @Override + public void setInhabitedTime(long p_177415_1_) {} + + @Override + public long getInhabitedTime() { + return 0; + } + + @Override + public boolean isLightCorrect() { + return needsLight; + } + + @Override + public void setLightCorrect(boolean needsLight) { + this.needsLight = needsLight; + } + + @Nullable + @Override + public BlockEntity getBlockEntity(BlockPos pos) { + return null; + } + + @Override + public BlockState getBlockState(BlockPos pos) { + return world.getBlockState(pos); + } + + @Override + public FluidState getFluidState(BlockPos p_204610_1_) { + return null; + } + + @Override + public void addReferenceForFeature(StructureFeature arg0, long arg1) {} + + @Override + public Map, LongSet> getAllReferences() { + return null; + } + + @Override + public LongSet getReferencesForFeature(StructureFeature arg0) { + return null; + } + + @Override + public StructureStart getStartForFeature(StructureFeature arg0) { + return null; + } + + @Override + public void setAllReferences(Map, LongSet> arg0) {} + + @Override + public void setStartForFeature(StructureFeature arg0, StructureStart arg1) {} + + @Override + public void setAllStarts(Map, StructureStart> p_201612_1_) {} + + @Override + public Map, StructureStart> getAllStarts() { + return null; + } + + @Override + public int getHeight() { + return world.getHeight(); + } + + @Override + public int getMinBuildHeight() { + return world.getMinBuildHeight(); + } + + @Override + public TickContainerAccess getFluidTicks() { + return BlackholeTickAccess.emptyContainer(); + } + + @Override + public TicksToSave getTicksForSerialization() { + return null; + } + + @Override + public TickContainerAccess getBlockTicks() { + return BlackholeTickAccess.emptyContainer(); + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java new file mode 100644 index 000000000..a3d4f1952 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSection.java @@ -0,0 +1,39 @@ +package com.jozufozu.flywheel.core.virtual; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.LevelChunkSection; + +public class VirtualChunkSection extends LevelChunkSection { + + public VirtualChunk owner; + + public final int xStart; + public final int yStart; + public final int zStart; + + public VirtualChunkSection(VirtualChunk owner, int yBase) { + super(yBase, owner.world.registryAccess() + .registry(Registry.BIOME_REGISTRY) + .orElseThrow()); + this.owner = owner; + this.xStart = owner.getPos() + .getMinBlockX(); + this.yStart = yBase; + this.zStart = owner.getPos() + .getMinBlockZ(); + } + + @Override + public BlockState getBlockState(int x, int y, int z) { + // ChunkSection#getBlockState expects local chunk coordinates, so we add to get + // back into world coords. + return owner.world.getBlockState(x + xStart, y + yStart, z + zStart); + } + + @Override + public BlockState setBlockState(int p_177484_1_, int p_177484_2_, int p_177484_3_, BlockState p_177484_4_, + boolean p_177484_5_) { + throw new IllegalStateException("Chunk sections should not be mutated in a fake world."); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java new file mode 100644 index 000000000..bfef41047 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java @@ -0,0 +1,65 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.HashMap; +import java.util.function.BooleanSupplier; + +import javax.annotation.Nullable; + +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.lighting.LevelLightEngine; + +public class VirtualChunkSource extends ChunkSource { + private final VirtualRenderWorld world; + + public final HashMap chunks = new HashMap<>(); + + public VirtualChunkSource(VirtualRenderWorld world) { + this.world = world; + } + + @Nullable + @Override + public BlockGetter getChunkForLighting(int x, int z) { + return getChunk(x, z); + } + + @Override + public Level getLevel() { + return world; + } + + @Nullable + @Override + public ChunkAccess getChunk(int x, int z, ChunkStatus status, boolean p_212849_4_) { + return getChunk(x, z); + } + + public ChunkAccess getChunk(int x, int z) { + long pos = ChunkPos.asLong(x, z); + + return chunks.computeIfAbsent(pos, $ -> new VirtualChunk(world, x, z)); + } + + @Override + public String gatherStats() { + return "WrappedChunkProvider"; + } + + @Override + public LevelLightEngine getLightEngine() { + return world.getLightEngine(); + } + + @Override + public void tick(BooleanSupplier pHasTimeLeft) {} + + @Override + public int getLoadedChunksCount() { + return 0; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyBlockGetter.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java similarity index 97% rename from src/main/java/com/jozufozu/flywheel/util/VirtualEmptyBlockGetter.java rename to src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java index 4f88342ab..8058bcf68 100644 --- a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyBlockGetter.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyBlockGetter.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.util; +package com.jozufozu.flywheel.core.virtual; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; @@ -120,7 +120,7 @@ public enum VirtualEmptyBlockGetter implements BlockAndTintGetter { @Override public float getShade(Direction direction, boolean bool) { - return Minecraft.getInstance().level.getShade(direction, bool); + return 1f; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyModelData.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyModelData.java similarity index 94% rename from src/main/java/com/jozufozu/flywheel/util/VirtualEmptyModelData.java rename to src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyModelData.java index 6d60d2bdb..4a8195857 100644 --- a/src/main/java/com/jozufozu/flywheel/util/VirtualEmptyModelData.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualEmptyModelData.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.util; +package com.jozufozu.flywheel.core.virtual; import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.ModelProperty; diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java new file mode 100644 index 000000000..2edd3fdf3 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualLevelEntityGetter.java @@ -0,0 +1,41 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.Collections; +import java.util.UUID; +import java.util.function.Consumer; + +import net.minecraft.world.level.entity.EntityAccess; +import net.minecraft.world.level.entity.EntityTypeTest; +import net.minecraft.world.level.entity.LevelEntityGetter; +import net.minecraft.world.phys.AABB; + +public class VirtualLevelEntityGetter implements LevelEntityGetter { + + @Override + public T get(int p_156931_) { + return null; + } + + @Override + public T get(UUID pUuid) { + return null; + } + + @Override + public Iterable getAll() { + return Collections.emptyList(); + } + + @Override + public void get(EntityTypeTest p_156935_, Consumer p_156936_) { + } + + @Override + public void get(AABB p_156937_, Consumer p_156938_) { + } + + @Override + public void get(EntityTypeTest p_156932_, AABB p_156933_, Consumer p_156934_) { + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java new file mode 100644 index 000000000..7d616c665 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java @@ -0,0 +1,265 @@ +package com.jozufozu.flywheel.core.virtual; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +import javax.annotation.Nullable; + +import com.jozufozu.flywheel.api.FlywheelWorld; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.SectionPos; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.TagContainer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.entity.LevelEntityGetter; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.lighting.LevelLightEngine; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import net.minecraft.world.level.storage.WritableLevelData; +import net.minecraft.world.scores.Scoreboard; +import net.minecraft.world.ticks.LevelTickAccess; + +public class VirtualRenderWorld extends Level implements FlywheelWorld { + public final Map blocksAdded = new HashMap<>(); + public final Map tesAdded = new HashMap<>(); + public final Set spannedSections = new HashSet<>(); + private final BlockPos.MutableBlockPos scratch = new BlockPos.MutableBlockPos(); + + public final LevelLightEngine lighter; + public final VirtualChunkSource chunkSource; + + protected Level level; + + protected LevelEntityGetter entityGetter = new VirtualLevelEntityGetter<>(); + + public VirtualRenderWorld(Level level) { + super((WritableLevelData) level.getLevelData(), level.dimension(), level.dimensionType(), level::getProfiler, + true, false, 0); + this.level = level; + this.chunkSource = new VirtualChunkSource(this); + this.lighter = new LevelLightEngine(chunkSource, true, false); + } + + /** + * Run this after you're done using setBlock(). + */ + public void runLightingEngine() { + for (Map.Entry entry : blocksAdded.entrySet()) { + BlockPos pos = entry.getKey(); + BlockState state = entry.getValue(); + int light = state.getLightEmission(this, pos); + if (light > 0) { + lighter.onBlockEmissionIncrease(pos, light); + } + } + + lighter.runUpdates(Integer.MAX_VALUE, false, false); + } + + public void setTileEntities(Collection tileEntities) { + tesAdded.clear(); + tileEntities.forEach(te -> tesAdded.put(te.getBlockPos(), te)); + } + + public void clear() { + blocksAdded.clear(); + } + + // MEANINGFUL OVERRIDES + + @Override + public ChunkSource getChunkSource() { + return chunkSource; + } + + @Override + public LevelLightEngine getLightEngine() { + return lighter; + } + + @Override + protected LevelEntityGetter getEntities() { + return entityGetter; + } + + @Override + public BlockState getBlockState(@Nullable BlockPos pos) { + BlockState state = blocksAdded.get(pos); + if (state != null) + return state; + return Blocks.AIR.defaultBlockState(); + } + + @Override + public boolean setBlockAndUpdate(BlockPos pos, BlockState state) { + return setBlock(pos, state, 0); + } + + @Override + public boolean setBlock(BlockPos pos, BlockState newState, int flags) { + blocksAdded.put(pos, newState); + + SectionPos sectionPos = SectionPos.of(pos); + if (spannedSections.add(sectionPos)) { + lighter.updateSectionStatus(sectionPos, false); + } + + if ((flags & Block.UPDATE_SUPPRESS_LIGHT) == 0) { + lighter.checkBlock(pos); + } + + return true; + } + + @Override + @Nullable + public BlockEntity getBlockEntity(BlockPos pos) { + return tesAdded.get(pos); + } + + @Override + public boolean isStateAtPosition(BlockPos pos, Predicate condition) { + return condition.test(getBlockState(pos)); + } + + public BlockState getBlockState(int x, int y, int z) { + return getBlockState(scratch.set(x, y, z)); + } + + // RENDERING CONSTANTS + + @Override + public int getMaxLocalRawBrightness(BlockPos pos) { + return 15; + } + + @Override + public float getShade(Direction p_230487_1_, boolean p_230487_2_) { + return 1f; + } + + // THIN WRAPPERS AHEAD + + @Override + public RegistryAccess registryAccess() { + return level.registryAccess(); + } + + @Override + public LevelTickAccess getBlockTicks() { + return level.getBlockTicks(); + } + + @Override + public LevelTickAccess getFluidTicks() { + return level.getFluidTicks(); + } + + @Override + public RecipeManager getRecipeManager() { + return level.getRecipeManager(); + } + + @Override + public TagContainer getTagManager() { + return level.getTagManager(); + } + + @Override + public int getFreeMapId() { + return level.getFreeMapId(); + } + + @Override + public Scoreboard getScoreboard() { + return level.getScoreboard(); + } + + @Override + public Biome getUncachedNoiseBiome(int p_225604_1_, int p_225604_2_, int p_225604_3_) { + return level.getUncachedNoiseBiome(p_225604_1_, p_225604_2_, p_225604_3_); + } + + // UNIMPORTANT CONSTANTS + + @Override + @Nullable + public Entity getEntity(int id) { + return null; + } + + @Override + @Nullable + public MapItemSavedData getMapData(String mapName) { + return null; + } + + @Override + public boolean isLoaded(BlockPos pos) { + return true; + } + + @Override + public boolean isAreaLoaded(BlockPos center, int range) { + return true; + } + + @Override + public List players() { + return Collections.emptyList(); + } + + @Override + public String gatherChunkSourceStats() { + return ""; + } + + // NOOP + + @Override + public void levelEvent(@Nullable Player player, int type, BlockPos pos, int data) {} + + @Override + public void playSound(@Nullable Player player, double x, double y, double z, SoundEvent soundIn, + SoundSource category, float volume, float pitch) {} + + @Override + public void playSound(@Nullable Player p_217384_1_, Entity p_217384_2_, SoundEvent p_217384_3_, + SoundSource p_217384_4_, float p_217384_5_, float p_217384_6_) {} + + @Override + public void setMapData(String pMapId, MapItemSavedData pData) {} + + @Override + public void destroyBlockProgress(int breakerId, BlockPos pos, int progress) {} + + @Override + public void updateNeighbourForOutputSignal(BlockPos p_175666_1_, Block p_175666_2_) {} + + @Override + public void gameEvent(@Nullable Entity pEntity, GameEvent pEvent, BlockPos pPos) {} + + @Override + public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {} + +} diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java b/src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java new file mode 100644 index 000000000..c9b5451c0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/package-info.java @@ -0,0 +1,6 @@ +@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault +package com.jozufozu.flywheel.core.virtual; + +import javax.annotation.ParametersAreNonnullByDefault; + +import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/block.frag b/src/main/resources/assets/flywheel/flywheel/shaders/block.frag index 5e1402b05..d8e5169fe 100644 --- a/src/main/resources/assets/flywheel/flywheel/shaders/block.frag +++ b/src/main/resources/assets/flywheel/flywheel/shaders/block.frag @@ -12,12 +12,6 @@ void fragment(BlockFrag r) { vec4 color = vec4(tex.rgb * FLWLight(r.light).rgb * r.diffuse, tex.a) * r.color; -// flw_WorldPos = ; -// flw_Normal = ; -// flw_Albedo = tex.rgb; -// flw_Alpha = tex.a; -// flw_LightMap = r.light; -// flw_Tint = r.color; FLWFinalizeColor(color); } #endif From 47e3aaa2900e72e4c7278e1416dbccb005f54109 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 26 Dec 2021 15:41:20 -0800 Subject: [PATCH 3/5] Towards starlight compat - Steal Mods enum from Create. - Cursemaven dep for starlight Co-authored-by: Aeiou <3160746+aeiouenigma@users.noreply.github.com> --- build.gradle | 8 ++ .../flywheel/core/virtual/VirtualChunk.java | 14 ++- .../core/virtual/VirtualChunkSource.java | 4 - .../core/virtual/VirtualRenderWorld.java | 85 +++++++++++++++++-- .../java/com/jozufozu/flywheel/util/Mods.java | 47 ++++++++++ 5 files changed, 147 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/util/Mods.java diff --git a/build.gradle b/build.gradle index 759b5e7f0..12a1dbb04 100644 --- a/build.gradle +++ b/build.gradle @@ -92,6 +92,12 @@ mixin { } repositories { + maven { + url 'https://www.cursemaven.com' + content { + includeGroup "curse.maven" + } + } maven { name 'tterrag maven' url 'https://maven.tterrag.com/' @@ -101,6 +107,8 @@ repositories { dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + compileOnly fg.deobf("curse.maven:starlight-526854:3559934") + // https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497 // Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings // This allows 'Settings > Build, Execution, and Deployment > Build Tools > Gradle > Build and run using' set to IntelliJ to work correctly diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java index 925d7516a..ec3bb296f 100644 --- a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunk.java @@ -7,6 +7,10 @@ import java.util.stream.Stream; import javax.annotation.Nullable; +import com.jozufozu.flywheel.util.Mods; + +import ca.spottedleaf.starlight.common.chunk.ExtendedChunk; +import ca.spottedleaf.starlight.common.light.StarLightEngine; import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.shorts.ShortList; import net.minecraft.core.BlockPos; @@ -48,11 +52,17 @@ public class VirtualChunk extends ChunkAccess { this.x = x; this.z = z; - this.sections = new LevelChunkSection[16]; + int sectionCount = world.getSectionsCount(); + this.sections = new LevelChunkSection[sectionCount]; - for (int i = 0; i < 16; i++) { + for (int i = 0; i < sectionCount; i++) { sections[i] = new VirtualChunkSection(this, i << 4); } + + Mods.STARLIGHT.executeIfInstalled(() -> () -> { + ((ExtendedChunk)this).setBlockNibbles(StarLightEngine.getFilledEmptyLight(this)); + ((ExtendedChunk)this).setSkyNibbles(StarLightEngine.getFilledEmptyLight(this)); + }); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java index bfef41047..b374260d0 100644 --- a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualChunkSource.java @@ -3,8 +3,6 @@ package com.jozufozu.flywheel.core.virtual; import java.util.HashMap; import java.util.function.BooleanSupplier; -import javax.annotation.Nullable; - import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; @@ -22,7 +20,6 @@ public class VirtualChunkSource extends ChunkSource { this.world = world; } - @Nullable @Override public BlockGetter getChunkForLighting(int x, int z) { return getChunk(x, z); @@ -33,7 +30,6 @@ public class VirtualChunkSource extends ChunkSource { return world; } - @Nullable @Override public ChunkAccess getChunk(int x, int z, ChunkStatus status, boolean p_212849_4_) { return getChunk(x, z); diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java index 7d616c665..fb50c9469 100644 --- a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java @@ -29,7 +29,9 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkSource; +import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.entity.LevelEntityGetter; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.lighting.LevelLightEngine; @@ -45,17 +47,24 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld { public final Set spannedSections = new HashSet<>(); private final BlockPos.MutableBlockPos scratch = new BlockPos.MutableBlockPos(); - public final LevelLightEngine lighter; - public final VirtualChunkSource chunkSource; + protected final Level level; + protected final LevelLightEngine lighter; + protected final VirtualChunkSource chunkSource; + protected final LevelEntityGetter entityGetter = new VirtualLevelEntityGetter<>(); - protected Level level; - - protected LevelEntityGetter entityGetter = new VirtualLevelEntityGetter<>(); + protected final int height; + protected final int minBuildHeight; public VirtualRenderWorld(Level level) { + this(level, level.getHeight(), level.getMinBuildHeight()); + } + + public VirtualRenderWorld(Level level, int height, int minBuildHeight) { super((WritableLevelData) level.getLevelData(), level.dimension(), level.dimensionType(), level::getProfiler, true, false, 0); this.level = level; + this.height = height; + this.minBuildHeight = minBuildHeight; this.chunkSource = new VirtualChunkSource(this); this.lighter = new LevelLightEngine(chunkSource, true, false); } @@ -87,6 +96,16 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld { // MEANINGFUL OVERRIDES + @Override + public int getHeight() { + return height; + } + + @Override + public int getMinBuildHeight() { + return minBuildHeight; + } + @Override public ChunkSource getChunkSource() { return chunkSource; @@ -262,4 +281,60 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld { @Override public void sendBlockUpdated(BlockPos pos, BlockState oldState, BlockState newState, int flags) {} + // Override Starlight's ExtendedWorld interface methods: + + public LevelChunk getChunkAtImmediately(final int chunkX, final int chunkZ) { + return chunkSource.getChunk(chunkX, chunkZ, false); + } + + public ChunkAccess getAnyChunkImmediately(final int chunkX, final int chunkZ) { + return chunkSource.getChunk(chunkX, chunkZ); + } + + // Intentionally copied from LevelHeightAccessor. Lithium overrides these methods so we need to, too. + + @Override + public int getMaxBuildHeight() { + return this.getMinBuildHeight() + this.getHeight(); + } + + @Override + public int getSectionsCount() { + return this.getMaxSection() - this.getMinSection(); + } + + @Override + public int getMinSection() { + return SectionPos.blockToSectionCoord(this.getMinBuildHeight()); + } + + @Override + public int getMaxSection() { + return SectionPos.blockToSectionCoord(this.getMaxBuildHeight() - 1) + 1; + } + + @Override + public boolean isOutsideBuildHeight(BlockPos pos) { + return this.isOutsideBuildHeight(pos.getY()); + } + + @Override + public boolean isOutsideBuildHeight(int y) { + return y < this.getMinBuildHeight() || y >= this.getMaxBuildHeight(); + } + + @Override + public int getSectionIndex(int y) { + return this.getSectionIndexFromSectionY(SectionPos.blockToSectionCoord(y)); + } + + @Override + public int getSectionIndexFromSectionY(int sectionY) { + return sectionY - this.getMinSection(); + } + + @Override + public int getSectionYFromSectionIndex(int sectionIndex) { + return sectionIndex + this.getMinSection(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/util/Mods.java b/src/main/java/com/jozufozu/flywheel/util/Mods.java new file mode 100644 index 000000000..27c0cb2f2 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/util/Mods.java @@ -0,0 +1,47 @@ +package com.jozufozu.flywheel.util; + +import java.util.Optional; +import java.util.function.Supplier; + +import net.minecraftforge.fml.ModList; + +/** + * For compatibility with and without another mod present, we have to define load conditions of the specific code + */ +public enum Mods { + STARLIGHT("starlight"); + + private final String id; + + Mods(String id) { + this.id = id; + } + + /** + * @return a boolean of whether the mod is loaded or not based on mod id + */ + public boolean isLoaded() { + return ModList.get().isLoaded(id); + } + + /** + * Simple hook to run code if a mod is installed + * @param toRun will be run only if the mod is loaded + * @return Optional.empty() if the mod is not loaded, otherwise an Optional of the return value of the given supplier + */ + public Optional runIfInstalled(Supplier> toRun) { + if (isLoaded()) + return Optional.of(toRun.get().get()); + return Optional.empty(); + } + + /** + * Simple hook to execute code if a mod is installed + * @param toExecute will be executed only if the mod is loaded + */ + public void executeIfInstalled(Supplier toExecute) { + if (isLoaded()) { + toExecute.get().run(); + } + } +} From 78030b2f40bd9291ba1acc40034db6fcefd3f399 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Mon, 27 Dec 2021 13:37:09 -0800 Subject: [PATCH 4/5] Fix contraption lighting - Actually just one line. --- changelog.txt | 10 +++++- .../backend/model/ArrayModelRenderer.java | 2 -- .../core/vertex/BlockWriterUnsafe.java | 2 +- .../core/vertex/VertexWriterUnsafe.java | 1 + .../core/virtual/VirtualRenderWorld.java | 32 +++++++++---------- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/changelog.txt b/changelog.txt index e2e1695aa..1a62e6f1a 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,12 @@ -0.4.1a: +0.5.0: +New + - Added parallel batching backend, effectively a CPU instancer. + - Now partially compatible with starlight. +Technical/API + - Much more flexible vertex formats. + - Do instance updates/ticking entirely async. + +0.4.2-rc: Fixes - Partially fix crash on intel and mesa drivers (needs Create to update) - Fix garbage rendering on AMD GPUs diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java index 0a5185bd9..457226ead 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java @@ -4,7 +4,6 @@ import java.util.function.Supplier; import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.core.model.Model; -import com.jozufozu.flywheel.util.AttribUtil; public class ArrayModelRenderer extends ModelRenderer { @@ -36,7 +35,6 @@ public class ArrayModelRenderer extends ModelRenderer { vao = new GlVertexArray(); vao.bind(); - vao.enableArrays(this.model.getAttributeCount()); // bind the model's vbo to our vao this.model.setupState(); diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java index 84d49dee9..044160349 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/BlockWriterUnsafe.java @@ -46,7 +46,7 @@ public class BlockWriterUnsafe extends VertexWriterUnsafe { MemoryUtil.memPutByte(ptr + 15, a); MemoryUtil.memPutFloat(ptr + 16, u); MemoryUtil.memPutFloat(ptr + 20, v); - MemoryUtil.memPutInt(ptr + 24, light); + MemoryUtil.memPutInt(ptr + 24, light << 8); // light is packed in the low byte of each short MemoryUtil.memPutByte(ptr + 28, RenderMath.nb(nX)); MemoryUtil.memPutByte(ptr + 29, RenderMath.nb(nY)); MemoryUtil.memPutByte(ptr + 30, RenderMath.nb(nZ)); diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java b/src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java index 5ad8bd70c..c524fc804 100644 --- a/src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java +++ b/src/main/java/com/jozufozu/flywheel/core/vertex/VertexWriterUnsafe.java @@ -24,6 +24,7 @@ public abstract class VertexWriterUnsafe implements Vertex protected void advance() { writeVertex++; + // account for seeking if (writeVertex > totalVertices) totalVertices = writeVertex; } diff --git a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java index fb50c9469..bfd246988 100644 --- a/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java +++ b/src/main/java/com/jozufozu/flywheel/core/virtual/VirtualRenderWorld.java @@ -96,6 +96,22 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld { // MEANINGFUL OVERRIDES + @Override + public boolean setBlock(BlockPos pos, BlockState newState, int flags) { + blocksAdded.put(pos, newState); + + SectionPos sectionPos = SectionPos.of(pos); + if (spannedSections.add(sectionPos)) { + lighter.updateSectionStatus(sectionPos, false); + } + + if ((flags & Block.UPDATE_SUPPRESS_LIGHT) == 0) { + lighter.checkBlock(pos); + } + + return true; + } + @Override public int getHeight() { return height; @@ -134,22 +150,6 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld { return setBlock(pos, state, 0); } - @Override - public boolean setBlock(BlockPos pos, BlockState newState, int flags) { - blocksAdded.put(pos, newState); - - SectionPos sectionPos = SectionPos.of(pos); - if (spannedSections.add(sectionPos)) { - lighter.updateSectionStatus(sectionPos, false); - } - - if ((flags & Block.UPDATE_SUPPRESS_LIGHT) == 0) { - lighter.checkBlock(pos); - } - - return true; - } - @Override @Nullable public BlockEntity getBlockEntity(BlockPos pos) { From 179eafecd3eb8fcc931d42d839b99d1191071fea Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Mon, 27 Dec 2021 19:14:19 -0800 Subject: [PATCH 5/5] Go through GlVertexArray - VAO state is now handled by GlVertexArray objects - IndexedModel no longer inherits from VBOModel - BufferedModel doesn't need #clearState - Likely fixes crash on intel drivers --- .../flywheel/backend/gl/GlObject.java | 13 +--- .../flywheel/backend/gl/GlVertexArray.java | 30 ++++++-- .../instancing/instancing/GPUInstancer.java | 16 ++--- .../backend/model/ArrayModelRenderer.java | 32 +++++---- .../flywheel/backend/model/BufferedModel.java | 13 ++-- .../flywheel/backend/model/IndexedModel.java | 71 +++++++++++++++---- .../flywheel/backend/model/ModelPool.java | 20 ++---- .../flywheel/backend/model/ModelRenderer.java | 47 ------------ .../flywheel/backend/model/VBOModel.java | 15 ++-- .../flywheel/core/layout/BufferLayout.java | 15 ++-- .../jozufozu/flywheel/util/AttribUtil.java | 27 ------- 11 files changed, 137 insertions(+), 162 deletions(-) delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/model/ModelRenderer.java delete mode 100644 src/main/java/com/jozufozu/flywheel/util/AttribUtil.java diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlObject.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlObject.java index b36bcb5ce..27956c87e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlObject.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlObject.java @@ -18,9 +18,7 @@ public abstract class GlObject { protected final void checkHandle() { if (this.isInvalid()) { - String descriptor = getDescriptor(); - String message = (descriptor == null ? "" : (descriptor + " ")) + "handle is not valid."; - throw new IllegalStateException(message); + throw new IllegalStateException("handle is not valid."); } } @@ -33,10 +31,8 @@ public abstract class GlObject { } public void delete() { - if (isInvalid()) { - String descriptor = getDescriptor(); - String message = (descriptor == null ? "" : (descriptor + " ")) + "handle already deleted."; - throw new IllegalStateException(message); + if (this.isInvalid()) { + throw new IllegalStateException("handle already deleted."); } deleteInternal(handle); @@ -45,7 +41,4 @@ public abstract class GlObject { protected abstract void deleteInternal(int handle); - protected String getDescriptor() { - return ""; - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java index 18f7bfc26..1ec315fa9 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/GlVertexArray.java @@ -1,7 +1,10 @@ package com.jozufozu.flywheel.backend.gl; +import org.lwjgl.opengl.GL20; + +import com.jozufozu.flywheel.core.layout.BufferLayout; +import com.jozufozu.flywheel.core.layout.LayoutItem; import com.jozufozu.flywheel.mixin.BufferUploaderAccessor; -import com.jozufozu.flywheel.util.AttribUtil; import com.mojang.blaze3d.platform.GlStateManager; public class GlVertexArray extends GlObject { @@ -20,11 +23,28 @@ public class GlVertexArray extends GlObject { BufferUploaderAccessor.flywheel$setLastVAO(0); } + public void enableArrays(int count) { + for (int i = 0; i < count; i++) { + GL20.glEnableVertexAttribArray(i); + } + } + + public void disableArrays(int count) { + for (int i = 0; i < count; i++) { + GL20.glDisableVertexAttribArray(i); + } + } + + public void bindAttributes(int startIndex, BufferLayout type) { + int offset = 0; + for (LayoutItem spec : type.getLayoutItems()) { + spec.vertexAttribPointer(type.getStride(), startIndex, offset); + startIndex += spec.getAttributeCount(); + offset += spec.getSize(); + } + } + protected void deleteInternal(int handle) { GlStateManager._glDeleteVertexArrays(handle); } - - public void enableArrays(int count) { - AttribUtil.enableArrays(count); - } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java index 1c7f0eb74..5d0e20bd2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/GPUInstancer.java @@ -8,13 +8,13 @@ import com.jozufozu.flywheel.api.struct.Instanced; import com.jozufozu.flywheel.api.struct.StructWriter; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.gl.GlVertexArray; -import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer; import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType; import com.jozufozu.flywheel.backend.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.instancing.AbstractInstancer; import com.jozufozu.flywheel.backend.model.BufferedModel; import com.jozufozu.flywheel.backend.model.ModelAllocator; +import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.core.model.Model; public class GPUInstancer extends AbstractInstancer { @@ -73,14 +73,14 @@ public class GPUInstancer extends AbstractInstancer { model = modelAllocator.alloc(modelData, arenaModel -> { vao.bind(); - arenaModel.setupState(); + arenaModel.setupState(vao); }); vao.bind(); + vao.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount()); instanceVBO = GlBuffer.requestPersistent(GlBufferType.ARRAY_BUFFER); instanceVBO.setGrowthMargin(instanceFormat.getStride() * 16); - vao.enableArrays(model.getAttributeCount() + instanceFormat.getAttributeCount()); } public boolean isInitialized() { @@ -180,19 +180,19 @@ public class GPUInstancer extends AbstractInstancer { glInstanceCount = size; - informAttribDivisors(); + bindInstanceAttributes(); return true; } return false; } - private void informAttribDivisors() { - int staticAttributes = model.getAttributeCount(); - instanceFormat.vertexAttribPointers(staticAttributes); + private void bindInstanceAttributes() { + int attributeBaseIndex = model.getAttributeCount(); + vao.bindAttributes(attributeBaseIndex, instanceFormat); for (int i = 0; i < instanceFormat.getAttributeCount(); i++) { - Backend.getInstance().compat.instancedArrays.vertexAttribDivisor(i + staticAttributes, 1); + Backend.getInstance().compat.instancedArrays.vertexAttribDivisor(attributeBaseIndex + i, 1); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java index 457226ead..f190aa103 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ArrayModelRenderer.java @@ -1,46 +1,54 @@ package com.jozufozu.flywheel.backend.model; -import java.util.function.Supplier; - import com.jozufozu.flywheel.backend.gl.GlVertexArray; import com.jozufozu.flywheel.core.model.Model; -public class ArrayModelRenderer extends ModelRenderer { +public class ArrayModelRenderer { + private final Model model; protected GlVertexArray vao; + protected BufferedModel vbo; + protected boolean initialized; - public ArrayModelRenderer(Supplier model) { - super(model); + public ArrayModelRenderer(Model model) { + this.model = model; } - @Override + /** + * Renders this model, checking first if there is anything to render. + */ public void draw() { if (!initialized) init(); if (!isValid()) return; vao.bind(); - model.drawCall(); + vbo.drawCall(); } - @Override protected void init() { initialized = true; - Model model = modelSupplier.get(); if (model.empty()) return; - this.model = new IndexedModel(model); + this.vbo = new IndexedModel(model); vao = new GlVertexArray(); vao.bind(); // bind the model's vbo to our vao - this.model.setupState(); + this.vbo.setupState(vao); GlVertexArray.unbind(); + } - this.model.clearState(); + public void delete() { + if (vbo != null) + vbo.delete(); + } + + protected boolean isValid() { + return vbo != null && vbo.valid(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java index 2c7bf5cb9..5dc2e3107 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/BufferedModel.java @@ -1,7 +1,8 @@ package com.jozufozu.flywheel.backend.model; -import com.jozufozu.flywheel.core.layout.BufferLayout; import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.backend.gl.GlVertexArray; +import com.jozufozu.flywheel.core.layout.BufferLayout; public interface BufferedModel { @@ -10,11 +11,9 @@ public interface BufferedModel { int getVertexCount(); /** - * The VBO/VAO should be bound externally. + * The VAO must be bound externally. */ - void setupState(); - - void clearState(); + void setupState(GlVertexArray vao); void drawCall(); @@ -27,7 +26,7 @@ public interface BufferedModel { void delete(); - default BufferLayout getFormat() { + default BufferLayout getLayout() { return getType().getLayout(); } @@ -36,6 +35,6 @@ public interface BufferedModel { } default int getAttributeCount() { - return getFormat().getAttributeCount(); + return getType().getLayout().getAttributeCount(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java index 06bd043b2..7a372b0c8 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/IndexedModel.java @@ -3,7 +3,14 @@ package com.jozufozu.flywheel.backend.model; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL31; +import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.gl.GlPrimitive; +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.gl.buffer.MappedBuffer; +import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; import com.jozufozu.flywheel.core.model.Model; /** @@ -11,26 +18,43 @@ import com.jozufozu.flywheel.core.model.Model; * *
This should be favored over a normal BufferedModel. */ -public class IndexedModel extends VBOModel { +public class IndexedModel implements BufferedModel { + protected final Model model; + protected final GlPrimitive primitiveMode; protected ElementBuffer ebo; + protected GlBuffer vbo; + protected boolean deleted; public IndexedModel(Model model) { - super(GlPrimitive.TRIANGLES, model); + this.model = model; + this.primitiveMode = GlPrimitive.TRIANGLES; + + vbo = new MappedGlBuffer(GlBufferType.ARRAY_BUFFER); + + vbo.bind(); + // allocate the buffer on the gpu + vbo.ensureCapacity(model.size()); + + // mirror it in system memory, so we can write to it, and upload our model. + try (MappedBuffer buffer = vbo.getBuffer()) { + model.writeInto(buffer.unwrap()); + } catch (Exception e) { + Flywheel.LOGGER.error(String.format("Error uploading model '%s':", model.name()), e); + } + + vbo.unbind(); this.ebo = model.createEBO(); } - @Override - public void setupState() { - super.setupState(); - ebo.bind(); - } - - @Override - public void clearState() { - super.clearState(); - ebo.unbind(); + /** + * The VBO/VAO should be bound externally. + */ + public void setupState(GlVertexArray vao) { + vbo.bind(); + vao.enableArrays(getAttributeCount()); + vao.bindAttributes(0, getType().getLayout()); } @Override @@ -39,6 +63,9 @@ public class IndexedModel extends VBOModel { GL20.glDrawElements(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0); } + /** + * Draws many instances of this model, assuming the appropriate state is already bound. + */ @Override public void drawInstances(int instanceCount) { if (!valid()) return; @@ -47,4 +74,24 @@ public class IndexedModel extends VBOModel { GL31.glDrawElementsInstanced(primitiveMode.glEnum, ebo.elementCount, ebo.eboIndexType.getGlEnum(), 0, instanceCount); } + + public boolean isDeleted() { + return deleted; + } + + @Override + public VertexType getType() { + return model.getType(); + } + + public int getVertexCount() { + return model.vertexCount(); + } + + public void delete() { + if (deleted) return; + + deleted = true; + vbo.delete(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java index 4561577bf..7eadc68dc 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/ModelPool.java @@ -6,15 +6,15 @@ import java.util.List; import org.lwjgl.opengl.GL32; import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.vertex.VertexType; +import com.jozufozu.flywheel.api.vertex.VertexWriter; import com.jozufozu.flywheel.backend.gl.GlPrimitive; +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.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; import com.jozufozu.flywheel.core.model.Model; -import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.api.vertex.VertexWriter; -import com.jozufozu.flywheel.util.AttribUtil; public class ModelPool implements ModelAllocator { @@ -178,18 +178,10 @@ public class ModelPool implements ModelAllocator { } @Override - public void setupState() { + public void setupState(GlVertexArray vao) { vbo.bind(); - ebo.bind(); - AttribUtil.enableArrays(getAttributeCount()); - ModelPool.this.vertexType.getLayout().vertexAttribPointers(0); - } - - @Override - public void clearState() { - AttribUtil.disableArrays(getAttributeCount()); - ebo.unbind(); - vbo.unbind(); + vao.enableArrays(getAttributeCount()); + vao.bindAttributes(0, vertexType.getLayout()); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/ModelRenderer.java b/src/main/java/com/jozufozu/flywheel/backend/model/ModelRenderer.java deleted file mode 100644 index 2debba1ab..000000000 --- a/src/main/java/com/jozufozu/flywheel/backend/model/ModelRenderer.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.jozufozu.flywheel.backend.model; - -import java.util.function.Supplier; - -import com.jozufozu.flywheel.core.model.Model; - -public class ModelRenderer { - - protected Supplier modelSupplier; - protected BufferedModel model; - - protected boolean initialized; - - public ModelRenderer(Supplier modelSupplier) { - this.modelSupplier = modelSupplier; - } - - /** - * Renders this model, checking first if there is anything to render. - */ - public void draw() { - if (!initialized) init(); - if (!isValid()) return; - - model.setupState(); - model.drawCall(); - model.clearState(); - } - - public void delete() { - if (model != null) - model.delete(); - } - - protected void init() { - initialized = true; - Model model = modelSupplier.get(); - - if (model.empty()) return; - - this.model = new IndexedModel(model); - } - - protected boolean isValid() { - return model != null && model.valid(); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java index dcc26d234..54dccbd28 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java +++ b/src/main/java/com/jozufozu/flywheel/backend/model/VBOModel.java @@ -5,14 +5,14 @@ import static org.lwjgl.opengl.GL11.glDrawArrays; import org.lwjgl.opengl.GL31; import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.gl.GlPrimitive; +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.gl.buffer.MappedBuffer; import com.jozufozu.flywheel.backend.gl.buffer.MappedGlBuffer; import com.jozufozu.flywheel.core.model.Model; -import com.jozufozu.flywheel.api.vertex.VertexType; -import com.jozufozu.flywheel.util.AttribUtil; public class VBOModel implements BufferedModel { @@ -57,15 +57,10 @@ public class VBOModel implements BufferedModel { /** * The VBO/VAO should be bound externally. */ - public void setupState() { + public void setupState(GlVertexArray vao) { vbo.bind(); - AttribUtil.enableArrays(getAttributeCount()); - getFormat().vertexAttribPointers(0); - } - - public void clearState() { - AttribUtil.disableArrays(getAttributeCount()); - vbo.unbind(); + vao.enableArrays(getAttributeCount()); + vao.bindAttributes(0, getLayout()); } public void drawCall() { diff --git a/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java b/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java index cbfb4fcc7..d7111f706 100644 --- a/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java +++ b/src/main/java/com/jozufozu/flywheel/core/layout/BufferLayout.java @@ -9,7 +9,7 @@ import com.jozufozu.flywheel.api.vertex.VertexType; * Classic Vertex Format struct with a clever name. * *

- * Used for vertices and instance. Describes the layout of a datatype in a buffer object. + * Used for vertices and instances. Describes the layout of a datatype in a buffer object. *

* * @see com.jozufozu.flywheel.api.struct.StructType @@ -34,6 +34,10 @@ public class BufferLayout { this.stride = stride; } + public List getLayoutItems() { + return allAttributes; + } + public int getAttributeCount() { return numAttributes; } @@ -42,15 +46,6 @@ public class BufferLayout { return stride; } - public void vertexAttribPointers(int index) { - int offset = 0; - for (LayoutItem spec : this.allAttributes) { - spec.vertexAttribPointer(stride, index, offset); - index += spec.getAttributeCount(); - offset += spec.getSize(); - } - } - public static Builder builder() { return new Builder(); } diff --git a/src/main/java/com/jozufozu/flywheel/util/AttribUtil.java b/src/main/java/com/jozufozu/flywheel/util/AttribUtil.java deleted file mode 100644 index b50fe47a3..000000000 --- a/src/main/java/com/jozufozu/flywheel/util/AttribUtil.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.jozufozu.flywheel.util; - -import org.lwjgl.opengl.GL20; - -// TODO: move this functionality into GlVertexArray and track it -public class AttribUtil { - - public static void enableArrays(int count) { - enableArrays(0, count); - } - - public static void enableArrays(int fromInclusive, int toExclusive) { - for (int i = fromInclusive; i < toExclusive; i++) { - GL20.glEnableVertexAttribArray(i); - } - } - - public static void disableArrays(int count) { - disableArrays(0, count); - } - - public static void disableArrays(int fromInclusive, int toExclusive) { - for (int i = fromInclusive; i < toExclusive; i++) { - GL20.glDisableVertexAttribArray(i); - } - } -}