mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-29 14:24:58 +01:00
Merge remote-tracking branch 'origin/1.19/dev' into 1.19/fabric/dev
Conflicts: build.gradle gradle.properties src/main/java/com/jozufozu/flywheel/Flywheel.java src/main/java/com/jozufozu/flywheel/backend/Loader.java src/main/java/com/jozufozu/flywheel/config/FlwCommands.java src/main/java/com/jozufozu/flywheel/core/PartialModel.java src/main/java/com/jozufozu/flywheel/core/model/BakedModelBuilder.java src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java src/main/java/com/jozufozu/flywheel/core/model/ShadeSeparatedBufferBuilder.java src/main/java/com/jozufozu/flywheel/core/model/WorldModelBuilder.java src/main/java/com/jozufozu/flywheel/core/vertex/BlockVertex.java src/main/java/com/jozufozu/flywheel/event/EntityWorldHandler.java src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java src/main/java/com/jozufozu/flywheel/util/RenderMath.java src/main/resources/META-INF/mods.toml src/main/resources/pack.mcmeta
This commit is contained in:
commit
954d1d77fb
30 changed files with 393 additions and 187 deletions
|
@ -61,7 +61,8 @@ dependencies {
|
|||
// Fabric API
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
|
||||
|
||||
modCompileOnly 'curse.maven:starlight-521783:3667443'
|
||||
// switch to implementation for debugging
|
||||
modCompileOnly 'maven.modrinth:starlight:1.1.1+1.19'
|
||||
|
||||
modCompileOnly 'maven.modrinth:iris:1.18.x-v1.2.5'
|
||||
modCompileOnly 'maven.modrinth:sodium:mc1.18.2-0.4.1'
|
||||
|
@ -155,6 +156,6 @@ curseforge {
|
|||
changelog = file('changelog.txt')
|
||||
releaseType = project.curse_type
|
||||
mainArtifact jar
|
||||
addGameVersion '1.18.2'
|
||||
addGameVersion '1.19.2'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@ org.gradle.daemon = false
|
|||
|
||||
# mod version info
|
||||
mod_version = 0.6.8
|
||||
artifact_minecraft_version = 1.18.2
|
||||
artifact_minecraft_version = 1.19.2
|
||||
|
||||
minecraft_version = 1.18.2
|
||||
minecraft_version = 1.19.2
|
||||
loader_version = 0.14.9
|
||||
fabric_version = 0.66.0+1.18.2
|
||||
fabric_version = 0.66.0+1.19.2
|
||||
|
||||
# build dependency versions
|
||||
loom_version = 1.0-SNAPSHOT
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.jozufozu.flywheel.backend.Loader;
|
|||
import com.jozufozu.flywheel.backend.RenderWork;
|
||||
import com.jozufozu.flywheel.backend.ShadersModHandler;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.core.Contexts;
|
||||
import com.jozufozu.flywheel.core.PartialModel;
|
||||
|
@ -21,6 +22,7 @@ import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
|||
import com.mojang.logging.LogUtils;
|
||||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||
|
@ -55,6 +57,7 @@ public class Flywheel implements ClientModInitializer {
|
|||
ShadersModHandler.init();
|
||||
Backend.init();
|
||||
|
||||
ClientCommandRegistrationCallback.EVENT.register(FlwCommands::registerClientCommands);
|
||||
FlywheelEvents.RELOAD_RENDERERS.register(ProgramCompiler::invalidateAll);
|
||||
|
||||
FlywheelEvents.GATHER_CONTEXT.register(Contexts::flwInit);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -90,11 +90,11 @@ public class Loader {
|
|||
private void loadProgramSpecs(ResourceManager manager) {
|
||||
programs.clear();
|
||||
|
||||
Collection<ResourceLocation> programSpecs = manager.listResources(PROGRAM_DIR, s -> s.endsWith(".json"));
|
||||
Map<ResourceLocation, Resource> programSpecs = manager.listResources(PROGRAM_DIR, loc -> loc.getPath().endsWith(".json"));
|
||||
|
||||
for (ResourceLocation location : programSpecs) {
|
||||
try (Resource resource = manager.getResource(location)) {
|
||||
String s = StringUtil.readToString(resource.getInputStream());
|
||||
programSpecs.forEach((location, resource) -> {
|
||||
try (InputStream inputStream = resource.open()) {
|
||||
String s = StringUtil.readToString(inputStream);
|
||||
|
||||
ResourceLocation specName = ResourceUtil.trim(location, PROGRAM_DIR, ".json");
|
||||
|
||||
|
@ -114,7 +114,7 @@ public class Loader {
|
|||
} catch (Exception e) {
|
||||
Backend.LOGGER.error("Could not load program " + location, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static class ResourceReloadListener implements ResourceManagerReloadListener, IdentifiableResourceReloadListener {
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import net.minecraft.commands.SharedSuggestionProvider;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
|
||||
public enum BackendTypeArgument implements ArgumentType<BackendType> {
|
||||
INSTANCE;
|
||||
|
||||
private static final Dynamic2CommandExceptionType INVALID = new Dynamic2CommandExceptionType((found, constants) -> {
|
||||
// TODO: don't steal lang
|
||||
return new TranslatableComponent("commands.forge.arguments.enum.invalid", constants, found);
|
||||
});
|
||||
|
||||
@Override
|
||||
public BackendType parse(StringReader reader) throws CommandSyntaxException {
|
||||
String string = reader.readUnquotedString();
|
||||
|
||||
BackendType engine = BackendType.byName(string);
|
||||
|
||||
if (engine == null) {
|
||||
throw INVALID.createWithContext(reader, string, BackendType.validNames());
|
||||
}
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
|
||||
return SharedSuggestionProvider.suggest(BackendType.validNames(), builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getExamples() {
|
||||
return BackendType.validNames();
|
||||
}
|
||||
|
||||
public static BackendTypeArgument getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
|
@ -8,17 +8,20 @@ import org.jetbrains.annotations.NotNull;
|
|||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.config.Option.EnumOption;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
|
||||
import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager;
|
||||
import net.fabricmc.fabric.api.client.command.v1.FabricClientCommandSource;
|
||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
|
||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
|
||||
public final class FlwCommands {
|
||||
public static void init(FlwConfig config) {
|
||||
public static void registerClientCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandBuildContext context) {
|
||||
FlwConfig config = FlwConfig.get();
|
||||
|
||||
ConfigCommandBuilder commandBuilder = new ConfigCommandBuilder("flywheel");
|
||||
|
||||
commandBuilder.addOption(config.backend, (builder, option) -> enumOptionCommand(builder, config, option,
|
||||
|
@ -34,27 +37,27 @@ public final class FlwCommands {
|
|||
|
||||
commandBuilder.addOption(config.debugNormals, (builder, option) -> booleanOptionCommand(builder, config, option,
|
||||
(source, value) -> {
|
||||
Component text = new TextComponent("Normal debug mode is currently: ").append(boolToText(value));
|
||||
Component text = Component.literal("Normal debug mode is currently: ").append(boolToText(value));
|
||||
source.sendFeedback(text);
|
||||
},
|
||||
(source, value) -> {
|
||||
Component text = boolToText(value).append(new TextComponent(" normal debug mode").withStyle(ChatFormatting.WHITE));
|
||||
Component text = boolToText(value).append(Component.literal(" normal debug mode").withStyle(ChatFormatting.WHITE));
|
||||
source.sendFeedback(text);
|
||||
}
|
||||
));
|
||||
|
||||
commandBuilder.addOption(config.limitUpdates, (builder, option) -> booleanOptionCommand(builder, config, option,
|
||||
(source, value) -> {
|
||||
Component text = new TextComponent("Update limiting is currently: ").append(boolToText(value));
|
||||
Component text = Component.literal("Update limiting is currently: ").append(boolToText(value));
|
||||
source.sendFeedback(text);
|
||||
},
|
||||
(source, value) -> {
|
||||
Component text = boolToText(value).append(new TextComponent(" update limiting.").withStyle(ChatFormatting.WHITE));
|
||||
Component text = boolToText(value).append(Component.literal(" update limiting.").withStyle(ChatFormatting.WHITE));
|
||||
source.sendFeedback(text);
|
||||
}
|
||||
));
|
||||
|
||||
commandBuilder.build();
|
||||
commandBuilder.build(dispatcher);
|
||||
}
|
||||
|
||||
public static void booleanOptionCommand(LiteralArgumentBuilder<FabricClientCommandSource> builder, FlwConfig config, Option<Boolean> option, BiConsumer<FabricClientCommandSource, Boolean> displayAction, BiConsumer<FabricClientCommandSource, Boolean> setAction) {
|
||||
|
@ -96,14 +99,14 @@ public final class FlwCommands {
|
|||
}
|
||||
|
||||
public static MutableComponent boolToText(boolean b) {
|
||||
return b ? new TextComponent("enabled").withStyle(ChatFormatting.DARK_GREEN) : new TextComponent("disabled").withStyle(ChatFormatting.RED);
|
||||
return b ? Component.literal("enabled").withStyle(ChatFormatting.DARK_GREEN) : Component.literal("disabled").withStyle(ChatFormatting.RED);
|
||||
}
|
||||
|
||||
public static Component getEngineMessage(@NotNull BackendType type) {
|
||||
return switch (type) {
|
||||
case OFF -> new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED);
|
||||
case INSTANCING -> new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN);
|
||||
case BATCHING -> new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN);
|
||||
case OFF -> Component.literal("Disabled Flywheel").withStyle(ChatFormatting.RED);
|
||||
case INSTANCING -> Component.literal("Using Instancing Engine").withStyle(ChatFormatting.GREEN);
|
||||
case BATCHING -> Component.literal("Using Batching Engine").withStyle(ChatFormatting.GREEN);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -124,8 +127,8 @@ public final class FlwCommands {
|
|||
command.then(builder);
|
||||
}
|
||||
|
||||
public void build() {
|
||||
ClientCommandManager.DISPATCHER.register(command);
|
||||
public void build(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||
dispatcher.register(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ public class FlwConfig {
|
|||
|
||||
public static void init() {
|
||||
INSTANCE.load();
|
||||
FlwCommands.init(INSTANCE);
|
||||
}
|
||||
|
||||
public BackendType getBackendType() {
|
||||
|
|
|
@ -22,10 +22,10 @@ import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
|
|||
* Creating a PartialModel will make the associated modelLocation automatically load.
|
||||
* PartialModels must be initialized the mod class constructor.
|
||||
* <br>
|
||||
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations)
|
||||
* Once {@link ModelEvent.BakingCompleted} finishes, all PartialModels (with valid modelLocations)
|
||||
* will have their bakedModel fields populated.
|
||||
* <br>
|
||||
* Attempting to create a PartialModel after {@link ModelRegistryEvent} will cause an error.
|
||||
* Attempting to create a PartialModel after {@link ModelEvent.RegisterAdditional} will cause an error.
|
||||
*/
|
||||
public class PartialModel {
|
||||
|
||||
|
@ -36,7 +36,7 @@ public class PartialModel {
|
|||
protected BakedModel bakedModel;
|
||||
|
||||
public PartialModel(ResourceLocation modelLocation) {
|
||||
if (tooLate) throw new RuntimeException("PartialModel '" + modelLocation + "' loaded after ModelRegistryEvent");
|
||||
if (tooLate) throw new RuntimeException("PartialModel '" + modelLocation + "' loaded after ModelEvent.RegisterAdditional");
|
||||
|
||||
this.modelLocation = modelLocation;
|
||||
ALL.add(this);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter;
|
||||
import com.jozufozu.flywheel.fabric.model.DefaultLayerFilteringBakedModel;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
|
@ -12,6 +10,7 @@ import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
|||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -42,7 +41,7 @@ public final class BakedModelBuilder implements Bufferable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void bufferInto(ModelBlockRenderer blockRenderer, VertexConsumer consumer, Random random) {
|
||||
public void bufferInto(ModelBlockRenderer blockRenderer, VertexConsumer consumer, RandomSource random) {
|
||||
BakedModel model = DefaultLayerFilteringBakedModel.wrap(this.model);
|
||||
if (consumer instanceof ShadeSeparatingVertexConsumer shadeSeparatingWrapper) {
|
||||
model = shadeSeparatingWrapper.wrapModel(model);
|
||||
|
|
|
@ -1,9 +1,25 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
|
||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
|
||||
import com.jozufozu.flywheel.backend.model.ElementBuffer;
|
||||
import com.jozufozu.flywheel.core.Formats;
|
||||
import com.jozufozu.flywheel.core.QuadConverter;
|
||||
import com.jozufozu.flywheel.util.Pair;
|
||||
import com.mojang.blaze3d.platform.MemoryTracker;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat.IndexType;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
|
@ -16,6 +32,7 @@ public class BlockModel implements Model {
|
|||
|
||||
private final VertexList reader;
|
||||
private final String name;
|
||||
private final EBOSupplier eboSupplier;
|
||||
|
||||
public BlockModel(BlockState state) {
|
||||
this(Minecraft.getInstance()
|
||||
|
@ -36,9 +53,19 @@ public class BlockModel implements Model {
|
|||
this(bufferable.build(), name);
|
||||
}
|
||||
|
||||
public BlockModel(ShadeSeparatedBufferBuilder bufferBuilder, String name) {
|
||||
public BlockModel(Pair<RenderedBuffer, Integer> pair, String name) {
|
||||
this.name = name;
|
||||
reader = Formats.BLOCK.createReader(bufferBuilder);
|
||||
|
||||
RenderedBuffer renderedBuffer = pair.first();
|
||||
BufferBuilder.DrawState drawState = renderedBuffer.drawState();
|
||||
reader = Formats.BLOCK.createReader(renderedBuffer, pair.second());
|
||||
|
||||
if (!drawState.sequentialIndex()) {
|
||||
eboSupplier = new BufferEBOSupplier(renderedBuffer.indexBuffer(), drawState.indexCount(), drawState.indexType());
|
||||
} else {
|
||||
eboSupplier = () -> QuadConverter.getInstance()
|
||||
.quads2Tris(vertexCount() / 4);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,6 +83,11 @@ public class BlockModel implements Model {
|
|||
return reader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementBuffer createEBO() {
|
||||
return eboSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VertexType getType() {
|
||||
return Formats.BLOCK;
|
||||
|
@ -70,5 +102,55 @@ public class BlockModel implements Model {
|
|||
//
|
||||
}
|
||||
}
|
||||
eboSupplier.delete();
|
||||
}
|
||||
|
||||
private interface EBOSupplier extends Supplier<ElementBuffer> {
|
||||
default void delete() {
|
||||
}
|
||||
}
|
||||
|
||||
private static class BufferEBOSupplier implements EBOSupplier {
|
||||
private final ByteBuffer indexBuffer;
|
||||
private final int indexCount;
|
||||
private final IndexType indexType;
|
||||
|
||||
private int eboName = -1;
|
||||
private ElementBuffer ebo;
|
||||
|
||||
public BufferEBOSupplier(ByteBuffer indexBufferSrc, int indexCount, IndexType indexType) {
|
||||
indexBuffer = MemoryTracker.create(indexBufferSrc.capacity());
|
||||
MemoryUtil.memCopy(indexBufferSrc, indexBuffer);
|
||||
this.indexCount = indexCount;
|
||||
this.indexType = indexType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementBuffer get() {
|
||||
if (eboName == -1) {
|
||||
eboName = createEBO();
|
||||
ebo = new ElementBuffer(eboName, indexCount, indexType);
|
||||
MemoryUtil.memFree(indexBuffer);
|
||||
}
|
||||
|
||||
return ebo;
|
||||
}
|
||||
|
||||
private int createEBO() {
|
||||
int vbo = GL32.glGenBuffers();
|
||||
|
||||
// XXX ARRAY_BUFFER is bound and restored
|
||||
var bufferType = GlBufferType.ARRAY_BUFFER;
|
||||
var oldBuffer = bufferType.getBoundBuffer();
|
||||
bufferType.bind(vbo);
|
||||
GL15.glBufferData(bufferType.glEnum, indexBuffer, GlBufferUsage.STATIC_DRAW.glEnum);
|
||||
bufferType.bind(oldBuffer);
|
||||
return vbo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
GL32.glDeleteBuffers(eboName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
|
||||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.jozufozu.flywheel.util.Pair;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
|
||||
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
/**
|
||||
* An interface for objects that can "rendered" into a BufferBuilder.
|
||||
*/
|
||||
public interface Bufferable {
|
||||
void bufferInto(ModelBlockRenderer renderer, VertexConsumer consumer, Random random);
|
||||
void bufferInto(ModelBlockRenderer renderer, VertexConsumer consumer, RandomSource random);
|
||||
|
||||
default ShadeSeparatedBufferBuilder build() {
|
||||
return ModelUtil.getBufferBuilder(this);
|
||||
default Pair<RenderedBuffer, Integer> build() {
|
||||
return ModelUtil.getRenderedBuffer(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.backend.model.BufferBuilderExtension;
|
||||
import com.jozufozu.flywheel.util.Pair;
|
||||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
@ -15,6 +17,7 @@ import net.minecraft.client.renderer.RenderType;
|
|||
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||
|
@ -22,7 +25,18 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
|
|||
public class ModelUtil {
|
||||
private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
|
||||
|
||||
public static ShadeSeparatedBufferBuilder getBufferBuilder(Bufferable bufferable) {
|
||||
public static Pair<RenderedBuffer, Integer> endShadeSeparated(BufferBuilder shadedBuilder, BufferBuilder unshadedBuilder) {
|
||||
int unshadedStartVertex = ((BufferBuilderExtension) shadedBuilder).flywheel$getVertices();
|
||||
RenderedBuffer unshadedBuffer = unshadedBuilder.endOrDiscardIfEmpty();
|
||||
if (unshadedBuffer != null) {
|
||||
// FIXME: Unshaded indices
|
||||
((BufferBuilderExtension) shadedBuilder).flywheel$appendBufferUnsafe(unshadedBuffer.vertexBuffer());
|
||||
}
|
||||
RenderedBuffer buffer = shadedBuilder.end();
|
||||
return Pair.of(buffer, unshadedStartVertex);
|
||||
}
|
||||
|
||||
public static Pair<RenderedBuffer, Integer> getRenderedBuffer(Bufferable bufferable) {
|
||||
ModelBlockRenderer blockRenderer = Minecraft.getInstance().getBlockRenderer().getModelRenderer();
|
||||
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
|
||||
|
||||
|
@ -30,31 +44,29 @@ public class ModelUtil {
|
|||
|
||||
bufferable.bufferInto(blockRenderer, objects.shadeSeparatingWrapper, objects.random);
|
||||
|
||||
objects.end();
|
||||
|
||||
return objects.separatedBufferBuilder;
|
||||
return objects.end();
|
||||
}
|
||||
|
||||
public static ShadeSeparatedBufferBuilder getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack poseStack) {
|
||||
public static Pair<RenderedBuffer, Integer> getBufferBuilder(BakedModel model, BlockState referenceState, PoseStack poseStack) {
|
||||
return new BakedModelBuilder(model).withReferenceState(referenceState)
|
||||
.withPoseStack(poseStack)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ShadeSeparatedBufferBuilder getBufferBuilder(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) {
|
||||
public static Pair<RenderedBuffer, Integer> getBufferBuilder(BlockAndTintGetter renderWorld, BakedModel model, BlockState referenceState, PoseStack poseStack) {
|
||||
return new BakedModelBuilder(model).withReferenceState(referenceState)
|
||||
.withPoseStack(poseStack)
|
||||
.withRenderWorld(renderWorld)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
|
||||
public static Pair<RenderedBuffer, Integer> getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks) {
|
||||
return new WorldModelBuilder(layer).withRenderWorld(renderWorld)
|
||||
.withBlocks(blocks)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ShadeSeparatedBufferBuilder getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, PoseStack poseStack) {
|
||||
public static Pair<RenderedBuffer, Integer> getBufferBuilderFromTemplate(BlockAndTintGetter renderWorld, RenderType layer, Collection<StructureTemplate.StructureBlockInfo> blocks, PoseStack poseStack) {
|
||||
return new WorldModelBuilder(layer).withRenderWorld(renderWorld)
|
||||
.withBlocks(blocks)
|
||||
.withPoseStack(poseStack)
|
||||
|
@ -73,22 +85,20 @@ public class ModelUtil {
|
|||
}
|
||||
|
||||
private static class ThreadLocalObjects {
|
||||
public final Random random = new Random();
|
||||
public final RandomSource random = RandomSource.create();
|
||||
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
|
||||
public final ShadeSeparatedBufferBuilder separatedBufferBuilder = new ShadeSeparatedBufferBuilder(512);
|
||||
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
|
||||
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
|
||||
|
||||
private void begin() {
|
||||
this.separatedBufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
this.shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
this.unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||
this.shadeSeparatingWrapper.prepare(this.separatedBufferBuilder, this.unshadedBuilder);
|
||||
this.shadeSeparatingWrapper.prepare(this.shadedBuilder, this.unshadedBuilder);
|
||||
}
|
||||
|
||||
private void end() {
|
||||
private Pair<RenderedBuffer, Integer> end() {
|
||||
this.shadeSeparatingWrapper.clear();
|
||||
this.unshadedBuilder.end();
|
||||
this.separatedBufferBuilder.appendUnshadedVertices(this.unshadedBuilder);
|
||||
this.separatedBufferBuilder.end();
|
||||
return ModelUtil.endShadeSeparated(shadedBuilder, unshadedBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.jozufozu.flywheel.backend.model.BufferBuilderExtension;
|
||||
import com.jozufozu.flywheel.fabric.helper.BufferBuilderHelper;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
public class ShadeSeparatedBufferBuilder extends BufferBuilder {
|
||||
protected int unshadedStartVertex;
|
||||
|
||||
public ShadeSeparatedBufferBuilder(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
public void appendUnshadedVertices(BufferBuilder unshadedBuilder) {
|
||||
Pair<DrawState, ByteBuffer> data = unshadedBuilder.popNextBuffer();
|
||||
ByteBuffer buffer = data.getSecond();
|
||||
BufferBuilderHelper.fixByteOrder(unshadedBuilder, buffer);
|
||||
unshadedStartVertex = ((BufferBuilderExtension) this).flywheel$getVertices();
|
||||
((BufferBuilderExtension) this).flywheel$appendBufferUnsafe(buffer);
|
||||
}
|
||||
|
||||
public int getUnshadedStartVertex() {
|
||||
return unshadedStartVertex;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.core.model;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.fabric.model.FabricModelUtil;
|
||||
|
@ -13,6 +12,7 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext.QuadTransform;
|
|||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
|
@ -113,7 +113,7 @@ public class ShadeSeparatingVertexConsumer implements VertexConsumer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<RandomSource> randomSupplier, RenderContext context) {
|
||||
context.pushTransform(quadTransform);
|
||||
super.emitBlockQuads(blockView, state, pos, randomSupplier, context);
|
||||
context.popTransform();
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.jozufozu.flywheel.core.model;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import com.jozufozu.flywheel.core.virtual.VirtualEmptyBlockGetter;
|
||||
import com.jozufozu.flywheel.fabric.model.CullingBakedModel;
|
||||
|
@ -19,6 +18,7 @@ import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
|||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -36,7 +36,7 @@ public final class WorldModelBuilder implements Bufferable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void bufferInto(ModelBlockRenderer modelRenderer, VertexConsumer consumer, Random random) {
|
||||
public void bufferInto(ModelBlockRenderer modelRenderer, VertexConsumer consumer, RandomSource random) {
|
||||
BlockRenderDispatcher dispatcher = Minecraft.getInstance().getBlockRenderer();
|
||||
|
||||
ModelBlockRenderer.enableCaching();
|
||||
|
@ -87,6 +87,6 @@ public final class WorldModelBuilder implements Bufferable {
|
|||
}
|
||||
|
||||
public BlockModel intoMesh(String name) {
|
||||
return new BlockModel(ModelUtil.getBufferBuilder(this), name);
|
||||
return new BlockModel(this, name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.jozufozu.flywheel.core.source;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -28,24 +28,25 @@ public class ShaderSources implements SourceFinder {
|
|||
public final Index index;
|
||||
|
||||
public ShaderSources(ResourceManager manager) {
|
||||
Collection<ResourceLocation> allShaders = manager.listResources(SHADER_DIR, s -> {
|
||||
Map<ResourceLocation, Resource> allShaders = manager.listResources(SHADER_DIR, loc -> {
|
||||
String path = loc.getPath();
|
||||
for (String ext : EXTENSIONS) {
|
||||
if (s.endsWith(ext)) return true;
|
||||
if (path.endsWith(ext)) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
for (ResourceLocation location : allShaders) {
|
||||
try (Resource resource = manager.getResource(location)) {
|
||||
String source = StringUtil.readToString(resource.getInputStream());
|
||||
allShaders.forEach((location, resource) -> {
|
||||
try (InputStream inputStream = resource.open()) {
|
||||
String source = StringUtil.readToString(inputStream);
|
||||
|
||||
ResourceLocation name = ResourceUtil.removePrefixUnchecked(location, SHADER_DIR);
|
||||
|
||||
shaderSources.put(name, new SourceFile(this, name, source));
|
||||
} catch (IOException e) {
|
||||
//
|
||||
} catch (IOException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
index = new Index(shaderSources);
|
||||
}
|
||||
|
|
|
@ -6,11 +6,8 @@ import com.jozufozu.flywheel.api.vertex.VertexList;
|
|||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||
import com.jozufozu.flywheel.core.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.core.layout.CommonItems;
|
||||
import com.jozufozu.flywheel.core.model.ShadeSeparatedBufferBuilder;
|
||||
import com.jozufozu.flywheel.fabric.helper.BufferBuilderHelper;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
|
||||
public class BlockVertex implements VertexType {
|
||||
|
||||
|
@ -63,21 +60,21 @@ Vertex FLWCreateVertex() {
|
|||
return new BlockVertexListUnsafe.Shaded(buffer, vertexCount, unshadedStartVertex);
|
||||
}
|
||||
|
||||
public VertexList createReader(BufferBuilder bufferBuilder) {
|
||||
public VertexList createReader(BufferBuilder.RenderedBuffer renderedBuffer, int unshadedStartVertex) {
|
||||
|
||||
// TODO: try to avoid virtual model rendering
|
||||
Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popNextBuffer();
|
||||
BufferBuilder.DrawState drawState = pair.getFirst();
|
||||
BufferBuilder.DrawState drawState = renderedBuffer.drawState();
|
||||
|
||||
if (drawState.format() != DefaultVertexFormat.BLOCK) {
|
||||
throw new RuntimeException("Cannot use BufferBuilder with " + drawState.format());
|
||||
}
|
||||
ByteBuffer vertexBuffer = renderedBuffer.vertexBuffer();
|
||||
|
||||
ByteBuffer buffer = pair.getSecond();
|
||||
BufferBuilderHelper.fixByteOrder(bufferBuilder, buffer);
|
||||
if (bufferBuilder instanceof ShadeSeparatedBufferBuilder separated) {
|
||||
return createReader(buffer, drawState.vertexCount(), separated.getUnshadedStartVertex());
|
||||
int vertexCount = drawState.vertexCount();
|
||||
if (unshadedStartVertex >= 0 && unshadedStartVertex < vertexCount) {
|
||||
return createReader(vertexBuffer, vertexCount, unshadedStartVertex);
|
||||
} else {
|
||||
return createReader(buffer, drawState.vertexCount());
|
||||
return createReader(vertexBuffer, vertexCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ 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.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureStart;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
|
@ -194,39 +194,39 @@ public class VirtualChunk extends ChunkAccess {
|
|||
|
||||
@Override
|
||||
@Nullable
|
||||
public StructureStart getStartForFeature(ConfiguredStructureFeature<?, ?> pStructure) {
|
||||
public StructureStart getStartForStructure(Structure structure) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartForFeature(ConfiguredStructureFeature<?, ?> pStructure, StructureStart pStart) {
|
||||
public void setStartForStructure(Structure structure, StructureStart start) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ConfiguredStructureFeature<?, ?>, StructureStart> getAllStarts() {
|
||||
public Map<Structure, StructureStart> getAllStarts() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllStarts(Map<ConfiguredStructureFeature<?, ?>, StructureStart> pStructureStarts) {
|
||||
public void setAllStarts(Map<Structure, StructureStart> structureStarts) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LongSet getReferencesForFeature(ConfiguredStructureFeature<?, ?> pStructure) {
|
||||
public LongSet getReferencesForStructure(Structure structure) {
|
||||
return LongSets.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addReferenceForFeature(ConfiguredStructureFeature<?, ?> pStructure, long pReference) {
|
||||
public void addReferenceForStructure(Structure structure, long reference) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ConfiguredStructureFeature<?, ?>, LongSet> getAllReferences() {
|
||||
public Map<Structure, LongSet> getAllReferences() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAllReferences(Map<ConfiguredStructureFeature<?, ?>, LongSet> pStructureReferences) {
|
||||
public void setAllReferences(Map<Structure, LongSet> structureReferences) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,10 +36,12 @@ 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.gameevent.GameEvent.Context;
|
||||
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.phys.Vec3;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
import net.minecraft.world.ticks.LevelTickAccess;
|
||||
|
||||
|
@ -68,7 +70,7 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld {
|
|||
|
||||
public VirtualRenderWorld(Level level, Vec3i biomeOffset, int height, int minBuildHeight) {
|
||||
super((WritableLevelData) level.getLevelData(), level.dimension(), level.dimensionTypeRegistration(), level::getProfiler,
|
||||
true, false, 0);
|
||||
true, false, 0, 0);
|
||||
this.biomeOffset = biomeOffset;
|
||||
this.level = level;
|
||||
this.height = nextMultipleOf16(height);
|
||||
|
@ -289,6 +291,17 @@ public class VirtualRenderWorld extends Level implements FlywheelWorld {
|
|||
@Override
|
||||
public void levelEvent(@Nullable Player player, int type, BlockPos pos, int data) {}
|
||||
|
||||
@Override
|
||||
public void gameEvent(GameEvent p_220404_, Vec3 p_220405_, Context p_220406_) {}
|
||||
|
||||
@Override
|
||||
public void playSeededSound(Player p_220363_, double p_220364_, double p_220365_, double p_220366_,
|
||||
SoundEvent p_220367_, SoundSource p_220368_, float p_220369_, float p_220370_, long p_220371_) {}
|
||||
|
||||
@Override
|
||||
public void playSeededSound(Player p_220372_, Entity p_220373_, SoundEvent p_220374_, SoundSource p_220375_,
|
||||
float p_220376_, float p_220377_, long p_220378_) {}
|
||||
|
||||
@Override
|
||||
public void playSound(@Nullable Player player, double x, double y, double z, SoundEvent soundIn,
|
||||
SoundSource category, float volume, float pitch) {}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.fabric.model;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
|
@ -8,6 +7,7 @@ import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
|||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -33,7 +33,7 @@ public class CullingBakedModel extends ForwardingBakedModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<RandomSource> randomSupplier, RenderContext context) {
|
||||
completionFlags = 0;
|
||||
resultFlags = 0;
|
||||
context.pushTransform(quad -> {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.fabric.model;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
|
||||
|
@ -10,6 +9,7 @@ import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
|||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -30,14 +30,14 @@ public class DefaultLayerFilteringBakedModel extends ForwardingBakedModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<RandomSource> randomSupplier, RenderContext context) {
|
||||
context.pushTransform(DefaultLayerFilteringBakedModel::hasDefaultBlendMode);
|
||||
super.emitBlockQuads(blockView, state, pos, randomSupplier, context);
|
||||
context.popTransform();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
public void emitItemQuads(ItemStack stack, Supplier<RandomSource> randomSupplier, RenderContext context) {
|
||||
context.pushTransform(DefaultLayerFilteringBakedModel::hasDefaultBlendMode);
|
||||
super.emitItemQuads(stack, randomSupplier, context);
|
||||
context.popTransform();
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.fabric.model;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
|
@ -9,6 +8,7 @@ import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
|||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class LayerFilteringBakedModel extends ForwardingBakedModel {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier<RandomSource> randomSupplier, RenderContext context) {
|
||||
RenderType defaultLayer = ItemBlockRenderTypes.getChunkRenderType(state);
|
||||
if (super.isVanillaAdapter()) {
|
||||
if (defaultLayer == targetLayer) {
|
||||
|
|
|
@ -1,30 +1,78 @@
|
|||
package com.jozufozu.flywheel.mixin.instancemanage;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
import com.jozufozu.flywheel.util.RenderChunkExtension;
|
||||
|
||||
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunkRegion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
|
||||
public class ChunkRebuildHooksMixin {
|
||||
public abstract class ChunkRebuildHooksMixin {
|
||||
@Unique
|
||||
private Level flywheel$level;
|
||||
|
||||
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
|
||||
private <E extends BlockEntity> void addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set<BlockEntity> set, E be, CallbackInfo ci) {
|
||||
if (Backend.canUseInstancing(be.getLevel())) {
|
||||
if (InstancedRenderRegistry.canInstance(be.getType()))
|
||||
InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be);
|
||||
@Inject(method = "<init>(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;DLnet/minecraft/client/renderer/chunk/RenderChunkRegion;Z)V", at = @At("RETURN"))
|
||||
private void setLevel(ChunkRenderDispatcher.RenderChunk this$1, double p_194427_, RenderChunkRegion region, boolean p_194429_, CallbackInfo ci) {
|
||||
flywheel$level = ((RenderChunkExtension) this$1).flywheel$getLevel();
|
||||
}
|
||||
|
||||
if (InstancedRenderRegistry.shouldSkipRender(be))
|
||||
ci.cancel();
|
||||
@Redirect(method = "doTask", at = @At(value = "INVOKE", target = "Ljava/util/List;addAll(Ljava/util/Collection;)Z"))
|
||||
private <E extends BlockEntity> boolean addAndFilterBEs(List<BlockEntity> self, Collection<? extends E> es) {
|
||||
if (!Backend.canUseInstancing(flywheel$level)) {
|
||||
return self.addAll(es);
|
||||
}
|
||||
|
||||
boolean added = false;
|
||||
var instanced = new ArrayList<BlockEntity>();
|
||||
for (E be : es) {
|
||||
if (InstancedRenderRegistry.canInstance(be.getType())) {
|
||||
instanced.add(be);
|
||||
}
|
||||
|
||||
if (!InstancedRenderRegistry.shouldSkipRender(be)) {
|
||||
self.add(be);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
InstancedRenderDispatcher.getBlockEntities(flywheel$level).queueAddAll(instanced);
|
||||
return added;
|
||||
}
|
||||
|
||||
@Redirect(method = "doTask", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk;updateGlobalBlockEntities(Ljava/util/Collection;)V"))
|
||||
private void addAndFilterBEs(ChunkRenderDispatcher.RenderChunk self, Collection<BlockEntity> bes) {
|
||||
if (!Backend.canUseInstancing(flywheel$level)) {
|
||||
((RenderChunkAccessor) self).flywheel$updateGlobalBlockEntities(bes);
|
||||
return;
|
||||
}
|
||||
|
||||
var global = new ArrayList<BlockEntity>();
|
||||
var instanced = new ArrayList<BlockEntity>();
|
||||
for (BlockEntity be : bes) {
|
||||
if (InstancedRenderRegistry.canInstance(be.getType())) {
|
||||
instanced.add(be);
|
||||
}
|
||||
|
||||
if (!InstancedRenderRegistry.shouldSkipRender(be)) {
|
||||
global.add(be);
|
||||
}
|
||||
}
|
||||
|
||||
InstancedRenderDispatcher.getBlockEntities(flywheel$level).queueAddAll(instanced);
|
||||
((RenderChunkAccessor) self).flywheel$updateGlobalBlockEntities(global);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package com.jozufozu.flywheel.mixin.instancemanage;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
|
||||
|
||||
@Mixin(ChunkRenderDispatcher.class)
|
||||
public interface ChunkRenderDispatcherAccessor {
|
||||
|
||||
@Accessor
|
||||
ClientLevel getLevel();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.jozufozu.flywheel.mixin.instancemanage;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
/**
|
||||
* For use in {@link ChunkRebuildHooksMixin#addAndFilterBEs(ChunkRenderDispatcher.RenderChunk, Collection)}
|
||||
*/
|
||||
@Mixin(ChunkRenderDispatcher.RenderChunk.class)
|
||||
public interface RenderChunkAccessor {
|
||||
|
||||
@Invoker("updateGlobalBlockEntities")
|
||||
void flywheel$updateGlobalBlockEntities(Collection<BlockEntity> blockEntities);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.jozufozu.flywheel.mixin.instancemanage;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
|
||||
|
||||
@Mixin(ChunkRenderDispatcher.RenderChunk.class)
|
||||
public class RenderChunkMixin implements com.jozufozu.flywheel.util.RenderChunkExtension {
|
||||
|
||||
@Shadow(aliases = {"this$0", "field_20833", "f_dssekupm"}) // Optifine does not use the obfuscated name so the mapped name must be included as an alias
|
||||
@Final
|
||||
private ChunkRenderDispatcher this$0;
|
||||
|
||||
@Override
|
||||
public ClientLevel flywheel$getLevel() {
|
||||
return ((ChunkRenderDispatcherAccessor) this$0).getLevel();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.jozufozu.flywheel.mixin.instancemanage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||
|
||||
import me.jellysquid.mods.sodium.client.render.chunk.data.ChunkRenderData;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
|
||||
@Mixin(targets = "me.jellysquid.mods.sodium.client.render.chunk.data.ChunkRenderData$Builder", remap = false)
|
||||
public class SodiumChunkRenderDataMixin {
|
||||
|
||||
@Unique
|
||||
private List<BlockEntity> flywheel$blockEntities;
|
||||
@Unique
|
||||
private Level flywheel$level;
|
||||
|
||||
@Inject(method = "addBlockEntity", at = @At("HEAD"), cancellable = true, require = 0)
|
||||
private void flywheel$onAddBlockEntity(BlockEntity be, boolean cull, CallbackInfo ci) {
|
||||
if (flywheel$level == null) {
|
||||
flywheel$level = be.getLevel();
|
||||
}
|
||||
|
||||
if (!Backend.canUseInstancing(flywheel$level)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (InstancedRenderRegistry.canInstance(be.getType())) {
|
||||
if (flywheel$blockEntities == null) {
|
||||
flywheel$blockEntities = new ArrayList<>();
|
||||
}
|
||||
|
||||
// Collect BEs in a temporary list to avoid excessive synchronization in InstancedRenderDispatcher.
|
||||
flywheel$blockEntities.add(be);
|
||||
}
|
||||
|
||||
if (InstancedRenderRegistry.shouldSkipRender(be)) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "build", at = @At("HEAD"))
|
||||
private void flywheel$onBuild(CallbackInfoReturnable<ChunkRenderData> cir) {
|
||||
if (flywheel$level == null || flywheel$blockEntities == null || !Backend.canUseInstancing(flywheel$level)) {
|
||||
return;
|
||||
}
|
||||
|
||||
InstancedRenderDispatcher.getBlockEntities(flywheel$level)
|
||||
.queueAddAll(flywheel$blockEntities);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package com.jozufozu.flywheel.util;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
|
||||
public interface RenderChunkExtension {
|
||||
ClientLevel flywheel$getLevel();
|
||||
}
|
|
@ -33,7 +33,7 @@
|
|||
"depends": {
|
||||
"fabricloader": ">=0.11.3",
|
||||
"fabric": "*",
|
||||
"minecraft": ">=1.18.2",
|
||||
"minecraft": ">=1.19.2",
|
||||
"java": ">=17"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,12 @@
|
|||
"atlas.AtlasDataMixin",
|
||||
"atlas.SheetDataAccessor",
|
||||
"instancemanage.ChunkRebuildHooksMixin",
|
||||
"instancemanage.ChunkRenderDispatcherAccessor",
|
||||
"instancemanage.InstanceAddMixin",
|
||||
"instancemanage.InstanceRemoveMixin",
|
||||
"instancemanage.RenderChunkAccessor",
|
||||
"instancemanage.RenderChunkMixin",
|
||||
"instancemanage.SodiumChunkRenderDataMixin",
|
||||
"light.LightUpdateMixin",
|
||||
"light.NetworkLightUpdateMixin",
|
||||
"matrix.Matrix3fMixin",
|
||||
|
|
Loading…
Reference in a new issue