mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-06 18:24:59 +01:00
More clean up
This commit is contained in:
parent
945ed9a1e4
commit
72b5968305
118 changed files with 899 additions and 953 deletions
|
@ -3,7 +3,9 @@ package com.jozufozu.flywheel;
|
||||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.Backends;
|
||||||
import com.jozufozu.flywheel.backend.Loader;
|
import com.jozufozu.flywheel.backend.Loader;
|
||||||
|
import com.jozufozu.flywheel.backend.Pipelines;
|
||||||
import com.jozufozu.flywheel.backend.engine.batching.DrawBuffer;
|
import com.jozufozu.flywheel.backend.engine.batching.DrawBuffer;
|
||||||
import com.jozufozu.flywheel.config.BackendArgument;
|
import com.jozufozu.flywheel.config.BackendArgument;
|
||||||
import com.jozufozu.flywheel.config.FlwCommands;
|
import com.jozufozu.flywheel.config.FlwCommands;
|
||||||
|
@ -14,14 +16,12 @@ import com.jozufozu.flywheel.impl.BackendManagerImpl;
|
||||||
import com.jozufozu.flywheel.impl.IdRegistryImpl;
|
import com.jozufozu.flywheel.impl.IdRegistryImpl;
|
||||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||||
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.lib.backend.Backends;
|
|
||||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||||
import com.jozufozu.flywheel.lib.format.Formats;
|
import com.jozufozu.flywheel.lib.format.Formats;
|
||||||
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
||||||
import com.jozufozu.flywheel.lib.material.Materials;
|
import com.jozufozu.flywheel.lib.material.Materials;
|
||||||
import com.jozufozu.flywheel.lib.model.Models;
|
import com.jozufozu.flywheel.lib.model.Models;
|
||||||
import com.jozufozu.flywheel.lib.model.PartialModel;
|
import com.jozufozu.flywheel.lib.model.PartialModel;
|
||||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
|
||||||
import com.jozufozu.flywheel.lib.struct.StructTypes;
|
import com.jozufozu.flywheel.lib.struct.StructTypes;
|
||||||
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
||||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||||
|
@ -36,7 +36,6 @@ import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.eventbus.api.EventPriority;
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
import net.minecraftforge.eventbus.api.IEventBus;
|
||||||
import net.minecraftforge.fml.CrashReportCallables;
|
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import net.minecraftforge.fml.IExtensionPoint;
|
import net.minecraftforge.fml.IExtensionPoint;
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
|
@ -47,7 +46,6 @@ import net.minecraftforge.network.NetworkConstants;
|
||||||
|
|
||||||
@Mod(Flywheel.ID)
|
@Mod(Flywheel.ID)
|
||||||
public class Flywheel {
|
public class Flywheel {
|
||||||
|
|
||||||
public static final String ID = "flywheel";
|
public static final String ID = "flywheel";
|
||||||
public static final Logger LOGGER = LogUtils.getLogger();
|
public static final Logger LOGGER = LogUtils.getLogger();
|
||||||
private static ArtifactVersion version;
|
private static ArtifactVersion version;
|
||||||
|
@ -78,11 +76,12 @@ public class Flywheel {
|
||||||
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
||||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||||
|
|
||||||
|
forgeEventBus.addListener(BackendManagerImpl::onReloadRenderers);
|
||||||
|
|
||||||
forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onReloadRenderers);
|
forgeEventBus.addListener(EventPriority.HIGHEST, QuadConverter::onReloadRenderers);
|
||||||
forgeEventBus.addListener(Models::onReloadRenderers);
|
forgeEventBus.addListener(Models::onReloadRenderers);
|
||||||
forgeEventBus.addListener(DrawBuffer::onReloadRenderers);
|
forgeEventBus.addListener(DrawBuffer::onReloadRenderers);
|
||||||
|
|
||||||
forgeEventBus.addListener(InstancedRenderDispatcher::onReloadRenderers);
|
|
||||||
forgeEventBus.addListener(InstancedRenderDispatcher::onRenderStage);
|
forgeEventBus.addListener(InstancedRenderDispatcher::onRenderStage);
|
||||||
forgeEventBus.addListener(InstancedRenderDispatcher::onBeginFrame);
|
forgeEventBus.addListener(InstancedRenderDispatcher::onBeginFrame);
|
||||||
forgeEventBus.addListener(InstancedRenderDispatcher::tick);
|
forgeEventBus.addListener(InstancedRenderDispatcher::tick);
|
||||||
|
@ -100,23 +99,23 @@ public class Flywheel {
|
||||||
// forgeEventBus.addListener(ExampleEffect::tick);
|
// forgeEventBus.addListener(ExampleEffect::tick);
|
||||||
// forgeEventBus.addListener(ExampleEffect::onReload);
|
// forgeEventBus.addListener(ExampleEffect::onReload);
|
||||||
|
|
||||||
ShadersModHandler.init();
|
BackendManagerImpl.init();
|
||||||
|
|
||||||
|
Pipelines.init();
|
||||||
Backends.init();
|
Backends.init();
|
||||||
Loader.init();
|
Loader.init();
|
||||||
|
|
||||||
|
ShadersModHandler.init();
|
||||||
|
|
||||||
Formats.init();
|
Formats.init();
|
||||||
StructTypes.init();
|
StructTypes.init();
|
||||||
Materials.init();
|
Materials.init();
|
||||||
Contexts.init();
|
Contexts.init();
|
||||||
Pipelines.init();
|
|
||||||
|
|
||||||
MaterialIndices.init();
|
MaterialIndices.init();
|
||||||
|
|
||||||
VanillaInstances.init();
|
VanillaInstances.init();
|
||||||
|
|
||||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManagerImpl::getBackendNameForCrashReport);
|
|
||||||
|
|
||||||
// https://github.com/Jozufozu/Flywheel/issues/69
|
// https://github.com/Jozufozu/Flywheel/issues/69
|
||||||
// Weird issue with accessor loading.
|
// Weird issue with accessor loading.
|
||||||
// Only thing I've seen that's close to a fix is to force the class to load before trying to use it.
|
// Only thing I've seen that's close to a fix is to force the class to load before trying to use it.
|
||||||
|
|
|
@ -17,9 +17,8 @@ public final class BackendManager {
|
||||||
return BackendManagerImpl.isOn();
|
return BackendManagerImpl.isOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: definitively sort existing calls to this method into API (include behavior in javadoc) or default backend code
|
public static Backend getOffBackend() {
|
||||||
public static void refresh() {
|
return BackendManagerImpl.getOffBackend();
|
||||||
BackendManagerImpl.refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Backend getDefaultBackend() {
|
public static Backend getDefaultBackend() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.api.event;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.joml.FrustumIntersection;
|
import org.joml.FrustumIntersection;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.MatrixUtil;
|
import com.jozufozu.flywheel.lib.math.MatrixUtil;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.api.instance;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package com.jozufozu.flywheel.api.instance;
|
||||||
|
|
||||||
import org.joml.FrustumIntersection;
|
import org.joml.FrustumIntersection;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface giving {@link Instance}s a hook to have a function called at
|
* An interface giving {@link Instance}s a hook to have a function called at
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.api.instance;
|
package com.jozufozu.flywheel.api.instance;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface giving {@link Instance}s a hook to have a function called at
|
* An interface giving {@link Instance}s a hook to have a function called at
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.api.instancer;
|
package com.jozufozu.flywheel.api.instancer;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instancer is how you interact with an instanced model.
|
* An instancer is how you interact with an instanced model.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.api.instancer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
|
||||||
public interface InstancerProvider {
|
public interface InstancerProvider {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package com.jozufozu.flywheel.api.material;
|
package com.jozufozu.flywheel.api.material;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.registry.Registry;
|
import com.jozufozu.flywheel.api.registry.Registry;
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
|
||||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
@ -21,9 +19,5 @@ public interface Material {
|
||||||
|
|
||||||
RenderType getBatchingRenderType();
|
RenderType getBatchingRenderType();
|
||||||
|
|
||||||
VertexTransformer getVertexTransformer();
|
MaterialVertexTransformer getVertexTransformer();
|
||||||
|
|
||||||
interface VertexTransformer {
|
|
||||||
void transform(MutableVertexList vertexList, ClientLevel level);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.jozufozu.flywheel.api.material;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
|
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
|
public interface MaterialVertexTransformer {
|
||||||
|
void transform(MutableVertexList vertexList, ClientLevel level);
|
||||||
|
}
|
|
@ -5,13 +5,11 @@ import org.joml.Vector4fc;
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.gl.buffer.ElementBuffer;
|
import com.jozufozu.flywheel.gl.buffer.ElementBuffer;
|
||||||
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A holder for arbitrary vertex data that can be written to memory or a vertex list.
|
* A holder for arbitrary vertex data that can be written to memory or a vertex list.
|
||||||
*/
|
*/
|
||||||
public interface Mesh {
|
public interface Mesh {
|
||||||
|
|
||||||
VertexType getVertexType();
|
VertexType getVertexType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,18 +48,9 @@ public interface Mesh {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an element buffer object that indexes the vertices of this mesh.
|
* Create an element buffer object that indexes the vertices of this mesh.
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Very often models in minecraft are made up of sequential quads, which is a very predictable pattern.
|
|
||||||
* The default implementation accommodates this, however this can be overridden to change the behavior and
|
|
||||||
* support more complex models.
|
|
||||||
* </p>
|
|
||||||
* @return an element buffer object indexing this model's vertices.
|
* @return an element buffer object indexing this model's vertices.
|
||||||
*/
|
*/
|
||||||
default ElementBuffer createEBO() {
|
ElementBuffer createEBO();
|
||||||
return QuadConverter.getInstance()
|
|
||||||
.quads2Tris(getVertexCount() / 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector4fc getBoundingSphere();
|
Vector4fc getBoundingSphere();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.jozufozu.flywheel.api.instancer;
|
package com.jozufozu.flywheel.api.struct;
|
||||||
|
|
||||||
public interface Handle {
|
public interface Handle {
|
||||||
|
|
||||||
void setChanged();
|
void setChanged();
|
||||||
|
|
||||||
void setDeleted();
|
void setDeleted();
|
|
@ -1,6 +1,4 @@
|
||||||
package com.jozufozu.flywheel.api.instancer;
|
package com.jozufozu.flywheel.api.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
|
||||||
|
|
||||||
public interface InstancePart {
|
public interface InstancePart {
|
||||||
StructType<?> type();
|
StructType<?> type();
|
|
@ -1,13 +1,9 @@
|
||||||
package com.jozufozu.flywheel.api.struct;
|
package com.jozufozu.flywheel.api.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
import com.jozufozu.flywheel.api.registry.Registry;
|
import com.jozufozu.flywheel.api.registry.Registry;
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
|
||||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
import com.jozufozu.flywheel.impl.RegistryImpl;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,10 +29,5 @@ public interface StructType<P extends InstancePart> {
|
||||||
|
|
||||||
ResourceLocation instanceShader();
|
ResourceLocation instanceShader();
|
||||||
|
|
||||||
VertexTransformer<P> getVertexTransformer();
|
StructVertexTransformer<P> getVertexTransformer();
|
||||||
|
|
||||||
interface VertexTransformer<P extends InstancePart> {
|
|
||||||
void transform(MutableVertexList vertexList, P struct, ClientLevel level);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.jozufozu.flywheel.api.struct;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
|
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
|
public interface StructVertexTransformer<P extends InstancePart> {
|
||||||
|
void transform(MutableVertexList vertexList, P struct, ClientLevel level);
|
||||||
|
}
|
|
@ -1,14 +1,11 @@
|
||||||
package com.jozufozu.flywheel.api.struct;
|
package com.jozufozu.flywheel.api.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StructWriters can quickly consume many instances of S and write them to some memory address.
|
* StructWriters can quickly consume many instances and write them to some memory address.
|
||||||
*/
|
*/
|
||||||
public interface StructWriter<P extends InstancePart> {
|
public interface StructWriter<P extends InstancePart> {
|
||||||
/**
|
/**
|
||||||
* Write the given struct to the given memory address.
|
* Write the given struct to the given memory address.
|
||||||
*/
|
*/
|
||||||
void write(final long ptr, final P struct);
|
void write(final long ptr, final P struct);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ package com.jozufozu.flywheel.api.vertex;
|
||||||
* VertexList assumes nothing about the layout of the vertices. Implementations should feel free to return constants
|
* VertexList assumes nothing about the layout of the vertices. Implementations should feel free to return constants
|
||||||
* for values that are unused in their layout.
|
* for values that are unused in their layout.
|
||||||
* </p>
|
* </p>
|
||||||
* TODO: more flexible elements?
|
|
||||||
*/
|
*/
|
||||||
public interface VertexList {
|
public interface VertexList {
|
||||||
float x(int index);
|
float x(int index);
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.FlywheelLevel;
|
|
||||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
|
||||||
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
|
||||||
|
|
||||||
public class BackendUtil {
|
|
||||||
private static ParallelTaskExecutor executor;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a thread pool for running Flywheel related work in parallel.
|
|
||||||
* @return A global Flywheel thread pool.
|
|
||||||
*/
|
|
||||||
public static ParallelTaskExecutor getTaskExecutor() {
|
|
||||||
if (executor == null) {
|
|
||||||
executor = new ParallelTaskExecutor("Flywheel");
|
|
||||||
executor.startWorkers();
|
|
||||||
}
|
|
||||||
|
|
||||||
return executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Contract("null -> false")
|
|
||||||
public static boolean canUseInstancing(@Nullable LevelAccessor level) {
|
|
||||||
return BackendManager.isOn() && isFlywheelLevel(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to avoid calling Flywheel functions on (fake) levels that don't specifically support it.
|
|
||||||
*/
|
|
||||||
public static boolean isFlywheelLevel(@Nullable LevelAccessor level) {
|
|
||||||
if (level == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!level.isClientSide()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level instanceof FlywheelLevel flywheelLevel && flywheelLevel.supportsFlywheel()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return level == Minecraft.getInstance().level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isGameActive() {
|
|
||||||
return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.lib.backend;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.backend.Backend;
|
import com.jozufozu.flywheel.api.backend.Backend;
|
||||||
|
@ -6,30 +6,20 @@ import com.jozufozu.flywheel.backend.engine.batching.BatchingEngine;
|
||||||
import com.jozufozu.flywheel.backend.engine.indirect.IndirectEngine;
|
import com.jozufozu.flywheel.backend.engine.indirect.IndirectEngine;
|
||||||
import com.jozufozu.flywheel.backend.engine.instancing.InstancingEngine;
|
import com.jozufozu.flywheel.backend.engine.instancing.InstancingEngine;
|
||||||
import com.jozufozu.flywheel.gl.versioned.GlCompat;
|
import com.jozufozu.flywheel.gl.versioned.GlCompat;
|
||||||
|
import com.jozufozu.flywheel.lib.backend.SimpleBackend;
|
||||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
|
||||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
|
||||||
public class Backends {
|
public class Backends {
|
||||||
public static final Backend OFF = SimpleBackend.builder()
|
|
||||||
.engineMessage(new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED))
|
|
||||||
.engineFactory(level -> {
|
|
||||||
throw new IllegalStateException("Cannot create engine when backend is off.");
|
|
||||||
})
|
|
||||||
.fallback(() -> Backends.OFF)
|
|
||||||
.supported(() -> true)
|
|
||||||
.register(Flywheel.rl("off"));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use a thread pool to buffer instances in parallel on the CPU.
|
* Use a thread pool to buffer instances in parallel on the CPU.
|
||||||
*/
|
*/
|
||||||
public static final Backend BATCHING = SimpleBackend.builder()
|
public static final Backend BATCHING = SimpleBackend.builder()
|
||||||
.engineMessage(new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN))
|
.engineMessage(new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN))
|
||||||
.engineFactory(level -> new BatchingEngine())
|
.engineFactory(level -> new BatchingEngine())
|
||||||
.fallback(() -> Backends.OFF)
|
|
||||||
.supported(() -> !ShadersModHandler.isShaderPackInUse())
|
.supported(() -> !ShadersModHandler.isShaderPackInUse())
|
||||||
.register(Flywheel.rl("batching"));
|
.register(Flywheel.rl("batching"));
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package com.jozufozu.flywheel.backend;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
||||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||||
import com.jozufozu.flywheel.glsl.error.ErrorReporter;
|
import com.jozufozu.flywheel.glsl.error.ErrorReporter;
|
||||||
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.impl.BackendManagerImpl;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
|
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
|
||||||
|
@ -27,8 +25,6 @@ public class Loader implements ResourceManagerReloadListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResourceManagerReload(ResourceManager manager) {
|
public void onResourceManagerReload(ResourceManager manager) {
|
||||||
BackendManager.refresh();
|
|
||||||
|
|
||||||
var errorReporter = new ErrorReporter();
|
var errorReporter = new ErrorReporter();
|
||||||
ShaderSources sources = new ShaderSources(errorReporter, manager);
|
ShaderSources sources = new ShaderSources(errorReporter, manager);
|
||||||
|
|
||||||
|
@ -38,14 +34,12 @@ public class Loader implements ResourceManagerReloadListener {
|
||||||
|
|
||||||
FlwCompiler.INSTANCE = new FlwCompiler(sources);
|
FlwCompiler.INSTANCE = new FlwCompiler(sources);
|
||||||
|
|
||||||
ClientLevel level = Minecraft.getInstance().level;
|
// TODO: Move this to the impl package
|
||||||
if (level != null) {
|
BackendManagerImpl.refresh(Minecraft.getInstance().level);
|
||||||
InstancedRenderDispatcher.resetInstanceWorld(level);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// Can be null when running datagenerators due to the unfortunate time we call this
|
// Can be null when running data generators due to the unfortunate time we call this
|
||||||
Minecraft minecraft = Minecraft.getInstance();
|
Minecraft minecraft = Minecraft.getInstance();
|
||||||
if (minecraft == null) {
|
if (minecraft == null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package com.jozufozu.flywheel.lib.pipeline;
|
package com.jozufozu.flywheel.backend;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.engine.indirect.IndirectComponent;
|
import com.jozufozu.flywheel.backend.engine.indirect.IndirectComponent;
|
||||||
import com.jozufozu.flywheel.backend.engine.instancing.InstancedArraysComponent;
|
import com.jozufozu.flywheel.backend.engine.instancing.InstancedArraysComponent;
|
||||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||||
|
import com.jozufozu.flywheel.lib.pipeline.SimplePipeline;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
@ -22,7 +23,6 @@ public class Pipelines {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Files {
|
public static class Files {
|
|
@ -17,6 +17,7 @@ import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
|
import com.jozufozu.flywheel.backend.Pipelines;
|
||||||
import com.jozufozu.flywheel.backend.engine.indirect.IndirectComponent;
|
import com.jozufozu.flywheel.backend.engine.indirect.IndirectComponent;
|
||||||
import com.jozufozu.flywheel.gl.GLSLVersion;
|
import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||||
|
@ -27,7 +28,6 @@ import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||||
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
||||||
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
||||||
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
||||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
|
||||||
import com.jozufozu.flywheel.util.StringUtil;
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
|
|
||||||
public class FlwCompiler {
|
public class FlwCompiler {
|
||||||
|
|
|
@ -13,7 +13,6 @@ import com.jozufozu.flywheel.gl.GLSLVersion;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlShader;
|
import com.jozufozu.flywheel.gl.shader.GlShader;
|
||||||
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.gl.shader.ShaderType;
|
||||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
|
||||||
|
|
||||||
public class ShaderCompiler {
|
public class ShaderCompiler {
|
||||||
private final Map<ShaderKey, CompilationResult> shaderCache = new HashMap<>();
|
private final Map<ShaderKey, CompilationResult> shaderCache = new HashMap<>();
|
||||||
|
@ -87,7 +86,7 @@ public class ShaderCompiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private Consumer<FailedCompilation> errorConsumer = FlwUtil::noop;
|
private Consumer<FailedCompilation> errorConsumer = error -> {};
|
||||||
private CompilationFactory factory = Compilation::new;
|
private CompilationFactory factory = Compilation::new;
|
||||||
private Includer includer = RecursiveIncluder.INSTANCE;
|
private Includer includer = RecursiveIncluder.INSTANCE;
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,12 @@ package com.jozufozu.flywheel.backend.engine;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
|
||||||
public abstract class AbstractInstancer<P extends InstancePart> implements Instancer<P> {
|
public abstract class AbstractInstancer<P extends InstancePart> implements Instancer<P> {
|
||||||
|
|
||||||
public final StructType<P> type;
|
public final StructType<P> type;
|
||||||
|
|
||||||
// Lock for all instance data, only needs to be used in methods that may run on the TaskExecutor.
|
// Lock for all instance data, only needs to be used in methods that may run on the TaskExecutor.
|
||||||
|
@ -42,30 +40,33 @@ public abstract class AbstractInstancer<P extends InstancePart> implements Insta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear all instance data without freeing resources.
|
|
||||||
*/
|
|
||||||
public void clear() {
|
|
||||||
handles.forEach(HandleImpl::clear);
|
|
||||||
data.clear();
|
|
||||||
handles.clear();
|
|
||||||
changed.clear();
|
|
||||||
deleted.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInstanceCount() {
|
public int getInstanceCount() {
|
||||||
return data.size();
|
return data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<P> getRange(int start, int end) {
|
public void notifyDirty(int index) {
|
||||||
return data.subList(start, end);
|
if (index < 0 || index >= getInstanceCount()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (lock) {
|
||||||
|
changed.set(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<P> getAll() {
|
public void notifyRemoval(int index) {
|
||||||
return data;
|
if (index < 0 || index >= getInstanceCount()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (lock) {
|
||||||
|
deleted.set(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeDeletedInstances() {
|
protected void removeDeletedInstances() {
|
||||||
|
if (deleted.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out which elements are to be removed.
|
// Figure out which elements are to be removed.
|
||||||
final int oldSize = this.data.size();
|
final int oldSize = this.data.size();
|
||||||
int removeCount = deleted.cardinality();
|
int removeCount = deleted.cardinality();
|
||||||
|
@ -95,26 +96,19 @@ public abstract class AbstractInstancer<P extends InstancePart> implements Insta
|
||||||
.clear();
|
.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all instance data without freeing resources.
|
||||||
|
*/
|
||||||
|
public void clear() {
|
||||||
|
handles.forEach(HandleImpl::clear);
|
||||||
|
data.clear();
|
||||||
|
handles.clear();
|
||||||
|
changed.clear();
|
||||||
|
deleted.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Instancer[" + getInstanceCount() + ']';
|
return "AbstractInstancer[" + getInstanceCount() + ']';
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyDirty(int index) {
|
|
||||||
if (index < 0 || index >= getInstanceCount()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
synchronized (lock) {
|
|
||||||
changed.set(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyRemoval(int index) {
|
|
||||||
if (index < 0 || index >= getInstanceCount()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
synchronized (lock) {
|
|
||||||
deleted.set(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package com.jozufozu.flywheel.backend.engine;
|
package com.jozufozu.flywheel.backend.engine;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
import com.jozufozu.flywheel.api.struct.Handle;
|
||||||
|
|
||||||
public class HandleImpl implements Handle {
|
public class HandleImpl implements Handle {
|
||||||
|
|
||||||
private final AbstractInstancer<?> instancer;
|
private final AbstractInstancer<?> instancer;
|
||||||
private int index;
|
private int index;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.jozufozu.flywheel.backend.engine;
|
package com.jozufozu.flywheel.backend.engine;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
|
||||||
public record InstancerKey<P extends InstancePart>(StructType<P> type, Model model, RenderStage stage) {
|
public record InstancerKey<P extends InstancePart>(StructType<P> type, Model model, RenderStage stage) {
|
||||||
|
|
|
@ -10,9 +10,9 @@ import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
|
||||||
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||||
|
import com.jozufozu.flywheel.lib.math.MoreMath;
|
||||||
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
|
||||||
|
|
||||||
public class UniformBuffer {
|
public class UniformBuffer {
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ public class UniformBuffer {
|
||||||
var builder = ImmutableList.<LiveProvider>builder();
|
var builder = ImmutableList.<LiveProvider>builder();
|
||||||
int totalBytes = 0;
|
int totalBytes = 0;
|
||||||
for (ShaderUniforms provider : providers) {
|
for (ShaderUniforms provider : providers) {
|
||||||
int size = FlwUtil.align16(provider.byteSize());
|
int size = MoreMath.align16(provider.byteSize());
|
||||||
|
|
||||||
builder.add(new LiveProvider(provider, totalBytes, size));
|
builder.add(new LiveProvider(provider, totalBytes, size));
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,10 @@ public class BatchedMeshPool {
|
||||||
growthMargin = vertexFormat.getVertexSize() * 32;
|
growthMargin = vertexFormat.getVertexSize() * 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VertexFormat getVertexFormat() {
|
||||||
|
return vertexFormat;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a mesh in the arena.
|
* Allocate a mesh in the arena.
|
||||||
*
|
*
|
||||||
|
@ -139,10 +143,6 @@ public class BatchedMeshPool {
|
||||||
pendingUpload.clear();
|
pendingUpload.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VertexFormat getVertexFormat() {
|
|
||||||
return vertexFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "BatchedMeshPool{" + "vertexFormat=" + vertexFormat + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
|
return "BatchedMeshPool{" + "vertexFormat=" + vertexFormat + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
|
||||||
|
|
|
@ -5,9 +5,9 @@ import java.util.List;
|
||||||
import com.jozufozu.flywheel.api.backend.Engine;
|
import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
|
|
|
@ -15,10 +15,10 @@ import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.ImmutableListMultimap;
|
import com.google.common.collect.ImmutableListMultimap;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
@ -83,7 +83,7 @@ public class BatchingTransformManager {
|
||||||
var meshes = model.getMeshes();
|
var meshes = model.getMeshes();
|
||||||
for (var entry : meshes.entrySet()) {
|
for (var entry : meshes.entrySet()) {
|
||||||
var material = entry.getKey();
|
var material = entry.getKey();
|
||||||
var renderType = material.getBatchingRenderType();
|
RenderType renderType = material.getBatchingRenderType();
|
||||||
TransformCall<?> transformCall = new TransformCall<>(instancer, material, alloc(entry.getValue(), renderType.format()));
|
TransformCall<?> transformCall = new TransformCall<>(instancer, material, alloc(entry.getValue(), renderType.format()));
|
||||||
transformSet.put(renderType, transformCall);
|
transformSet.put(renderType, transformCall);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,25 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.batching;
|
package com.jozufozu.flywheel.backend.engine.batching;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
|
|
||||||
public class CPUInstancer<P extends InstancePart> extends AbstractInstancer<P> {
|
public class CPUInstancer<P extends InstancePart> extends AbstractInstancer<P> {
|
||||||
|
|
||||||
public CPUInstancer(StructType<P> type) {
|
public CPUInstancer(StructType<P> type) {
|
||||||
super(type);
|
super(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update() {
|
public List<P> getRange(int start, int end) {
|
||||||
if (!deleted.isEmpty()) {
|
return data.subList(start, end);
|
||||||
removeDeletedInstances();
|
}
|
||||||
}
|
|
||||||
|
public List<P> getAll() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
removeDeletedInstances();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class DrawBuffer {
|
||||||
private boolean prepared;
|
private boolean prepared;
|
||||||
private int vertexCount;
|
private int vertexCount;
|
||||||
|
|
||||||
DrawBuffer(RenderType renderType, VertexFormat format, int stride, VertexListProvider provider) {
|
public DrawBuffer(RenderType renderType, VertexFormat format, int stride, VertexListProvider provider) {
|
||||||
this.renderType = renderType;
|
this.renderType = renderType;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.stride = stride;
|
this.stride = stride;
|
||||||
|
|
|
@ -3,8 +3,6 @@ package com.jozufozu.flywheel.backend.engine.batching;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexListProviderRegistry;
|
import com.jozufozu.flywheel.api.vertex.VertexListProviderRegistry;
|
||||||
|
@ -20,7 +18,6 @@ public class DrawBufferSet {
|
||||||
|
|
||||||
private final Map<RenderStage, DrawBuffer> buffers = new EnumMap<>(RenderStage.class);
|
private final Map<RenderStage, DrawBuffer> buffers = new EnumMap<>(RenderStage.class);
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public DrawBufferSet(RenderType renderType) {
|
public DrawBufferSet(RenderType renderType) {
|
||||||
this.renderType = renderType;
|
this.renderType = renderType;
|
||||||
format = renderType.format();
|
format = renderType.format();
|
||||||
|
|
|
@ -2,17 +2,16 @@ package com.jozufozu.flywheel.backend.engine.batching;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructVertexTransformer;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
|
import com.jozufozu.flywheel.lib.vertex.VertexTransformations;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Matrix3f;
|
import com.mojang.math.Matrix3f;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
import com.mojang.math.Vector3f;
|
|
||||||
import com.mojang.math.Vector4f;
|
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
|
@ -37,11 +36,11 @@ public class TransformCall<P extends InstancePart> {
|
||||||
return meshVertexCount * instancer.getInstanceCount();
|
return meshVertexCount * instancer.getInstanceCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
public void setup() {
|
||||||
instancer.update();
|
instancer.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void submitTasks(TaskExecutor executor, DrawBuffer buffer, int startVertex, PoseStack.Pose matrices, ClientLevel level) {
|
public void submitTasks(TaskExecutor executor, DrawBuffer buffer, int startVertex, PoseStack.Pose matrices, ClientLevel level) {
|
||||||
int instances = instancer.getInstanceCount();
|
int instances = instancer.getInstanceCount();
|
||||||
|
|
||||||
while (instances > 0) {
|
while (instances > 0) {
|
||||||
|
@ -57,21 +56,21 @@ public class TransformCall<P extends InstancePart> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transformRange(ReusableVertexList vertexList, int from, int to, PoseStack.Pose matrices, ClientLevel level) {
|
public void transformRange(ReusableVertexList vertexList, int from, int to, PoseStack.Pose matrices, ClientLevel level) {
|
||||||
transformList(vertexList, instancer.getRange(from, to), matrices, level);
|
transformList(vertexList, instancer.getRange(from, to), matrices, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transformAll(ReusableVertexList vertexList, PoseStack.Pose matrices, ClientLevel level) {
|
public void transformAll(ReusableVertexList vertexList, PoseStack.Pose matrices, ClientLevel level) {
|
||||||
transformList(vertexList, instancer.getAll(), matrices, level);
|
transformList(vertexList, instancer.getAll(), matrices, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transformList(ReusableVertexList vertexList, List<P> parts, PoseStack.Pose matrices, ClientLevel level) {
|
public void transformList(ReusableVertexList vertexList, List<P> parts, PoseStack.Pose matrices, ClientLevel level) {
|
||||||
long anchorPtr = vertexList.ptr();
|
long anchorPtr = vertexList.ptr();
|
||||||
int totalVertexCount = vertexList.vertexCount();
|
int totalVertexCount = vertexList.vertexCount();
|
||||||
|
|
||||||
vertexList.vertexCount(meshVertexCount);
|
vertexList.vertexCount(meshVertexCount);
|
||||||
|
|
||||||
StructType.VertexTransformer<P> structVertexTransformer = instancer.type.getVertexTransformer();
|
StructVertexTransformer<P> structVertexTransformer = instancer.type.getVertexTransformer();
|
||||||
|
|
||||||
for (P p : parts) {
|
for (P p : parts) {
|
||||||
mesh.copyTo(vertexList.ptr());
|
mesh.copyTo(vertexList.ptr());
|
||||||
|
@ -88,34 +87,12 @@ public class TransformCall<P extends InstancePart> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyMatrices(MutableVertexList vertexList, PoseStack.Pose matrices) {
|
private static void applyMatrices(MutableVertexList vertexList, PoseStack.Pose matrices) {
|
||||||
Vector4f pos = new Vector4f();
|
|
||||||
Vector3f normal = new Vector3f();
|
|
||||||
|
|
||||||
Matrix4f modelMatrix = matrices.pose();
|
Matrix4f modelMatrix = matrices.pose();
|
||||||
Matrix3f normalMatrix = matrices.normal();
|
Matrix3f normalMatrix = matrices.normal();
|
||||||
|
|
||||||
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
||||||
pos.set(
|
VertexTransformations.transformPos(vertexList, i, modelMatrix);
|
||||||
vertexList.x(i),
|
VertexTransformations.transformNormal(vertexList, i, normalMatrix);
|
||||||
vertexList.y(i),
|
|
||||||
vertexList.z(i),
|
|
||||||
1f
|
|
||||||
);
|
|
||||||
pos.transform(modelMatrix);
|
|
||||||
vertexList.x(i, pos.x());
|
|
||||||
vertexList.y(i, pos.y());
|
|
||||||
vertexList.z(i, pos.z());
|
|
||||||
|
|
||||||
normal.set(
|
|
||||||
vertexList.normalX(i),
|
|
||||||
vertexList.normalY(i),
|
|
||||||
vertexList.normalZ(i)
|
|
||||||
);
|
|
||||||
normal.transform(normalMatrix);
|
|
||||||
normal.normalize();
|
|
||||||
vertexList.normalX(i, normal.x());
|
|
||||||
vertexList.normalY(i, normal.y());
|
|
||||||
vertexList.normalZ(i, normal.z());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.layout.LayoutItem;
|
import com.jozufozu.flywheel.api.layout.LayoutItem;
|
||||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.backend.Pipelines;
|
||||||
import com.jozufozu.flywheel.glsl.ShaderSources;
|
import com.jozufozu.flywheel.glsl.ShaderSources;
|
||||||
import com.jozufozu.flywheel.glsl.SourceComponent;
|
import com.jozufozu.flywheel.glsl.SourceComponent;
|
||||||
import com.jozufozu.flywheel.glsl.SourceFile;
|
import com.jozufozu.flywheel.glsl.SourceFile;
|
||||||
|
@ -15,7 +16,6 @@ import com.jozufozu.flywheel.glsl.generate.FnSignature;
|
||||||
import com.jozufozu.flywheel.glsl.generate.GlslBlock;
|
import com.jozufozu.flywheel.glsl.generate.GlslBlock;
|
||||||
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
|
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
|
||||||
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
|
||||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,14 @@ import static org.lwjgl.opengl.GL45.glVertexArrayElementBuffer;
|
||||||
import static org.lwjgl.opengl.GL45.glVertexArrayVertexBuffer;
|
import static org.lwjgl.opengl.GL45.glVertexArrayVertexBuffer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
|
import com.jozufozu.flywheel.backend.Pipelines;
|
||||||
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
|
||||||
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
||||||
|
|
||||||
public class IndirectCullingGroup<P extends InstancePart> {
|
public class IndirectCullingGroup<P extends InstancePart> {
|
||||||
|
@ -109,7 +109,7 @@ public class IndirectCullingGroup<P extends InstancePart> {
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers.updateCounts(instanceCountThisFrame, drawSet.size());
|
buffers.updateCounts(instanceCountThisFrame, drawSet.size());
|
||||||
meshPool.uploadAll();
|
meshPool.flush();
|
||||||
uploadInstanceData();
|
uploadInstanceData();
|
||||||
uploadIndirectCommands();
|
uploadIndirectCommands();
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ public class IndirectCullingGroup<P extends InstancePart> {
|
||||||
int baseInstance = 0;
|
int baseInstance = 0;
|
||||||
for (var batch : drawSet.indirectDraws) {
|
for (var batch : drawSet.indirectDraws) {
|
||||||
batch.prepare(baseInstance);
|
batch.prepare(baseInstance);
|
||||||
baseInstance += batch.instancer().instanceCount;
|
baseInstance += batch.instancer().getInstanceCount();
|
||||||
}
|
}
|
||||||
return baseInstance;
|
return baseInstance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,32 +3,48 @@ package com.jozufozu.flywheel.backend.engine.indirect;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
||||||
|
|
||||||
public final class IndirectDraw<P extends InstancePart> {
|
public class IndirectDraw<P extends InstancePart> {
|
||||||
private final IndirectInstancer<P> instancer;
|
private final IndirectInstancer<P> instancer;
|
||||||
private final IndirectMeshPool.BufferedMesh mesh;
|
private final IndirectMeshPool.BufferedMesh mesh;
|
||||||
private final Material material;
|
private final Material material;
|
||||||
private final RenderStage stage;
|
private final RenderStage stage;
|
||||||
int baseInstance = -1;
|
|
||||||
|
|
||||||
final int vertexMaterialID;
|
private final int vertexMaterialID;
|
||||||
final int fragmentMaterialID;
|
private final int fragmentMaterialID;
|
||||||
|
|
||||||
boolean needsFullWrite = true;
|
private int baseInstance = -1;
|
||||||
|
private boolean needsFullWrite = true;
|
||||||
|
|
||||||
IndirectDraw(IndirectInstancer<P> instancer, Material material, RenderStage stage, IndirectMeshPool.BufferedMesh mesh) {
|
public IndirectDraw(IndirectInstancer<P> instancer, Material material, IndirectMeshPool.BufferedMesh mesh, RenderStage stage) {
|
||||||
this.instancer = instancer;
|
this.instancer = instancer;
|
||||||
this.material = material;
|
this.material = material;
|
||||||
this.stage = stage;
|
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
|
this.stage = stage;
|
||||||
|
|
||||||
this.vertexMaterialID = MaterialIndices.getVertexShaderIndex(material);
|
this.vertexMaterialID = MaterialIndices.getVertexShaderIndex(material);
|
||||||
this.fragmentMaterialID = MaterialIndices.getFragmentShaderIndex(material);
|
this.fragmentMaterialID = MaterialIndices.getFragmentShaderIndex(material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IndirectInstancer<P> instancer() {
|
||||||
|
return instancer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material material() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndirectMeshPool.BufferedMesh mesh() {
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RenderStage stage() {
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
public void prepare(int baseInstance) {
|
public void prepare(int baseInstance) {
|
||||||
instancer.update();
|
instancer.update();
|
||||||
if (baseInstance == this.baseInstance) {
|
if (baseInstance == this.baseInstance) {
|
||||||
|
@ -39,7 +55,7 @@ public final class IndirectDraw<P extends InstancePart> {
|
||||||
needsFullWrite = true;
|
needsFullWrite = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeObjects(long objectPtr, long batchIDPtr, int batchID) {
|
public void writeObjects(long objectPtr, long batchIDPtr, int batchID) {
|
||||||
if (needsFullWrite) {
|
if (needsFullWrite) {
|
||||||
instancer.writeFull(objectPtr, batchIDPtr, batchID);
|
instancer.writeFull(objectPtr, batchIDPtr, batchID);
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,7 +64,7 @@ public final class IndirectDraw<P extends InstancePart> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeIndirectCommand(long ptr) {
|
public void writeIndirectCommand(long ptr) {
|
||||||
var boundingSphere = mesh.mesh.getBoundingSphere();
|
var boundingSphere = mesh.getMesh().getBoundingSphere();
|
||||||
|
|
||||||
MemoryUtil.memPutInt(ptr, mesh.getIndexCount()); // count
|
MemoryUtil.memPutInt(ptr, mesh.getIndexCount()); // count
|
||||||
MemoryUtil.memPutInt(ptr + 4, 0); // instanceCount - to be incremented by the compute shader
|
MemoryUtil.memPutInt(ptr + 4, 0); // instanceCount - to be incremented by the compute shader
|
||||||
|
@ -59,22 +75,5 @@ public final class IndirectDraw<P extends InstancePart> {
|
||||||
boundingSphere.getToAddress(ptr + 20); // boundingSphere
|
boundingSphere.getToAddress(ptr + 20); // boundingSphere
|
||||||
MemoryUtil.memPutInt(ptr + 36, vertexMaterialID); // vertexMaterialID
|
MemoryUtil.memPutInt(ptr + 36, vertexMaterialID); // vertexMaterialID
|
||||||
MemoryUtil.memPutInt(ptr + 40, fragmentMaterialID); // fragmentMaterialID
|
MemoryUtil.memPutInt(ptr + 40, fragmentMaterialID); // fragmentMaterialID
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public IndirectInstancer<P> instancer() {
|
|
||||||
return instancer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IndirectMeshPool.BufferedMesh mesh() {
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Material material() {
|
|
||||||
return material;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RenderStage stage() {
|
|
||||||
return stage;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,16 +6,15 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
import com.jozufozu.flywheel.util.Pair;
|
import com.jozufozu.flywheel.util.Pair;
|
||||||
|
|
||||||
public class IndirectDrawManager {
|
public class IndirectDrawManager {
|
||||||
|
|
||||||
private final Map<InstancerKey<?>, IndirectInstancer<?>> instancers = new HashMap<>();
|
private final Map<InstancerKey<?>, IndirectInstancer<?>> instancers = new HashMap<>();
|
||||||
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
||||||
private final List<IndirectInstancer<?>> initializedInstancers = new ArrayList<>();
|
private final List<IndirectInstancer<?>> initializedInstancers = new ArrayList<>();
|
||||||
|
|
|
@ -11,10 +11,9 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
||||||
import com.jozufozu.flywheel.util.Textures;
|
|
||||||
|
|
||||||
public class IndirectDrawSet<P extends InstancePart> {
|
public class IndirectDrawSet<P extends InstancePart> {
|
||||||
|
|
||||||
|
@ -31,7 +30,7 @@ public class IndirectDrawSet<P extends InstancePart> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(IndirectInstancer<P> instancer, Material material, RenderStage stage, IndirectMeshPool.BufferedMesh bufferedMesh) {
|
public void add(IndirectInstancer<P> instancer, Material material, RenderStage stage, IndirectMeshPool.BufferedMesh bufferedMesh) {
|
||||||
indirectDraws.add(new IndirectDraw<>(instancer, material, stage, bufferedMesh));
|
indirectDraws.add(new IndirectDraw<>(instancer, material, bufferedMesh, stage));
|
||||||
determineMultiDraws();
|
determineMultiDraws();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ import org.lwjgl.opengl.GL32;
|
||||||
import com.jozufozu.flywheel.api.backend.Engine;
|
import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
import com.jozufozu.flywheel.gl.GlStateTracker;
|
import com.jozufozu.flywheel.gl.GlStateTracker;
|
||||||
|
|
|
@ -2,52 +2,43 @@ package com.jozufozu.flywheel.backend.engine.indirect;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
|
|
||||||
public class IndirectInstancer<P extends InstancePart> extends AbstractInstancer<P> {
|
public class IndirectInstancer<P extends InstancePart> extends AbstractInstancer<P> {
|
||||||
|
private final long instanceStride;
|
||||||
private final long objectStride;
|
|
||||||
private final StructWriter<P> writer;
|
|
||||||
int instanceCount = 0;
|
|
||||||
|
|
||||||
public IndirectInstancer(StructType<P> type) {
|
public IndirectInstancer(StructType<P> type) {
|
||||||
super(type);
|
super(type);
|
||||||
this.objectStride = type.getLayout()
|
this.instanceStride = type.getLayout()
|
||||||
.getStride();
|
.getStride();
|
||||||
writer = type.getWriter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public void update() {
|
||||||
return changed.isEmpty() && deleted.isEmpty() && instanceCount == 0;
|
removeDeletedInstances();
|
||||||
}
|
|
||||||
|
|
||||||
void update() {
|
|
||||||
if (!deleted.isEmpty()) {
|
|
||||||
removeDeletedInstances();
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceCount = data.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeSparse(long objectPtr, long batchIDPtr, int batchID) {
|
public void writeSparse(long objectPtr, long batchIDPtr, int batchID) {
|
||||||
final int size = data.size();
|
int count = data.size();
|
||||||
|
StructWriter<P> writer = type.getWriter();
|
||||||
|
for (int i = changed.nextSetBit(0); i >= 0 && i < count; i = changed.nextSetBit(i + 1)) {
|
||||||
|
// write object
|
||||||
|
writer.write(objectPtr + instanceStride * i, data.get(i));
|
||||||
|
|
||||||
for (int i = changed.nextSetBit(0); i >= 0 && i < size; i = changed.nextSetBit(i + 1)) {
|
// write batchID
|
||||||
writer.write(objectPtr + i * objectStride, data.get(i));
|
MemoryUtil.memPutInt(batchIDPtr + IndirectBuffers.INT_SIZE * i, batchID);
|
||||||
|
|
||||||
MemoryUtil.memPutInt(batchIDPtr + i * IndirectBuffers.INT_SIZE, batchID);
|
|
||||||
}
|
}
|
||||||
changed.clear();
|
changed.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeFull(long objectPtr, long batchIDPtr, int batchID) {
|
public void writeFull(long objectPtr, long batchIDPtr, int batchID) {
|
||||||
|
StructWriter<P> writer = type.getWriter();
|
||||||
for (var object : data) {
|
for (var object : data) {
|
||||||
// write object
|
// write object
|
||||||
writer.write(objectPtr, object);
|
writer.write(objectPtr, object);
|
||||||
objectPtr += objectStride;
|
objectPtr += instanceStride;
|
||||||
|
|
||||||
// write batchID
|
// write batchID
|
||||||
MemoryUtil.memPutInt(batchIDPtr, batchID);
|
MemoryUtil.memPutInt(batchIDPtr, batchID);
|
||||||
|
|
|
@ -39,6 +39,10 @@ public class IndirectMeshPool {
|
||||||
clientStorage = MemoryBlock.malloc(byteCapacity);
|
clientStorage = MemoryBlock.malloc(byteCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VertexType getVertexType() {
|
||||||
|
return vertexType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a model in the arena.
|
* Allocate a model in the arena.
|
||||||
*
|
*
|
||||||
|
@ -60,24 +64,26 @@ public class IndirectMeshPool {
|
||||||
return meshes.get(mesh);
|
return meshes.get(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uploadAll() {
|
public void flush() {
|
||||||
if (!dirty) {
|
if (dirty) {
|
||||||
return;
|
uploadAll();
|
||||||
|
dirty = false;
|
||||||
}
|
}
|
||||||
dirty = false;
|
}
|
||||||
|
|
||||||
|
private void uploadAll() {
|
||||||
final long ptr = clientStorage.ptr();
|
final long ptr = clientStorage.ptr();
|
||||||
|
|
||||||
int byteIndex = 0;
|
int byteIndex = 0;
|
||||||
int baseVertex = 0;
|
int baseVertex = 0;
|
||||||
for (BufferedMesh model : meshList) {
|
for (BufferedMesh mesh : meshList) {
|
||||||
model.byteIndex = byteIndex;
|
mesh.byteIndex = byteIndex;
|
||||||
model.baseVertex = baseVertex;
|
mesh.baseVertex = baseVertex;
|
||||||
|
|
||||||
model.buffer(ptr);
|
mesh.buffer(ptr);
|
||||||
|
|
||||||
byteIndex += model.size();
|
byteIndex += mesh.size();
|
||||||
baseVertex += model.mesh.getVertexCount();
|
baseVertex += mesh.mesh.getVertexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
nglNamedBufferSubData(vbo, 0, byteIndex, ptr);
|
nglNamedBufferSubData(vbo, 0, byteIndex, ptr);
|
||||||
|
@ -90,26 +96,18 @@ public class IndirectMeshPool {
|
||||||
meshList.clear();
|
meshList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VertexType getVertexType() {
|
|
||||||
return vertexType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BufferedMesh {
|
public class BufferedMesh {
|
||||||
public final Mesh mesh;
|
private final Mesh mesh;
|
||||||
private final int vertexCount;
|
private final int vertexCount;
|
||||||
|
|
||||||
private long byteIndex;
|
private long byteIndex;
|
||||||
private int baseVertex;
|
private int baseVertex;
|
||||||
|
|
||||||
private BufferedMesh(Mesh mesh) {
|
private BufferedMesh(Mesh mesh) {
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
|
|
||||||
vertexCount = mesh.getVertexCount();
|
vertexCount = mesh.getVertexCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buffer(long ptr) {
|
|
||||||
mesh.write(ptr + byteIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mesh getMesh() {
|
public Mesh getMesh() {
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
@ -129,5 +127,9 @@ public class IndirectMeshPool {
|
||||||
public VertexType getVertexType() {
|
public VertexType getVertexType() {
|
||||||
return vertexType;
|
return vertexType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void buffer(long ptr) {
|
||||||
|
mesh.write(ptr + byteIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.util;
|
package com.jozufozu.flywheel.backend.engine.indirect;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
|
@ -1,86 +1,50 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.instancing;
|
package com.jozufozu.flywheel.backend.engine.instancing;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
|
||||||
import com.jozufozu.flywheel.gl.GlStateTracker;
|
import com.jozufozu.flywheel.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||||
|
|
||||||
public class DrawCall {
|
public class DrawCall {
|
||||||
|
private final GPUInstancer<?> instancer;
|
||||||
|
private final InstancedMeshPool.BufferedMesh mesh;
|
||||||
|
|
||||||
final GPUInstancer<?> instancer;
|
|
||||||
final Material material;
|
|
||||||
private final int meshAttributes;
|
private final int meshAttributes;
|
||||||
InstancedMeshPool.BufferedMesh bufferedMesh;
|
private GlVertexArray vao;
|
||||||
GlVertexArray vao;
|
|
||||||
|
|
||||||
DrawCall(GPUInstancer<?> instancer, Material material, InstancedMeshPool.BufferedMesh mesh) {
|
public DrawCall(GPUInstancer<?> instancer, InstancedMeshPool.BufferedMesh mesh) {
|
||||||
this.instancer = instancer;
|
this.instancer = instancer;
|
||||||
this.material = material;
|
this.mesh = mesh;
|
||||||
this.vao = new GlVertexArray();
|
|
||||||
this.bufferedMesh = mesh;
|
meshAttributes = this.mesh.getAttributeCount();
|
||||||
this.meshAttributes = this.bufferedMesh.getAttributeCount();
|
vao = new GlVertexArray();
|
||||||
this.vao.enableArrays(this.meshAttributes + instancer.instanceFormat.getAttributeCount());
|
vao.enableArrays(meshAttributes + this.instancer.getAttributeCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Material getMaterial() {
|
public boolean isInvalid() {
|
||||||
return material;
|
return instancer.isInvalid() || vao == null;
|
||||||
}
|
|
||||||
|
|
||||||
public VertexType getVertexType() {
|
|
||||||
return bufferedMesh.getVertexType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
if (invalid()) {
|
if (isInvalid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (var ignored = GlStateTracker.getRestoreState()) {
|
try (var ignored = GlStateTracker.getRestoreState()) {
|
||||||
|
instancer.update();
|
||||||
|
|
||||||
this.instancer.update();
|
instancer.bindToVAO(vao, meshAttributes);
|
||||||
|
|
||||||
bindInstancerToVAO();
|
if (instancer.getInstanceCount() > 0) {
|
||||||
|
mesh.drawInstances(vao, instancer.getInstanceCount());
|
||||||
if (this.instancer.glInstanceCount > 0) {
|
|
||||||
bufferedMesh.drawInstances(vao, this.instancer.glInstanceCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldRemove() {
|
|
||||||
return invalid();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only {@code true} if the InstancedModel has been destroyed.
|
|
||||||
*/
|
|
||||||
private boolean invalid() {
|
|
||||||
return this.instancer.vbo == null || bufferedMesh == null || vao == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void bindInstancerToVAO() {
|
|
||||||
if (!this.instancer.boundTo.add(vao)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var instanceFormat = this.instancer.instanceFormat;
|
|
||||||
|
|
||||||
vao.bindAttributes(this.instancer.vbo, this.meshAttributes, instanceFormat, 0L);
|
|
||||||
|
|
||||||
for (int i = 0; i < instanceFormat.getAttributeCount(); i++) {
|
|
||||||
vao.setAttributeDivisor(this.meshAttributes + i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
if (invalid()) {
|
if (vao == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vao.delete();
|
vao.delete();
|
||||||
bufferedMesh.delete();
|
|
||||||
|
|
||||||
vao = null;
|
vao = null;
|
||||||
bufferedMesh = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
|
@ -16,17 +16,24 @@ import com.jozufozu.flywheel.gl.buffer.GlBufferUsage;
|
||||||
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
|
||||||
|
|
||||||
public class GPUInstancer<P extends InstancePart> extends AbstractInstancer<P> {
|
public class GPUInstancer<P extends InstancePart> extends AbstractInstancer<P> {
|
||||||
|
private final BufferLayout instanceFormat;
|
||||||
|
private final int instanceStride;
|
||||||
|
|
||||||
final BufferLayout instanceFormat;
|
private final Set<GlVertexArray> boundTo = new HashSet<>();
|
||||||
final Set<GlVertexArray> boundTo = new HashSet<>();
|
private GlBuffer vbo;
|
||||||
GlBuffer vbo;
|
|
||||||
int glInstanceCount = 0;
|
|
||||||
|
|
||||||
boolean anyToUpdate;
|
|
||||||
|
|
||||||
public GPUInstancer(StructType<P> type) {
|
public GPUInstancer(StructType<P> type) {
|
||||||
super(type);
|
super(type);
|
||||||
this.instanceFormat = type.getLayout();
|
instanceFormat = type.getLayout();
|
||||||
|
instanceStride = instanceFormat.getStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAttributeCount() {
|
||||||
|
return instanceFormat.getAttributeCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInvalid() {
|
||||||
|
return vbo == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
|
@ -35,63 +42,59 @@ public class GPUInstancer<P extends InstancePart> extends AbstractInstancer<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER, GlBufferUsage.DYNAMIC_DRAW);
|
vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER, GlBufferUsage.DYNAMIC_DRAW);
|
||||||
vbo.setGrowthMargin(instanceFormat.getStride() * 16);
|
vbo.setGrowthMargin(instanceStride * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public void update() {
|
||||||
return deleted.isEmpty() && changed.isEmpty() && glInstanceCount == 0;
|
removeDeletedInstances();
|
||||||
|
ensureBufferCapacity();
|
||||||
|
updateBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update() {
|
private void ensureBufferCapacity() {
|
||||||
if (!deleted.isEmpty()) {
|
int count = data.size();
|
||||||
removeDeletedInstances();
|
int byteSize = instanceStride * count;
|
||||||
}
|
if (vbo.ensureCapacity(byteSize)) {
|
||||||
|
// The vbo has moved, so we need to re-bind attributes
|
||||||
if (checkAndGrowBuffer()) {
|
|
||||||
// The instance vbo has moved, so we need to re-bind attributes
|
|
||||||
boundTo.clear();
|
boundTo.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!changed.isEmpty()) {
|
|
||||||
clearAndUpdateBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
glInstanceCount = data.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearAndUpdateBuffer() {
|
private void updateBuffer() {
|
||||||
final int size = data.size();
|
if (changed.isEmpty()) {
|
||||||
final long clearStart = (long) size * instanceFormat.getStride();
|
return;
|
||||||
final long clearLength = vbo.getSize() - clearStart;
|
}
|
||||||
|
|
||||||
|
int count = data.size();
|
||||||
|
long clearStart = instanceStride * (long) count;
|
||||||
|
long clearLength = vbo.getSize() - clearStart;
|
||||||
|
|
||||||
try (MappedBuffer buf = vbo.map()) {
|
try (MappedBuffer buf = vbo.map()) {
|
||||||
buf.clear(clearStart, clearLength);
|
buf.clear(clearStart, clearLength);
|
||||||
|
|
||||||
if (size > 0) {
|
long ptr = buf.getPtr();
|
||||||
final long ptr = buf.getPtr();
|
StructWriter<P> writer = type.getWriter();
|
||||||
final long stride = type.getLayout()
|
|
||||||
.getStride();
|
|
||||||
final StructWriter<P> writer = type.getWriter();
|
|
||||||
|
|
||||||
for (int i = changed.nextSetBit(0); i >= 0 && i < size; i = changed.nextSetBit(i + 1)) {
|
for (int i = changed.nextSetBit(0); i >= 0 && i < count; i = changed.nextSetBit(i + 1)) {
|
||||||
writer.write(ptr + i * stride, data.get(i));
|
writer.write(ptr + instanceStride * i, data.get(i));
|
||||||
}
|
|
||||||
changed.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changed.clear();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Flywheel.LOGGER.error("Error updating GPUInstancer:", e);
|
Flywheel.LOGGER.error("Error updating GPUInstancer:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void bindToVAO(GlVertexArray vao, int attributeOffset) {
|
||||||
* @return {@code true} if the buffer moved.
|
if (!boundTo.add(vao)) {
|
||||||
*/
|
return;
|
||||||
private boolean checkAndGrowBuffer() {
|
}
|
||||||
int size = this.data.size();
|
|
||||||
int stride = instanceFormat.getStride();
|
|
||||||
int requiredSize = size * stride;
|
|
||||||
|
|
||||||
return vbo.ensureCapacity(requiredSize);
|
vao.bindAttributes(vbo, attributeOffset, instanceFormat, 0L);
|
||||||
|
|
||||||
|
for (int i = 0; i < instanceFormat.getAttributeCount(); i++) {
|
||||||
|
vao.setAttributeDivisor(attributeOffset + i, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
|
|
@ -39,9 +39,12 @@ public class InstancedMeshPool {
|
||||||
public InstancedMeshPool(VertexType vertexType) {
|
public InstancedMeshPool(VertexType vertexType) {
|
||||||
this.vertexType = vertexType;
|
this.vertexType = vertexType;
|
||||||
int stride = vertexType.getLayout().getStride();
|
int stride = vertexType.getLayout().getStride();
|
||||||
this.vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
|
vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
|
||||||
|
vbo.setGrowthMargin(stride * 32);
|
||||||
|
}
|
||||||
|
|
||||||
this.vbo.setGrowthMargin(stride * 32);
|
public VertexType getVertexType() {
|
||||||
|
return vertexType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -161,10 +164,6 @@ public class InstancedMeshPool {
|
||||||
pendingUpload.clear();
|
pendingUpload.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VertexType getVertexType() {
|
|
||||||
return vertexType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "InstancedMeshPool{" + "vertexType=" + vertexType + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
|
return "InstancedMeshPool{" + "vertexType=" + vertexType + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
|
||||||
|
@ -210,10 +209,6 @@ public class InstancedMeshPool {
|
||||||
boundTo.clear();
|
boundTo.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawCall(GlVertexArray vao) {
|
|
||||||
drawInstances(vao, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawInstances(GlVertexArray vao, int instanceCount) {
|
public void drawInstances(GlVertexArray vao, int instanceCount) {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -14,16 +14,15 @@ import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.ImmutableListMultimap;
|
import com.google.common.collect.ImmutableListMultimap;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
|
|
||||||
public class InstancingDrawManager {
|
public class InstancingDrawManager {
|
||||||
|
|
||||||
private final Map<InstancerKey<?>, GPUInstancer<?>> instancers = new HashMap<>();
|
private final Map<InstancerKey<?>, GPUInstancer<?>> instancers = new HashMap<>();
|
||||||
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
||||||
private final List<GPUInstancer<?>> initializedInstancers = new ArrayList<>();
|
private final List<GPUInstancer<?>> initializedInstancers = new ArrayList<>();
|
||||||
|
@ -48,9 +47,6 @@ public class InstancingDrawManager {
|
||||||
|
|
||||||
public void flush() {
|
public void flush() {
|
||||||
for (var instancer : uninitializedInstancers) {
|
for (var instancer : uninitializedInstancers) {
|
||||||
instancer.instancer()
|
|
||||||
.init();
|
|
||||||
|
|
||||||
add(instancer.instancer(), instancer.model(), instancer.stage());
|
add(instancer.instancer(), instancer.model(), instancer.stage());
|
||||||
}
|
}
|
||||||
uninitializedInstancers.clear();
|
uninitializedInstancers.clear();
|
||||||
|
@ -80,11 +76,13 @@ public class InstancingDrawManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(GPUInstancer<?> instancer, Model model, RenderStage stage) {
|
private void add(GPUInstancer<?> instancer, Model model, RenderStage stage) {
|
||||||
|
instancer.init();
|
||||||
DrawSet drawSet = drawSets.computeIfAbsent(stage, DrawSet::new);
|
DrawSet drawSet = drawSets.computeIfAbsent(stage, DrawSet::new);
|
||||||
var meshes = model.getMeshes();
|
var meshes = model.getMeshes();
|
||||||
for (var entry : meshes.entrySet()) {
|
for (var entry : meshes.entrySet()) {
|
||||||
DrawCall drawCall = new DrawCall(instancer, entry.getKey(), alloc(entry.getValue()));
|
var mesh = alloc(entry.getValue());
|
||||||
var shaderState = new ShaderState(drawCall.getMaterial(), drawCall.getVertexType(), drawCall.instancer.type);
|
ShaderState shaderState = new ShaderState(entry.getKey(), mesh.getVertexType(), instancer.type);
|
||||||
|
DrawCall drawCall = new DrawCall(instancer, mesh);
|
||||||
drawSet.put(shaderState, drawCall);
|
drawSet.put(shaderState, drawCall);
|
||||||
}
|
}
|
||||||
initializedInstancers.add(instancer);
|
initializedInstancers.add(instancer);
|
||||||
|
@ -96,7 +94,6 @@ public class InstancingDrawManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DrawSet implements Iterable<Map.Entry<ShaderState, Collection<DrawCall>>> {
|
public static class DrawSet implements Iterable<Map.Entry<ShaderState, Collection<DrawCall>>> {
|
||||||
|
|
||||||
public static final DrawSet EMPTY = new DrawSet(ImmutableListMultimap.of());
|
public static final DrawSet EMPTY = new DrawSet(ImmutableListMultimap.of());
|
||||||
|
|
||||||
private final ListMultimap<ShaderState, DrawCall> drawCalls;
|
private final ListMultimap<ShaderState, DrawCall> drawCalls;
|
||||||
|
|
|
@ -8,17 +8,17 @@ import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||||
import com.jozufozu.flywheel.api.event.RenderStage;
|
import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Instancer;
|
import com.jozufozu.flywheel.api.instancer.Instancer;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
|
import com.jozufozu.flywheel.backend.Pipelines;
|
||||||
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
||||||
import com.jozufozu.flywheel.gl.GlStateTracker;
|
import com.jozufozu.flywheel.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
||||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
|
@ -47,7 +47,7 @@ public class InstancingEngine implements Engine {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginFrame(TaskExecutor executor, RenderContext context) {
|
public void beginFrame(TaskExecutor executor, RenderContext context) {
|
||||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
try (var state = GlStateTracker.getRestoreState()) {
|
||||||
drawManager.flush();
|
drawManager.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ public class InstancingEngine implements Engine {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
try (var state = GlStateTracker.getRestoreState()) {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
render(drawSet);
|
render(drawSet);
|
||||||
|
@ -83,7 +83,7 @@ public class InstancingEngine implements Engine {
|
||||||
var shader = entry.getKey();
|
var shader = entry.getKey();
|
||||||
var drawCalls = entry.getValue();
|
var drawCalls = entry.getValue();
|
||||||
|
|
||||||
drawCalls.removeIf(DrawCall::shouldRemove);
|
drawCalls.removeIf(DrawCall::isInvalid);
|
||||||
|
|
||||||
if (drawCalls.isEmpty()) {
|
if (drawCalls.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -102,9 +102,9 @@ public class InstancingEngine implements Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup(ShaderState desc) {
|
private void setup(ShaderState desc) {
|
||||||
var vertexType = desc.vertex();
|
|
||||||
var structType = desc.instance();
|
|
||||||
var material = desc.material();
|
var material = desc.material();
|
||||||
|
var vertexType = desc.vertexType();
|
||||||
|
var structType = desc.instanceType();
|
||||||
|
|
||||||
var program = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, structType, context, Pipelines.INSTANCED_ARRAYS);
|
var program = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, structType, context, Pipelines.INSTANCED_ARRAYS);
|
||||||
UniformBuffer.syncAndBind(program);
|
UniformBuffer.syncAndBind(program);
|
||||||
|
|
|
@ -4,5 +4,5 @@ import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
|
|
||||||
public record ShaderState(Material material, VertexType vertex, StructType<?> instance) {
|
public record ShaderState(Material material, VertexType vertexType, StructType<?> instanceType) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.jozufozu.flywheel.backend.task;
|
||||||
|
|
||||||
|
public class FlwTaskExecutor {
|
||||||
|
private static ParallelTaskExecutor executor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a thread pool for running Flywheel related work in parallel.
|
||||||
|
* @return A global Flywheel thread pool.
|
||||||
|
*/
|
||||||
|
public static ParallelTaskExecutor get() {
|
||||||
|
if (executor == null) {
|
||||||
|
executor = new ParallelTaskExecutor("Flywheel");
|
||||||
|
executor.startWorkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -146,6 +146,28 @@ public class ParallelTaskExecutor implements TaskExecutor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void discardAndAwait() {
|
||||||
|
// Discard everyone else's work...
|
||||||
|
while (taskQueue.pollLast() != null) {
|
||||||
|
synchronized (tasksCompletedNotifier) {
|
||||||
|
if (--incompleteTaskCounter == 0) {
|
||||||
|
tasksCompletedNotifier.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// and wait for any stragglers.
|
||||||
|
synchronized (tasksCompletedNotifier) {
|
||||||
|
while (incompleteTaskCounter > 0) {
|
||||||
|
try {
|
||||||
|
tasksCompletedNotifier.wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Runnable getNextTask() {
|
private Runnable getNextTask() {
|
||||||
Runnable task = taskQueue.pollFirst();
|
Runnable task = taskQueue.pollFirst();
|
||||||
|
|
|
@ -9,20 +9,19 @@ import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.arguments.ArgumentType;
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
|
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||||
|
|
||||||
import net.minecraft.commands.SharedSuggestionProvider;
|
import net.minecraft.commands.SharedSuggestionProvider;
|
||||||
import net.minecraft.network.chat.TranslatableComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class BackendArgument implements ArgumentType<Backend> {
|
public class BackendArgument implements ArgumentType<Backend> {
|
||||||
private static final List<String> STRING_IDS = Backend.REGISTRY.getAllIds().stream().map(ResourceLocation::toString).toList();
|
private static final List<String> STRING_IDS = Backend.REGISTRY.getAllIds().stream().map(ResourceLocation::toString).toList();
|
||||||
|
|
||||||
private static final Dynamic2CommandExceptionType INVALID = new Dynamic2CommandExceptionType((found, constants) -> {
|
public static final DynamicCommandExceptionType ERROR_UNKNOWN_BACKEND = new DynamicCommandExceptionType(arg -> {
|
||||||
// TODO: don't steal lang
|
return new TextComponent("Unknown backend '" + arg + "'");
|
||||||
return new TranslatableComponent("commands.forge.arguments.enum.invalid", constants, found);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
public static final BackendArgument INSTANCE = new BackendArgument();
|
public static final BackendArgument INSTANCE = new BackendArgument();
|
||||||
|
@ -33,7 +32,7 @@ public class BackendArgument implements ArgumentType<Backend> {
|
||||||
Backend backend = Backend.REGISTRY.get(id);
|
Backend backend = Backend.REGISTRY.get(id);
|
||||||
|
|
||||||
if (backend == null) {
|
if (backend == null) {
|
||||||
throw INVALID.createWithContext(reader, id.toString(), STRING_IDS);
|
throw ERROR_UNKNOWN_BACKEND.createWithContext(reader, id.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return backend;
|
return backend;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.slf4j.Logger;
|
||||||
import com.jozufozu.flywheel.glsl.ShaderLoadingException;
|
import com.jozufozu.flywheel.glsl.ShaderLoadingException;
|
||||||
import com.jozufozu.flywheel.glsl.SourceFile;
|
import com.jozufozu.flywheel.glsl.SourceFile;
|
||||||
import com.jozufozu.flywheel.glsl.span.Span;
|
import com.jozufozu.flywheel.glsl.span.Span;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
import com.jozufozu.flywheel.lib.math.MoreMath;
|
||||||
import com.jozufozu.flywheel.util.StringUtil;
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
|
||||||
|
@ -97,14 +97,14 @@ public class ErrorReporter {
|
||||||
|
|
||||||
int size = lines.size();
|
int size = lines.size();
|
||||||
|
|
||||||
int maxWidth = FlwUtil.numDigits(size) + 1;
|
int maxWidth = MoreMath.numDigits(size) + 1;
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder().append('\n');
|
StringBuilder builder = new StringBuilder().append('\n');
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
|
|
||||||
builder.append(i)
|
builder.append(i)
|
||||||
.append(StringUtil.repeatChar(' ', maxWidth - FlwUtil.numDigits(i)))
|
.append(StringUtil.repeatChar(' ', maxWidth - MoreMath.numDigits(i)))
|
||||||
.append("| ")
|
.append("| ")
|
||||||
.append(lines.get(i))
|
.append(lines.get(i))
|
||||||
.append('\n');
|
.append('\n');
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.jozufozu.flywheel.handler;
|
package com.jozufozu.flywheel.handler;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
|
||||||
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
||||||
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||||
|
@ -14,7 +14,7 @@ public class EntityWorldHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BackendUtil.canUseInstancing(level)) {
|
if (FlwUtil.canUseInstancing(level)) {
|
||||||
InstancedRenderDispatcher.getEntities(level)
|
InstancedRenderDispatcher.getEntities(level)
|
||||||
.queueAdd(event.getEntity());
|
.queueAdd(event.getEntity());
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ public class EntityWorldHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BackendUtil.canUseInstancing(level)) {
|
if (FlwUtil.canUseInstancing(level)) {
|
||||||
InstancedRenderDispatcher.getEntities(level)
|
InstancedRenderDispatcher.getEntities(level)
|
||||||
.remove(event.getEntity());
|
.remove(event.getEntity());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ package com.jozufozu.flywheel.handler;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
|
||||||
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||||
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
||||||
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
import com.jozufozu.flywheel.util.StringUtil;
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
import com.jozufozu.flywheel.util.WorldAttached;
|
import com.jozufozu.flywheel.util.WorldAttached;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class ForgeEvents {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tickLight(TickEvent.ClientTickEvent event) {
|
public static void tickLight(TickEvent.ClientTickEvent event) {
|
||||||
if (event.phase == TickEvent.Phase.END && BackendUtil.isGameActive()) {
|
if (event.phase == TickEvent.Phase.END && FlwUtil.isGameActive()) {
|
||||||
LightUpdater.get(Minecraft.getInstance().level)
|
LightUpdater.get(Minecraft.getInstance().level)
|
||||||
.tick();
|
.tick();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,33 @@ package com.jozufozu.flywheel.impl;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.backend.Backend;
|
import com.jozufozu.flywheel.api.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
|
||||||
|
import com.jozufozu.flywheel.backend.Backends;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.lib.backend.Backends;
|
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
||||||
|
import com.jozufozu.flywheel.lib.backend.SimpleBackend;
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraftforge.fml.CrashReportCallables;
|
||||||
|
|
||||||
public final class BackendManagerImpl {
|
public final class BackendManagerImpl {
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
|
private static final Backend OFF_BACKEND = SimpleBackend.builder()
|
||||||
|
.engineMessage(new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED))
|
||||||
|
.engineFactory(level -> {
|
||||||
|
throw new IllegalStateException("Cannot create engine when backend is off.");
|
||||||
|
})
|
||||||
|
.supported(() -> true)
|
||||||
|
.register(Flywheel.rl("off"));
|
||||||
|
|
||||||
private static final Backend DEFAULT_BACKEND = findDefaultBackend();
|
private static final Backend DEFAULT_BACKEND = findDefaultBackend();
|
||||||
|
|
||||||
private static Backend backend;
|
private static Backend backend;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -19,17 +38,35 @@ public final class BackendManagerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isOn() {
|
public static boolean isOn() {
|
||||||
return backend != null && backend != Backends.OFF;
|
return backend != null && backend != OFF_BACKEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void refresh() {
|
public static Backend getOffBackend() {
|
||||||
backend = chooseBackend();
|
return OFF_BACKEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Backend getDefaultBackend() {
|
public static Backend getDefaultBackend() {
|
||||||
return DEFAULT_BACKEND;
|
return DEFAULT_BACKEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Backend findDefaultBackend() {
|
||||||
|
// TODO: Automatically select the best default config based on the user's driver
|
||||||
|
// TODO: Figure out how this will work if custom backends are registered and without hardcoding the default backends
|
||||||
|
return Backends.INDIRECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||||
|
refresh(event.getLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void refresh(@Nullable ClientLevel level) {
|
||||||
|
backend = chooseBackend();
|
||||||
|
|
||||||
|
if (level != null) {
|
||||||
|
InstancedRenderDispatcher.resetInstanceWorld(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Backend chooseBackend() {
|
private static Backend chooseBackend() {
|
||||||
var preferred = FlwConfig.get().getBackend();
|
var preferred = FlwConfig.get().getBackend();
|
||||||
var actual = preferred.findFallback();
|
var actual = preferred.findFallback();
|
||||||
|
@ -41,21 +78,17 @@ public final class BackendManagerImpl {
|
||||||
return actual;
|
return actual;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Backend findDefaultBackend() {
|
public static void init() {
|
||||||
// TODO: Automatically select the best default config based on the user's driver
|
CrashReportCallables.registerCrashCallable("Flywheel Backend", () -> {
|
||||||
// TODO: Figure out how this will work if custom backends are registered
|
if (backend == null) {
|
||||||
return Backends.INDIRECT;
|
return "Uninitialized";
|
||||||
}
|
}
|
||||||
|
var backendId = Backend.REGISTRY.getId(backend);
|
||||||
public static String getBackendNameForCrashReport() {
|
if (backendId == null) {
|
||||||
if (backend == null) {
|
return "Unregistered";
|
||||||
return "Uninitialized";
|
}
|
||||||
}
|
return backendId.toString();
|
||||||
var backendId = Backend.REGISTRY.getId(backend);
|
});
|
||||||
if (backendId == null) {
|
|
||||||
return "Unregistered";
|
|
||||||
}
|
|
||||||
return backendId.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BackendManagerImpl() {
|
private BackendManagerImpl() {
|
||||||
|
|
|
@ -11,8 +11,8 @@ import com.jozufozu.flywheel.api.event.RenderStage;
|
||||||
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.effect.Effect;
|
import com.jozufozu.flywheel.api.instance.effect.Effect;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.backend.task.FlwTaskExecutor;
|
||||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
||||||
import com.jozufozu.flywheel.config.FlwCommands;
|
import com.jozufozu.flywheel.config.FlwCommands;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.impl.instancing.manager.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.impl.instancing.manager.BlockEntityInstanceManager;
|
||||||
|
@ -27,9 +27,10 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
/**
|
/**
|
||||||
* A manager class for a single world where instancing is supported.
|
* A manager class for a single world where instancing is supported.
|
||||||
*/
|
*/
|
||||||
public class InstanceWorld {
|
// AutoCloseable is implemented to prevent leaking this object from WorldAttached
|
||||||
|
public class InstanceWorld implements AutoCloseable {
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
private final TaskExecutor taskExecutor;
|
private final ParallelTaskExecutor taskExecutor;
|
||||||
|
|
||||||
private final InstanceManager<BlockEntity> blockEntities;
|
private final InstanceManager<BlockEntity> blockEntities;
|
||||||
private final InstanceManager<Entity> entities;
|
private final InstanceManager<Entity> entities;
|
||||||
|
@ -37,7 +38,7 @@ public class InstanceWorld {
|
||||||
|
|
||||||
public InstanceWorld(LevelAccessor level) {
|
public InstanceWorld(LevelAccessor level) {
|
||||||
engine = BackendManager.getBackend().createEngine(level);
|
engine = BackendManager.getBackend().createEngine(level);
|
||||||
taskExecutor = BackendUtil.getTaskExecutor();
|
taskExecutor = FlwTaskExecutor.get();
|
||||||
|
|
||||||
blockEntities = new BlockEntityInstanceManager(engine);
|
blockEntities = new BlockEntityInstanceManager(engine);
|
||||||
entities = new EntityInstanceManager(engine);
|
entities = new EntityInstanceManager(engine);
|
||||||
|
@ -127,9 +128,15 @@ public class InstanceWorld {
|
||||||
* Free all acquired resources and invalidate this instance world.
|
* Free all acquired resources and invalidate this instance world.
|
||||||
*/
|
*/
|
||||||
public void delete() {
|
public void delete() {
|
||||||
|
taskExecutor.discardAndAwait();
|
||||||
blockEntities.invalidate();
|
blockEntities.invalidate();
|
||||||
entities.invalidate();
|
entities.invalidate();
|
||||||
effects.invalidate();
|
effects.invalidate();
|
||||||
engine.delete();
|
engine.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,13 @@ package com.jozufozu.flywheel.impl.instancing;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderStageEvent;
|
import com.jozufozu.flywheel.api.event.RenderStageEvent;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.effect.Effect;
|
import com.jozufozu.flywheel.api.instance.effect.Effect;
|
||||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
|
||||||
import com.jozufozu.flywheel.extension.ClientLevelExtension;
|
import com.jozufozu.flywheel.extension.ClientLevelExtension;
|
||||||
import com.jozufozu.flywheel.impl.instancing.manager.InstanceManager;
|
import com.jozufozu.flywheel.impl.instancing.manager.InstanceManager;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.lib.util.AnimationTickHolder;
|
||||||
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
import com.jozufozu.flywheel.util.WorldAttached;
|
import com.jozufozu.flywheel.util.WorldAttached;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -34,7 +33,7 @@ public class InstancedRenderDispatcher {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ public class InstancedRenderDispatcher {
|
||||||
*/
|
*/
|
||||||
public static void queueUpdate(Entity entity) {
|
public static void queueUpdate(Entity entity) {
|
||||||
Level level = entity.level;
|
Level level = entity.level;
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +62,7 @@ public class InstancedRenderDispatcher {
|
||||||
* @param effect The effect whose instance you want to update.
|
* @param effect The effect whose instance you want to update.
|
||||||
*/
|
*/
|
||||||
public static void queueUpdate(LevelAccessor level, Effect effect) {
|
public static void queueUpdate(LevelAccessor level, Effect effect) {
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +76,7 @@ public class InstancedRenderDispatcher {
|
||||||
* @throws IllegalStateException if the backend is off
|
* @throws IllegalStateException if the backend is off
|
||||||
*/
|
*/
|
||||||
private static InstanceWorld getInstanceWorld(LevelAccessor level) {
|
private static InstanceWorld getInstanceWorld(LevelAccessor level) {
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
throw new IllegalStateException("Cannot retrieve instance world when backend is off!");
|
throw new IllegalStateException("Cannot retrieve instance world when backend is off!");
|
||||||
}
|
}
|
||||||
return INSTANCE_WORLDS.get(level);
|
return INSTANCE_WORLDS.get(level);
|
||||||
|
@ -100,7 +99,7 @@ public class InstancedRenderDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick(TickEvent.ClientTickEvent event) {
|
public static void tick(TickEvent.ClientTickEvent event) {
|
||||||
if (!BackendUtil.isGameActive() || event.phase == TickEvent.Phase.START) {
|
if (!FlwUtil.isGameActive() || event.phase == TickEvent.Phase.START) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +116,7 @@ public class InstancedRenderDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
Level level = cameraEntity.level;
|
Level level = cameraEntity.level;
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,12 +128,12 @@ public class InstancedRenderDispatcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onBeginFrame(BeginFrameEvent event) {
|
public static void onBeginFrame(BeginFrameEvent event) {
|
||||||
if (!BackendUtil.isGameActive()) {
|
if (!FlwUtil.isGameActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientLevel level = event.getContext().level();
|
ClientLevel level = event.getContext().level();
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,26 +142,17 @@ public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
public static void onRenderStage(RenderStageEvent event) {
|
public static void onRenderStage(RenderStageEvent event) {
|
||||||
ClientLevel level = event.getContext().level();
|
ClientLevel level = event.getContext().level();
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANCE_WORLDS.get(level).renderStage(event.getContext(), event.getStage());
|
INSTANCE_WORLDS.get(level).renderStage(event.getContext(), event.getStage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
|
||||||
ClientLevel level = event.getLevel();
|
|
||||||
if (level == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resetInstanceWorld(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void resetInstanceWorld(ClientLevel level) {
|
public static void resetInstanceWorld(ClientLevel level) {
|
||||||
INSTANCE_WORLDS.remove(level, InstanceWorld::delete);
|
INSTANCE_WORLDS.remove(level, InstanceWorld::delete);
|
||||||
|
|
||||||
if (!BackendUtil.canUseInstancing(level)) {
|
if (!FlwUtil.canUseInstancing(level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +165,7 @@ public class InstancedRenderDispatcher {
|
||||||
|
|
||||||
public static void addDebugInfo(List<String> info) {
|
public static void addDebugInfo(List<String> info) {
|
||||||
ClientLevel level = Minecraft.getInstance().level;
|
ClientLevel level = Minecraft.getInstance().level;
|
||||||
if (BackendUtil.canUseInstancing(level)) {
|
if (FlwUtil.canUseInstancing(level)) {
|
||||||
INSTANCE_WORLDS.get(level).addDebugInfo(info);
|
INSTANCE_WORLDS.get(level).addDebugInfo(info);
|
||||||
} else {
|
} else {
|
||||||
info.add("Disabled");
|
info.add("Disabled");
|
||||||
|
|
|
@ -8,10 +8,10 @@ import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
import com.jozufozu.flywheel.api.instance.BlockEntityInstance;
|
import com.jozufozu.flywheel.api.instance.BlockEntityInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
|
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
|
||||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
|
||||||
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
|
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
|
||||||
import com.jozufozu.flywheel.impl.instancing.storage.One2OneStorage;
|
import com.jozufozu.flywheel.impl.instancing.storage.One2OneStorage;
|
||||||
import com.jozufozu.flywheel.impl.instancing.storage.Storage;
|
import com.jozufozu.flywheel.impl.instancing.storage.Storage;
|
||||||
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
@ -66,7 +66,7 @@ public class BlockEntityInstanceManager extends InstanceManager<BlockEntity> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BackendUtil.isFlywheelLevel(level)) {
|
if (FlwUtil.isFlywheelLevel(level)) {
|
||||||
BlockPos pos = blockEntity.getBlockPos();
|
BlockPos pos = blockEntity.getBlockPos();
|
||||||
|
|
||||||
BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
|
BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
|
||||||
|
|
|
@ -5,10 +5,10 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import com.jozufozu.flywheel.api.backend.Engine;
|
import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
import com.jozufozu.flywheel.api.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
|
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
|
||||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
|
||||||
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
|
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
|
||||||
import com.jozufozu.flywheel.impl.instancing.storage.One2OneStorage;
|
import com.jozufozu.flywheel.impl.instancing.storage.One2OneStorage;
|
||||||
import com.jozufozu.flywheel.impl.instancing.storage.Storage;
|
import com.jozufozu.flywheel.impl.instancing.storage.Storage;
|
||||||
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
@ -53,7 +53,7 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
||||||
|
|
||||||
Level level = entity.level;
|
Level level = entity.level;
|
||||||
|
|
||||||
return BackendUtil.isFlywheelLevel(level);
|
return FlwUtil.isFlywheelLevel(level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,14 @@ public abstract class InstanceManager<T> {
|
||||||
queue.add(Transaction.add(obj));
|
queue.add(Transaction.add(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void remove(T obj) {
|
||||||
|
getStorage().remove(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void queueRemove(T obj) {
|
||||||
|
queue.add(Transaction.remove(obj));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the instance associated with an object.
|
* Update the instance associated with an object.
|
||||||
*
|
*
|
||||||
|
@ -91,10 +99,6 @@ public abstract class InstanceManager<T> {
|
||||||
queue.add(Transaction.update(obj));
|
queue.add(Transaction.update(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(T obj) {
|
|
||||||
getStorage().remove(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recreateAll() {
|
public void recreateAll() {
|
||||||
getStorage().recreateAll();
|
getStorage().recreateAll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
import com.jozufozu.flywheel.lib.format.AbstractVertexList;
|
import com.jozufozu.flywheel.lib.format.AbstractVertexList;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.function.Supplier;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.backend.Backend;
|
import com.jozufozu.flywheel.api.backend.Backend;
|
||||||
|
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||||
import com.jozufozu.flywheel.api.backend.Engine;
|
import com.jozufozu.flywheel.api.backend.Engine;
|
||||||
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
import com.jozufozu.flywheel.api.pipeline.Pipeline;
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ public class SimpleBackend implements Backend {
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private Component engineMessage;
|
private Component engineMessage;
|
||||||
private Function<LevelAccessor, Engine> engineFactory;
|
private Function<LevelAccessor, Engine> engineFactory;
|
||||||
private Supplier<Backend> fallback;
|
private Supplier<Backend> fallback = BackendManager::getOffBackend;
|
||||||
private BooleanSupplier isSupported;
|
private BooleanSupplier isSupported;
|
||||||
private Pipeline pipelineShader;
|
private Pipeline pipelineShader;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.lib.box;
|
package com.jozufozu.flywheel.lib.box;
|
||||||
|
|
||||||
import static com.jozufozu.flywheel.util.RenderMath.isPowerOf2;
|
import static com.jozufozu.flywheel.lib.math.RenderMath.isPowerOf2;
|
||||||
|
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.lib.box;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
@ -19,7 +19,6 @@ public class MutableBox implements ImmutableBox {
|
||||||
private int maxZ;
|
private int maxZ;
|
||||||
|
|
||||||
public MutableBox() {
|
public MutableBox() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MutableBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
public MutableBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
package com.jozufozu.flywheel.lib.context;
|
package com.jozufozu.flywheel.lib.context;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class Contexts {
|
public final class Contexts {
|
||||||
public static final SimpleContext WORLD = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.WORLD_FRAGMENT));
|
public static final SimpleContext WORLD = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.WORLD_FRAGMENT));
|
||||||
public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT));
|
public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT));
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Files {
|
public static final class Files {
|
||||||
public static final ResourceLocation WORLD_VERTEX = ResourceUtil.subPath(Names.WORLD, ".vert");
|
public static final ResourceLocation WORLD_VERTEX = ResourceUtil.subPath(Names.WORLD, ".vert");
|
||||||
public static final ResourceLocation WORLD_FRAGMENT = ResourceUtil.subPath(Names.WORLD, ".frag");
|
public static final ResourceLocation WORLD_FRAGMENT = ResourceUtil.subPath(Names.WORLD, ".frag");
|
||||||
public static final ResourceLocation CRUMBLING_VERTEX = ResourceUtil.subPath(Names.CRUMBLING, ".vert");
|
public static final ResourceLocation CRUMBLING_VERTEX = ResourceUtil.subPath(Names.CRUMBLING, ".vert");
|
||||||
public static final ResourceLocation CRUMBLING_FRAGMENT = ResourceUtil.subPath(Names.CRUMBLING, ".frag");
|
public static final ResourceLocation CRUMBLING_FRAGMENT = ResourceUtil.subPath(Names.CRUMBLING, ".frag");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
public static final class Names {
|
||||||
public static final ResourceLocation WORLD = Flywheel.rl("context/world");
|
public static final ResourceLocation WORLD = Flywheel.rl("context/world");
|
||||||
public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling");
|
public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.lib.format;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
package com.jozufozu.flywheel.lib.format;
|
package com.jozufozu.flywheel.lib.format;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class Formats {
|
public final class Formats {
|
||||||
public static final BlockVertex BLOCK = VertexType.REGISTRY.registerAndGet(new BlockVertex());
|
public static final BlockVertex BLOCK = VertexType.REGISTRY.registerAndGet(new BlockVertex());
|
||||||
public static final PosTexNormalVertex POS_TEX_NORMAL = VertexType.REGISTRY.registerAndGet(new PosTexNormalVertex());
|
public static final PosTexNormalVertex POS_TEX_NORMAL = VertexType.REGISTRY.registerAndGet(new PosTexNormalVertex());
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Files {
|
public static final class Files {
|
||||||
public static final ResourceLocation BLOCK_LAYOUT = ResourceUtil.subPath(Names.BLOCK, ".vert");
|
public static final ResourceLocation BLOCK_LAYOUT = ResourceUtil.subPath(Names.BLOCK, ".vert");
|
||||||
public static final ResourceLocation POS_TEX_NORMAL_LAYOUT = ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert");
|
public static final ResourceLocation POS_TEX_NORMAL_LAYOUT = ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
public static final class Names {
|
||||||
public static final ResourceLocation BLOCK = Flywheel.rl("layout/block");
|
public static final ResourceLocation BLOCK = Flywheel.rl("layout/block");
|
||||||
public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal");
|
public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal");
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.lib.format;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.jozufozu.flywheel.gl.array.VertexAttributeF;
|
||||||
import com.jozufozu.flywheel.gl.array.VertexAttributeI;
|
import com.jozufozu.flywheel.gl.array.VertexAttributeI;
|
||||||
|
|
||||||
public class CommonItems {
|
public class CommonItems {
|
||||||
|
|
||||||
private static final String VEC2_TYPE = "vec2";
|
private static final String VEC2_TYPE = "vec2";
|
||||||
private static final String VEC3_TYPE = "vec3";
|
private static final String VEC3_TYPE = "vec3";
|
||||||
private static final String VEC4_TYPE = "vec4";
|
private static final String VEC4_TYPE = "vec4";
|
||||||
|
@ -16,6 +15,7 @@ public class CommonItems {
|
||||||
private static final String FLOAT_TYPE = "float";
|
private static final String FLOAT_TYPE = "float";
|
||||||
private static final String UINT_TYPE = "uint";
|
private static final String UINT_TYPE = "uint";
|
||||||
private static final String LIGHT_COORD_TYPE = "LightCoord";
|
private static final String LIGHT_COORD_TYPE = "LightCoord";
|
||||||
|
|
||||||
public static final VecInput LIGHT_COORD = VecInput.builder()
|
public static final VecInput LIGHT_COORD = VecInput.builder()
|
||||||
.vertexAttribute(new VertexAttributeI(GlNumericType.USHORT, 2))
|
.vertexAttribute(new VertexAttributeI(GlNumericType.USHORT, 2))
|
||||||
.typeName(IVEC2_TYPE)
|
.typeName(IVEC2_TYPE)
|
||||||
|
@ -69,8 +69,4 @@ public class CommonItems {
|
||||||
|
|
||||||
public static final MatInput MAT3 = new MatInput(3, 3, "mat3", "Mat3F", "unpackMat3F");
|
public static final MatInput MAT3 = new MatInput(3, 3, "mat3", "Mat3F", "unpackMat3F");
|
||||||
public static final MatInput MAT4 = new MatInput(4, 4, "mat4", "Mat4F", "unpackMat4F");
|
public static final MatInput MAT4 = new MatInput(4, 4, "mat4", "Mat4F", "unpackMat4F");
|
||||||
|
|
||||||
private static class Unpacking {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.BackendUtil;
|
import com.jozufozu.flywheel.backend.task.FlwTaskExecutor;
|
||||||
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
import com.jozufozu.flywheel.lib.task.WorkGroup;
|
import com.jozufozu.flywheel.lib.task.WorkGroup;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
|
@ -23,7 +23,6 @@ import net.minecraft.world.level.LightLayer;
|
||||||
* {@link LightUpdated} for LightUpdater to work with them.
|
* {@link LightUpdated} for LightUpdater to work with them.
|
||||||
*/
|
*/
|
||||||
public class LightUpdater {
|
public class LightUpdater {
|
||||||
|
|
||||||
private static final WorldAttached<LightUpdater> LEVELS = new WorldAttached<>(LightUpdater::new);
|
private static final WorldAttached<LightUpdater> LEVELS = new WorldAttached<>(LightUpdater::new);
|
||||||
|
|
||||||
private final LevelAccessor level;
|
private final LevelAccessor level;
|
||||||
|
@ -68,7 +67,7 @@ public class LightUpdater {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.onComplete(() -> listeners.forEach(this::addListener))
|
.onComplete(() -> listeners.forEach(this::addListener))
|
||||||
.execute(BackendUtil.getTaskExecutor());
|
.execute(FlwTaskExecutor.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,7 +21,7 @@ import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
// TODO: add messages to exceptions
|
// TODO: add messages to exceptions
|
||||||
public class MaterialIndices {
|
public final class MaterialIndices {
|
||||||
private static Reference2IntMap<Material> materialIndices;
|
private static Reference2IntMap<Material> materialIndices;
|
||||||
private static Object2IntMap<ResourceLocation> vertexShaderIndices;
|
private static Object2IntMap<ResourceLocation> vertexShaderIndices;
|
||||||
private static Object2IntMap<ResourceLocation> fragmentShaderIndices;
|
private static Object2IntMap<ResourceLocation> fragmentShaderIndices;
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
package com.jozufozu.flywheel.lib.material;
|
package com.jozufozu.flywheel.lib.material;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
|
import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
|
||||||
import com.jozufozu.flywheel.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.lib.material.SimpleMaterial.GlStateShard;
|
import com.jozufozu.flywheel.lib.material.SimpleMaterial.GlStateShard;
|
||||||
|
import com.jozufozu.flywheel.lib.math.DiffuseLightCalculator;
|
||||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||||
import com.jozufozu.flywheel.util.DiffuseLightCalculator;
|
|
||||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
@ -18,7 +21,7 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.inventory.InventoryMenu;
|
import net.minecraft.world.inventory.InventoryMenu;
|
||||||
|
|
||||||
public final class Materials {
|
public final class Materials {
|
||||||
public static final Material.VertexTransformer SHADING_TRANSFORMER = (vertexList, level) -> {
|
public static final MaterialVertexTransformer SHADING_TRANSFORMER = (vertexList, level) -> {
|
||||||
if (ShadersModHandler.isShaderPackInUse()) {
|
if (ShadersModHandler.isShaderPackInUse()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -131,8 +134,8 @@ public final class Materials {
|
||||||
.batchingRenderType(RenderType.entitySolid(MINECART_LOCATION))
|
.batchingRenderType(RenderType.entitySolid(MINECART_LOCATION))
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Shards {
|
public static final class Shards {
|
||||||
|
@ -173,14 +176,14 @@ public final class Materials {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Files {
|
public static final class Files {
|
||||||
public static final ResourceLocation DEFAULT_VERTEX = ResourceUtil.subPath(Names.DEFAULT, ".vert");
|
public static final ResourceLocation DEFAULT_VERTEX = ResourceUtil.subPath(Names.DEFAULT, ".vert");
|
||||||
public static final ResourceLocation SHADED_VERTEX = ResourceUtil.subPath(Names.SHADED, ".vert");
|
public static final ResourceLocation SHADED_VERTEX = ResourceUtil.subPath(Names.SHADED, ".vert");
|
||||||
public static final ResourceLocation DEFAULT_FRAGMENT = ResourceUtil.subPath(Names.DEFAULT, ".frag");
|
public static final ResourceLocation DEFAULT_FRAGMENT = ResourceUtil.subPath(Names.DEFAULT, ".frag");
|
||||||
public static final ResourceLocation CUTOUT_FRAGMENT = ResourceUtil.subPath(Names.CUTOUT, ".frag");
|
public static final ResourceLocation CUTOUT_FRAGMENT = ResourceUtil.subPath(Names.CUTOUT, ".frag");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
public static final class Names {
|
||||||
public static final ResourceLocation DEFAULT = Flywheel.rl("material/default");
|
public static final ResourceLocation DEFAULT = Flywheel.rl("material/default");
|
||||||
public static final ResourceLocation CUTOUT = Flywheel.rl("material/cutout");
|
public static final ResourceLocation CUTOUT = Flywheel.rl("material/cutout");
|
||||||
public static final ResourceLocation SHADED = Flywheel.rl("material/shaded");
|
public static final ResourceLocation SHADED = Flywheel.rl("material/shaded");
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.jozufozu.flywheel.lib.material;
|
package com.jozufozu.flywheel.lib.material;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
|
import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderStateShard;
|
import net.minecraft.client.renderer.RenderStateShard;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
@ -12,9 +13,9 @@ public class SimpleMaterial implements Material {
|
||||||
protected final Runnable setup;
|
protected final Runnable setup;
|
||||||
protected final Runnable clear;
|
protected final Runnable clear;
|
||||||
protected final RenderType batchingRenderType;
|
protected final RenderType batchingRenderType;
|
||||||
protected final VertexTransformer vertexTransformer;
|
protected final MaterialVertexTransformer vertexTransformer;
|
||||||
|
|
||||||
public SimpleMaterial(ResourceLocation vertexShader, ResourceLocation fragmentShader, Runnable setup, Runnable clear, RenderType batchingRenderType, VertexTransformer vertexTransformer) {
|
public SimpleMaterial(ResourceLocation vertexShader, ResourceLocation fragmentShader, Runnable setup, Runnable clear, RenderType batchingRenderType, MaterialVertexTransformer vertexTransformer) {
|
||||||
this.vertexShader = vertexShader;
|
this.vertexShader = vertexShader;
|
||||||
this.fragmentShader = fragmentShader;
|
this.fragmentShader = fragmentShader;
|
||||||
this.setup = setup;
|
this.setup = setup;
|
||||||
|
@ -53,7 +54,7 @@ public class SimpleMaterial implements Material {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexTransformer getVertexTransformer() {
|
public MaterialVertexTransformer getVertexTransformer() {
|
||||||
return vertexTransformer;
|
return vertexTransformer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +64,7 @@ public class SimpleMaterial implements Material {
|
||||||
protected Runnable setup = () -> {};
|
protected Runnable setup = () -> {};
|
||||||
protected Runnable clear = () -> {};
|
protected Runnable clear = () -> {};
|
||||||
protected RenderType batchingRenderType = RenderType.solid();
|
protected RenderType batchingRenderType = RenderType.solid();
|
||||||
protected VertexTransformer vertexTransformer = (vertexList, level) -> {
|
protected MaterialVertexTransformer vertexTransformer = (vertexList, level) -> {};
|
||||||
};
|
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ public class SimpleMaterial implements Material {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder vertexTransformer(VertexTransformer vertexTransformer) {
|
public Builder vertexTransformer(MaterialVertexTransformer vertexTransformer) {
|
||||||
this.vertexTransformer = vertexTransformer;
|
this.vertexTransformer = vertexTransformer;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.util;
|
package com.jozufozu.flywheel.lib.math;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.util;
|
package com.jozufozu.flywheel.lib.math;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
@ -9,7 +9,37 @@ import com.jozufozu.flywheel.mixin.matrix.Matrix4fAccessor;
|
||||||
import com.mojang.math.Matrix3f;
|
import com.mojang.math.Matrix3f;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
|
|
||||||
public class MatrixUtil {
|
public final class MatrixUtil {
|
||||||
|
public static float transformPositionX(Matrix4f matrix, float x, float y, float z) {
|
||||||
|
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
||||||
|
return (m.flywheel$m00() * x) + (m.flywheel$m01() * y) + (m.flywheel$m02() * z) + m.flywheel$m03();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float transformPositionY(Matrix4f matrix, float x, float y, float z) {
|
||||||
|
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
||||||
|
return (m.flywheel$m10() * x) + (m.flywheel$m11() * y) + (m.flywheel$m12() * z) + m.flywheel$m13();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float transformPositionZ(Matrix4f matrix, float x, float y, float z) {
|
||||||
|
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
||||||
|
return (m.flywheel$m20() * x) + (m.flywheel$m21() * y) + (m.flywheel$m22() * z) + m.flywheel$m23();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float transformNormalX(Matrix3f matrix, float x, float y, float z) {
|
||||||
|
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
||||||
|
return (m.flywheel$m00() * x) + (m.flywheel$m01() * y) + (m.flywheel$m02() * z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float transformNormalY(Matrix3f matrix, float x, float y, float z) {
|
||||||
|
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
||||||
|
return (m.flywheel$m10() * x) + (m.flywheel$m11() * y) + (m.flywheel$m12() * z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float transformNormalZ(Matrix3f matrix, float x, float y, float z) {
|
||||||
|
Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
|
||||||
|
return (m.flywheel$m20() * x) + (m.flywheel$m21() * y) + (m.flywheel$m22() * z);
|
||||||
|
}
|
||||||
|
|
||||||
public static void write(Matrix4f matrix, ByteBuffer buf) {
|
public static void write(Matrix4f matrix, ByteBuffer buf) {
|
||||||
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
|
||||||
buf.putFloat(m.flywheel$m00());
|
buf.putFloat(m.flywheel$m00());
|
166
src/main/java/com/jozufozu/flywheel/lib/math/MoreMath.java
Normal file
166
src/main/java/com/jozufozu/flywheel/lib/math/MoreMath.java
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
package com.jozufozu.flywheel.lib.math;
|
||||||
|
|
||||||
|
import org.joml.Math;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
public final class MoreMath {
|
||||||
|
public static int align16(int numToRound) {
|
||||||
|
return (numToRound + 16 - 1) & -16;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int numDigits(int number) {
|
||||||
|
// cursed but allegedly the fastest algorithm, taken from https://www.baeldung.com/java-number-of-digits-in-int
|
||||||
|
if (number < 100000) {
|
||||||
|
if (number < 100) {
|
||||||
|
if (number < 10) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (number < 1000) {
|
||||||
|
return 3;
|
||||||
|
} else {
|
||||||
|
if (number < 10000) {
|
||||||
|
return 4;
|
||||||
|
} else {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (number < 10000000) {
|
||||||
|
if (number < 1000000) {
|
||||||
|
return 6;
|
||||||
|
} else {
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (number < 100000000) {
|
||||||
|
return 8;
|
||||||
|
} else {
|
||||||
|
if (number < 1000000000) {
|
||||||
|
return 9;
|
||||||
|
} else {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the frustum planes of the given projection matrix to the given buffer.<p>
|
||||||
|
* Uses a different format that is friendly towards an optimized instruction-parallel
|
||||||
|
* implementation of sphere-frustum intersection.<p>
|
||||||
|
* The format is as follows:<p>
|
||||||
|
* {@code vec4(nxX, pxX, nyX, pyX)}<br>
|
||||||
|
* {@code vec4(nxY, pxY, nyY, pyY)}<br>
|
||||||
|
* {@code vec4(nxZ, pxZ, nyZ, pyZ)}<br>
|
||||||
|
* {@code vec4(nxW, pxW, nyW, pyW)}<br>
|
||||||
|
* {@code vec2(nzX, pzX)}<br>
|
||||||
|
* {@code vec2(nzY, pzY)}<br>
|
||||||
|
* {@code vec2(nzZ, pzZ)}<br>
|
||||||
|
* {@code vec2(nzW, pzW)}<br>
|
||||||
|
* <p>
|
||||||
|
* Writes 96 bytes to the buffer.
|
||||||
|
*
|
||||||
|
* @param ptr The buffer to write the planes to.
|
||||||
|
* @param m The projection matrix to compute the frustum planes for.
|
||||||
|
*/
|
||||||
|
public static void writePackedFrustumPlanes(long ptr, Matrix4f m) {
|
||||||
|
float nxX, nxY, nxZ, nxW;
|
||||||
|
float pxX, pxY, pxZ, pxW;
|
||||||
|
float nyX, nyY, nyZ, nyW;
|
||||||
|
float pyX, pyY, pyZ, pyW;
|
||||||
|
float nzX, nzY, nzZ, nzW;
|
||||||
|
float pzX, pzY, pzZ, pzW;
|
||||||
|
|
||||||
|
float invl;
|
||||||
|
nxX = m.m03() + m.m00();
|
||||||
|
nxY = m.m13() + m.m10();
|
||||||
|
nxZ = m.m23() + m.m20();
|
||||||
|
nxW = m.m33() + m.m30();
|
||||||
|
invl = Math.invsqrt(nxX * nxX + nxY * nxY + nxZ * nxZ);
|
||||||
|
nxX *= invl;
|
||||||
|
nxY *= invl;
|
||||||
|
nxZ *= invl;
|
||||||
|
nxW *= invl;
|
||||||
|
|
||||||
|
pxX = m.m03() - m.m00();
|
||||||
|
pxY = m.m13() - m.m10();
|
||||||
|
pxZ = m.m23() - m.m20();
|
||||||
|
pxW = m.m33() - m.m30();
|
||||||
|
invl = Math.invsqrt(pxX * pxX + pxY * pxY + pxZ * pxZ);
|
||||||
|
pxX *= invl;
|
||||||
|
pxY *= invl;
|
||||||
|
pxZ *= invl;
|
||||||
|
pxW *= invl;
|
||||||
|
|
||||||
|
nyX = m.m03() + m.m01();
|
||||||
|
nyY = m.m13() + m.m11();
|
||||||
|
nyZ = m.m23() + m.m21();
|
||||||
|
nyW = m.m33() + m.m31();
|
||||||
|
invl = Math.invsqrt(nyX * nyX + nyY * nyY + nyZ * nyZ);
|
||||||
|
nyX *= invl;
|
||||||
|
nyY *= invl;
|
||||||
|
nyZ *= invl;
|
||||||
|
nyW *= invl;
|
||||||
|
|
||||||
|
pyX = m.m03() - m.m01();
|
||||||
|
pyY = m.m13() - m.m11();
|
||||||
|
pyZ = m.m23() - m.m21();
|
||||||
|
pyW = m.m33() - m.m31();
|
||||||
|
invl = Math.invsqrt(pyX * pyX + pyY * pyY + pyZ * pyZ);
|
||||||
|
pyX *= invl;
|
||||||
|
pyY *= invl;
|
||||||
|
pyZ *= invl;
|
||||||
|
pyW *= invl;
|
||||||
|
|
||||||
|
nzX = m.m03() + m.m02();
|
||||||
|
nzY = m.m13() + m.m12();
|
||||||
|
nzZ = m.m23() + m.m22();
|
||||||
|
nzW = m.m33() + m.m32();
|
||||||
|
invl = Math.invsqrt(nzX * nzX + nzY * nzY + nzZ * nzZ);
|
||||||
|
nzX *= invl;
|
||||||
|
nzY *= invl;
|
||||||
|
nzZ *= invl;
|
||||||
|
nzW *= invl;
|
||||||
|
|
||||||
|
pzX = m.m03() - m.m02();
|
||||||
|
pzY = m.m13() - m.m12();
|
||||||
|
pzZ = m.m23() - m.m22();
|
||||||
|
pzW = m.m33() - m.m32();
|
||||||
|
invl = Math.invsqrt(pzX * pzX + pzY * pzY + pzZ * pzZ);
|
||||||
|
pzX *= invl;
|
||||||
|
pzY *= invl;
|
||||||
|
pzZ *= invl;
|
||||||
|
pzW *= invl;
|
||||||
|
|
||||||
|
MemoryUtil.memPutFloat(ptr, nxX);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 4, pxX);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 8, nyX);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 12, pyX);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 16, nxY);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 20, pxY);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 24, nyY);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 28, pyY);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 32, nxZ);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 36, pxZ);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 40, nyZ);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 44, pyZ);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 48, nxW);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 52, pxW);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 56, nyW);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 60, pyW);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 64, nzX);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 68, pzX);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 72, nzY);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 76, pzY);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 80, nzZ);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 84, pzZ);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 88, nzW);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 92, pzW);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
package com.jozufozu.flywheel.util;
|
package com.jozufozu.flywheel.lib.math;
|
||||||
|
|
||||||
import net.minecraftforge.client.model.pipeline.LightUtil;
|
import net.minecraftforge.client.model.pipeline.LightUtil;
|
||||||
|
|
||||||
public class RenderMath {
|
public final class RenderMath {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a signed byte into a signed, normalized float.
|
* Convert a signed byte into a signed, normalized float.
|
||||||
*/
|
*/
|
|
@ -7,7 +7,7 @@ import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.StringUtil;
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
|
|
||||||
public class FlwMemoryTracker {
|
public final class FlwMemoryTracker {
|
||||||
public static final boolean DEBUG_MEMORY_SAFETY = System.getProperty("flw.debugMemorySafety") != null;
|
public static final boolean DEBUG_MEMORY_SAFETY = System.getProperty("flw.debugMemorySafety") != null;
|
||||||
|
|
||||||
static final Cleaner CLEANER = Cleaner.create();
|
static final Cleaner CLEANER = Cleaner.create();
|
||||||
|
|
|
@ -6,21 +6,21 @@ import java.nio.ByteBuffer;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import com.dreizak.miniball.highdim.Miniball;
|
import com.dreizak.miniball.highdim.Miniball;
|
||||||
import com.dreizak.miniball.model.PointSet;
|
import com.dreizak.miniball.model.PointSet;
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexList;
|
import com.jozufozu.flywheel.api.vertex.VertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexListProviderRegistry;
|
import com.jozufozu.flywheel.api.vertex.VertexListProviderRegistry;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.lib.format.Formats;
|
|
||||||
import com.jozufozu.flywheel.lib.material.Materials;
|
import com.jozufozu.flywheel.lib.material.Materials;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
|
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.mojang.logging.LogUtils;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
@ -28,7 +28,9 @@ import net.minecraft.client.renderer.block.BlockRenderDispatcher;
|
||||||
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
import net.minecraft.client.renderer.block.ModelBlockRenderer;
|
||||||
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
||||||
|
|
||||||
public class ModelUtil {
|
public final class ModelUtil {
|
||||||
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An alternative BlockRenderDispatcher that circumvents the Forge rendering pipeline to ensure consistency.
|
* An alternative BlockRenderDispatcher that circumvents the Forge rendering pipeline to ensure consistency.
|
||||||
* Meant to be used for virtual rendering.
|
* Meant to be used for virtual rendering.
|
||||||
|
@ -45,25 +47,24 @@ public class ModelUtil {
|
||||||
}
|
}
|
||||||
ObfuscationReflectionHelper.setPrivateValue(BlockRenderDispatcher.class, dispatcher, new ModelBlockRenderer(Minecraft.getInstance().getBlockColors()), "f_110900_");
|
ObfuscationReflectionHelper.setPrivateValue(BlockRenderDispatcher.class, dispatcher, new ModelBlockRenderer(Minecraft.getInstance().getBlockColors()), "f_110900_");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Flywheel.LOGGER.error("Failed to initialize vanilla BlockRenderDispatcher!", e);
|
LOGGER.error("Failed to initialize vanilla BlockRenderDispatcher!", e);
|
||||||
return defaultDispatcher;
|
return defaultDispatcher;
|
||||||
}
|
}
|
||||||
return dispatcher;
|
return dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Pair<VertexType, MemoryBlock> convertBlockBuffer(Pair<DrawState, ByteBuffer> pair) {
|
public static MemoryBlock convertVanillaBuffer(Pair<DrawState, ByteBuffer> pair, VertexType vertexType) {
|
||||||
DrawState drawState = pair.getFirst();
|
DrawState drawState = pair.getFirst();
|
||||||
int vertexCount = drawState.vertexCount();
|
int vertexCount = drawState.vertexCount();
|
||||||
VertexFormat srcFormat = drawState.format();
|
VertexFormat srcFormat = drawState.format();
|
||||||
VertexType dstVertexType = Formats.BLOCK;
|
|
||||||
|
|
||||||
ByteBuffer src = pair.getSecond();
|
ByteBuffer src = pair.getSecond();
|
||||||
MemoryBlock dst = MemoryBlock.malloc(vertexCount * dstVertexType.getLayout().getStride());
|
MemoryBlock dst = MemoryBlock.malloc(vertexCount * vertexType.getLayout().getStride());
|
||||||
long srcPtr = MemoryUtil.memAddress(src);
|
long srcPtr = MemoryUtil.memAddress(src);
|
||||||
long dstPtr = dst.ptr();
|
long dstPtr = dst.ptr();
|
||||||
|
|
||||||
ReusableVertexList srcList = VertexListProviderRegistry.getProvider(srcFormat).createVertexList();
|
ReusableVertexList srcList = VertexListProviderRegistry.getProvider(srcFormat).createVertexList();
|
||||||
ReusableVertexList dstList = dstVertexType.createVertexList();
|
ReusableVertexList dstList = vertexType.createVertexList();
|
||||||
srcList.ptr(srcPtr);
|
srcList.ptr(srcPtr);
|
||||||
dstList.ptr(dstPtr);
|
dstList.ptr(dstPtr);
|
||||||
srcList.vertexCount(vertexCount);
|
srcList.vertexCount(vertexCount);
|
||||||
|
@ -71,7 +72,7 @@ public class ModelUtil {
|
||||||
|
|
||||||
srcList.writeAll(dstList);
|
srcList.writeAll(dstList);
|
||||||
|
|
||||||
return Pair.of(dstVertexType, dst);
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -15,7 +15,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
public class Models {
|
public final class Models {
|
||||||
private static final Map<BlockState, Model> BLOCK_STATE = new HashMap<>();
|
private static final Map<BlockState, Model> BLOCK_STATE = new HashMap<>();
|
||||||
private static final Map<PartialModel, Model> PARTIAL = new HashMap<>();
|
private static final Map<PartialModel, Model> PARTIAL = new HashMap<>();
|
||||||
private static final Map<Pair<PartialModel, Direction>, Model> PARTIAL_DIR = new HashMap<>();
|
private static final Map<Pair<PartialModel, Direction>, Model> PARTIAL_DIR = new HashMap<>();
|
||||||
|
|
23
src/main/java/com/jozufozu/flywheel/lib/model/QuadMesh.java
Normal file
23
src/main/java/com/jozufozu/flywheel/lib/model/QuadMesh.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package com.jozufozu.flywheel.lib.model;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
|
import com.jozufozu.flywheel.gl.buffer.ElementBuffer;
|
||||||
|
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
||||||
|
|
||||||
|
public interface QuadMesh extends Mesh {
|
||||||
|
/**
|
||||||
|
* Create an element buffer object that indexes the vertices of this mesh.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Very often models in minecraft are made up of sequential quads, which is a very predictable pattern.
|
||||||
|
* The default implementation accommodates this, however this can be overridden to change the behavior and
|
||||||
|
* support more complex models.
|
||||||
|
* </p>
|
||||||
|
* @return an element buffer object indexing this model's vertices.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default ElementBuffer createEBO() {
|
||||||
|
return QuadConverter.getInstance()
|
||||||
|
.quads2Tris(getVertexCount() / 4);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,13 +3,12 @@ package com.jozufozu.flywheel.lib.model;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.joml.Vector4fc;
|
import org.joml.Vector4fc;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.api.vertex.VertexType;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
|
|
||||||
public class SimpleMesh implements Mesh {
|
public class SimpleMesh implements QuadMesh {
|
||||||
private final VertexType vertexType;
|
private final VertexType vertexType;
|
||||||
private final int vertexCount;
|
private final int vertexCount;
|
||||||
private final MemoryBlock contents;
|
private final MemoryBlock contents;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.function.BiFunction;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.lib.format.Formats;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
||||||
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
||||||
|
@ -20,7 +20,6 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
|
@ -106,8 +105,8 @@ public class BakedModelBuilder {
|
||||||
buffer.end();
|
buffer.end();
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
Material material = materialFunc.apply(renderType, shaded);
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
Pair<VertexType, MemoryBlock> pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
|
MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
|
||||||
meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
|
meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ModelBufferingUtil.bufferSingleShadeSeparated(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
|
ModelBufferingUtil.bufferSingleShadeSeparated(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
|
||||||
|
@ -121,8 +120,8 @@ public class BakedModelBuilder {
|
||||||
buffer.end();
|
buffer.end();
|
||||||
Material material = materialFunc.apply(renderType, false);
|
Material material = materialFunc.apply(renderType, false);
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
Pair<VertexType, MemoryBlock> pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
|
MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
|
||||||
meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString()));
|
meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ModelBufferingUtil.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer);
|
ModelBufferingUtil.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.function.BiFunction;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.lib.format.Formats;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
||||||
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
||||||
|
@ -20,7 +20,6 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
|
@ -95,8 +94,8 @@ public class BlockModelBuilder {
|
||||||
buffer.end();
|
buffer.end();
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
Material material = materialFunc.apply(renderType, shaded);
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
Pair<VertexType, MemoryBlock> pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
|
MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
|
||||||
meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "state=" + state.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
|
meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "state=" + state.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ModelBufferingUtil.bufferBlockShadeSeparated(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
|
ModelBufferingUtil.bufferBlockShadeSeparated(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
|
||||||
|
@ -110,8 +109,8 @@ public class BlockModelBuilder {
|
||||||
buffer.end();
|
buffer.end();
|
||||||
Material material = materialFunc.apply(renderType, false);
|
Material material = materialFunc.apply(renderType, false);
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
Pair<VertexType, MemoryBlock> pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
|
MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
|
||||||
meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "state=" + state.toString() + ",renderType=" + renderType.toString()));
|
meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "state=" + state.toString() + ",renderType=" + renderType.toString()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ModelBufferingUtil.bufferBlock(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer);
|
ModelBufferingUtil.bufferBlock(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.util.function.BiFunction;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.jozufozu.flywheel.api.material.Material;
|
import com.jozufozu.flywheel.api.material.Material;
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.vertex.VertexType;
|
import com.jozufozu.flywheel.lib.format.Formats;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
||||||
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
import com.jozufozu.flywheel.lib.model.SimpleMesh;
|
||||||
|
@ -22,7 +22,6 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -102,8 +101,8 @@ public class MultiBlockModelBuilder {
|
||||||
buffer.end();
|
buffer.end();
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
Material material = materialFunc.apply(renderType, shaded);
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
Pair<VertexType, MemoryBlock> pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
|
MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
|
||||||
meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "renderType=" + renderType.toString() + ",shaded=" + shaded));
|
meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "renderType=" + renderType.toString() + ",shaded=" + shaded));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ModelBufferingUtil.bufferMultiBlockShadeSeparated(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelDataMap, resultConsumer);
|
ModelBufferingUtil.bufferMultiBlockShadeSeparated(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelDataMap, resultConsumer);
|
||||||
|
@ -117,8 +116,8 @@ public class MultiBlockModelBuilder {
|
||||||
buffer.end();
|
buffer.end();
|
||||||
Material material = materialFunc.apply(renderType, false);
|
Material material = materialFunc.apply(renderType, false);
|
||||||
if (material != null) {
|
if (material != null) {
|
||||||
Pair<VertexType, MemoryBlock> pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
|
MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
|
||||||
meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "renderType=" + renderType.toString()));
|
meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "renderType=" + renderType.toString()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ModelBufferingUtil.bufferMultiBlock(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelDataMap, resultConsumer);
|
ModelBufferingUtil.bufferMultiBlock(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelDataMap, resultConsumer);
|
||||||
|
|
|
@ -5,22 +5,22 @@ import java.util.List;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.joml.Vector4fc;
|
import org.joml.Vector4fc;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.model.Mesh;
|
|
||||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||||
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
|
||||||
import com.jozufozu.flywheel.lib.format.Formats;
|
import com.jozufozu.flywheel.lib.format.Formats;
|
||||||
import com.jozufozu.flywheel.lib.format.PosTexNormalVertex;
|
import com.jozufozu.flywheel.lib.format.PosTexNormalVertex;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
import com.jozufozu.flywheel.lib.model.ModelUtil;
|
||||||
|
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
||||||
|
|
||||||
public class ModelPart implements Mesh {
|
public class ModelPart implements QuadMesh {
|
||||||
private final int vertexCount;
|
private final int vertexCount;
|
||||||
private final MemoryBlock contents;
|
private final MemoryBlock contents;
|
||||||
private final ReusableVertexList vertexList;
|
private final ReusableVertexList vertexList;
|
||||||
private final Vector4f boundingSphere;
|
private final Vector4f boundingSphere;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public ModelPart(List<PartBuilder.CuboidBuilder> cuboids, String name) {
|
public ModelPart(List<ModelPartBuilder.CuboidBuilder> cuboids, String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
this.vertexCount = countVertices(cuboids);
|
this.vertexCount = countVertices(cuboids);
|
||||||
|
@ -28,7 +28,7 @@ public class ModelPart implements Mesh {
|
||||||
contents = MemoryBlock.malloc(size());
|
contents = MemoryBlock.malloc(size());
|
||||||
long ptr = contents.ptr();
|
long ptr = contents.ptr();
|
||||||
VertexWriter writer = new VertexWriterImpl(ptr);
|
VertexWriter writer = new VertexWriterImpl(ptr);
|
||||||
for (PartBuilder.CuboidBuilder cuboid : cuboids) {
|
for (ModelPartBuilder.CuboidBuilder cuboid : cuboids) {
|
||||||
cuboid.write(writer);
|
cuboid.write(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ public class ModelPart implements Mesh {
|
||||||
boundingSphere = ModelUtil.computeBoundingSphere(vertexList);
|
boundingSphere = ModelUtil.computeBoundingSphere(vertexList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PartBuilder builder(String name, int sizeU, int sizeV) {
|
public static ModelPartBuilder builder(String name, int sizeU, int sizeV) {
|
||||||
return new PartBuilder(name, sizeU, sizeV);
|
return new ModelPartBuilder(name, sizeU, sizeV);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -78,9 +78,9 @@ public class ModelPart implements Mesh {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int countVertices(List<PartBuilder.CuboidBuilder> cuboids) {
|
private static int countVertices(List<ModelPartBuilder.CuboidBuilder> cuboids) {
|
||||||
int vertices = 0;
|
int vertices = 0;
|
||||||
for (PartBuilder.CuboidBuilder cuboid : cuboids) {
|
for (ModelPartBuilder.CuboidBuilder cuboid : cuboids) {
|
||||||
vertices += cuboid.vertices();
|
vertices += cuboid.vertices();
|
||||||
}
|
}
|
||||||
return vertices;
|
return vertices;
|
||||||
|
|
|
@ -12,8 +12,7 @@ import com.mojang.math.Vector3f;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
|
||||||
public class PartBuilder {
|
public class ModelPartBuilder {
|
||||||
|
|
||||||
private final float sizeU;
|
private final float sizeU;
|
||||||
private final float sizeV;
|
private final float sizeV;
|
||||||
|
|
||||||
|
@ -22,13 +21,13 @@ public class PartBuilder {
|
||||||
private final List<CuboidBuilder> cuboids = new ArrayList<>();
|
private final List<CuboidBuilder> cuboids = new ArrayList<>();
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public PartBuilder(String name, int sizeU, int sizeV) {
|
public ModelPartBuilder(String name, int sizeU, int sizeV) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.sizeU = (float) sizeU;
|
this.sizeU = (float) sizeU;
|
||||||
this.sizeV = (float) sizeV;
|
this.sizeV = (float) sizeV;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PartBuilder sprite(TextureAtlasSprite sprite) {
|
public ModelPartBuilder sprite(TextureAtlasSprite sprite) {
|
||||||
this.sprite = sprite;
|
this.sprite = sprite;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -41,36 +40,35 @@ public class PartBuilder {
|
||||||
return new ModelPart(cuboids, name);
|
return new ModelPart(cuboids, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PartBuilder addCuboid(CuboidBuilder builder) {
|
private ModelPartBuilder addCuboid(CuboidBuilder builder) {
|
||||||
cuboids.add(builder);
|
cuboids.add(builder);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CuboidBuilder {
|
public static class CuboidBuilder {
|
||||||
|
private TextureAtlasSprite sprite;
|
||||||
|
|
||||||
TextureAtlasSprite sprite;
|
private Set<Direction> visibleFaces = EnumSet.allOf(Direction.class);
|
||||||
|
private int textureOffsetU;
|
||||||
|
private int textureOffsetV;
|
||||||
|
|
||||||
Set<Direction> visibleFaces = EnumSet.allOf(Direction.class);
|
private float posX1;
|
||||||
int textureOffsetU;
|
private float posY1;
|
||||||
int textureOffsetV;
|
private float posZ1;
|
||||||
|
private float posX2;
|
||||||
|
private float posY2;
|
||||||
|
private float posZ2;
|
||||||
|
|
||||||
float posX1;
|
private boolean invertYZ;
|
||||||
float posY1;
|
|
||||||
float posZ1;
|
|
||||||
float posX2;
|
|
||||||
float posY2;
|
|
||||||
float posZ2;
|
|
||||||
|
|
||||||
boolean invertYZ;
|
private boolean useRotation;
|
||||||
|
private float rotationX;
|
||||||
|
private float rotationY;
|
||||||
|
private float rotationZ;
|
||||||
|
|
||||||
boolean useRotation;
|
private final ModelPartBuilder partBuilder;
|
||||||
float rotationX;
|
|
||||||
float rotationY;
|
|
||||||
float rotationZ;
|
|
||||||
|
|
||||||
final PartBuilder partBuilder;
|
private CuboidBuilder(ModelPartBuilder partBuilder) {
|
||||||
|
|
||||||
CuboidBuilder(PartBuilder partBuilder) {
|
|
||||||
this.partBuilder = partBuilder;
|
this.partBuilder = partBuilder;
|
||||||
this.sprite = partBuilder.sprite;
|
this.sprite = partBuilder.sprite;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +149,7 @@ public class PartBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PartBuilder endCuboid() {
|
public ModelPartBuilder endCuboid() {
|
||||||
return partBuilder.addCuboid(this);
|
return partBuilder.addCuboid(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,5 +252,4 @@ public class PartBuilder {
|
||||||
return v / partBuilder.sizeV;
|
return v / partBuilder.sizeV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ package com.jozufozu.flywheel.lib.modelpart;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
|
|
||||||
public class VertexWriterImpl implements VertexWriter {
|
public class VertexWriterImpl implements VertexWriter {
|
||||||
private long ptr;
|
private long ptr;
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
import com.jozufozu.flywheel.api.struct.Handle;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
|
||||||
public abstract class AbstractInstancePart implements InstancePart {
|
public abstract class AbstractInstancePart implements InstancePart {
|
||||||
|
protected final StructType<?> type;
|
||||||
public final StructType<?> type;
|
|
||||||
protected final Handle handle;
|
protected final Handle handle;
|
||||||
|
|
||||||
protected AbstractInstancePart(StructType<?> type, Handle handle) {
|
protected AbstractInstancePart(StructType<?> type, Handle handle) {
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
import com.jozufozu.flywheel.api.struct.Handle;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
|
|
||||||
public abstract class ColoredLitPart extends AbstractInstancePart implements FlatLit<ColoredLitPart> {
|
public abstract class ColoredLitPart extends AbstractInstancePart implements FlatLit<ColoredLitPart> {
|
||||||
|
|
||||||
public byte blockLight;
|
public byte blockLight;
|
||||||
public byte skyLight;
|
public byte skyLight;
|
||||||
|
|
||||||
|
@ -15,7 +14,7 @@ public abstract class ColoredLitPart extends AbstractInstancePart implements Fla
|
||||||
public byte b = (byte) 0xFF;
|
public byte b = (byte) 0xFF;
|
||||||
public byte a = (byte) 0xFF;
|
public byte a = (byte) 0xFF;
|
||||||
|
|
||||||
public ColoredLitPart(StructType<?> type, Handle handle) {
|
public ColoredLitPart(StructType<? extends ColoredLitPart> type, Handle handle) {
|
||||||
super(type, handle);
|
super(type, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +34,7 @@ public abstract class ColoredLitPart extends AbstractInstancePart implements Fla
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPackedLight() {
|
public int getPackedLight() {
|
||||||
return LightTexture.pack(this.blockLight, this.skyLight);
|
return LightTexture.pack(blockLight, skyLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ColoredLitPart setColor(int color) {
|
public ColoredLitPart setColor(int color) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancePart;
|
import com.jozufozu.flywheel.api.struct.InstancePart;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
import com.jozufozu.flywheel.api.struct.Handle;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
public class OrientedPart extends ColoredLitPart {
|
public class OrientedPart extends ColoredLitPart {
|
||||||
|
|
||||||
public float posX;
|
public float posX;
|
||||||
public float posY;
|
public float posY;
|
||||||
public float posZ;
|
public float posZ;
|
||||||
|
@ -19,8 +19,8 @@ public class OrientedPart extends ColoredLitPart {
|
||||||
public float qZ;
|
public float qZ;
|
||||||
public float qW = 1;
|
public float qW = 1;
|
||||||
|
|
||||||
public OrientedPart(Handle handle) {
|
public OrientedPart(StructType<? extends OrientedPart> type, Handle handle) {
|
||||||
super(StructTypes.ORIENTED, handle);
|
super(type, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrientedPart setPosition(BlockPos pos) {
|
public OrientedPart setPosition(BlockPos pos) {
|
||||||
|
@ -87,7 +87,7 @@ public class OrientedPart extends ColoredLitPart {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrientedPart copy(Handle handle) {
|
public OrientedPart copy(Handle handle) {
|
||||||
var out = new OrientedPart(handle);
|
var out = StructTypes.ORIENTED.create(handle);
|
||||||
out.posX = this.posX;
|
out.posX = this.posX;
|
||||||
out.posY = this.posY;
|
out.posY = this.posY;
|
||||||
out.posZ = this.posZ;
|
out.posZ = this.posZ;
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
|
||||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.api.struct.Handle;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructVertexTransformer;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
|
import com.jozufozu.flywheel.lib.vertex.VertexTransformations;
|
||||||
import com.mojang.math.Matrix3f;
|
import com.mojang.math.Matrix3f;
|
||||||
import com.mojang.math.Matrix4f;
|
import com.mojang.math.Matrix4f;
|
||||||
import com.mojang.math.Quaternion;
|
import com.mojang.math.Quaternion;
|
||||||
import com.mojang.math.Vector3f;
|
|
||||||
import com.mojang.math.Vector4f;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class OrientedType implements StructType<OrientedPart> {
|
public class OrientedType implements StructType<OrientedPart> {
|
||||||
|
|
||||||
public static final BufferLayout FORMAT = BufferLayout.builder()
|
public static final BufferLayout FORMAT = BufferLayout.builder()
|
||||||
.addItem(CommonItems.LIGHT_COORD, "light")
|
.addItem(CommonItems.LIGHT_COORD, "light")
|
||||||
.addItem(CommonItems.UNORM_4x8, "color")
|
.addItem(CommonItems.UNORM_4x8, "color")
|
||||||
|
@ -26,7 +25,7 @@ public class OrientedType implements StructType<OrientedPart> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrientedPart create(Handle handle) {
|
public OrientedPart create(Handle handle) {
|
||||||
return new OrientedPart(handle);
|
return new OrientedPart(this, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,11 +44,8 @@ public class OrientedType implements StructType<OrientedPart> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexTransformer<OrientedPart> getVertexTransformer() {
|
public StructVertexTransformer<OrientedPart> getVertexTransformer() {
|
||||||
return (vertexList, struct, level) -> {
|
return (vertexList, struct, level) -> {
|
||||||
Vector4f pos = new Vector4f();
|
|
||||||
Vector3f normal = new Vector3f();
|
|
||||||
|
|
||||||
Quaternion q = new Quaternion(struct.qX, struct.qY, struct.qZ, struct.qW);
|
Quaternion q = new Quaternion(struct.qX, struct.qY, struct.qZ, struct.qW);
|
||||||
|
|
||||||
Matrix4f modelMatrix = new Matrix4f();
|
Matrix4f modelMatrix = new Matrix4f();
|
||||||
|
@ -67,27 +63,8 @@ public class OrientedType implements StructType<OrientedPart> {
|
||||||
int light = struct.getPackedLight();
|
int light = struct.getPackedLight();
|
||||||
|
|
||||||
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
||||||
pos.set(
|
VertexTransformations.transformPos(vertexList, i, modelMatrix);
|
||||||
vertexList.x(i),
|
VertexTransformations.transformNormal(vertexList, i, normalMatrix);
|
||||||
vertexList.y(i),
|
|
||||||
vertexList.z(i),
|
|
||||||
1f
|
|
||||||
);
|
|
||||||
pos.transform(modelMatrix);
|
|
||||||
vertexList.x(i, pos.x());
|
|
||||||
vertexList.y(i, pos.y());
|
|
||||||
vertexList.z(i, pos.z());
|
|
||||||
|
|
||||||
normal.set(
|
|
||||||
vertexList.normalX(i),
|
|
||||||
vertexList.normalY(i),
|
|
||||||
vertexList.normalZ(i)
|
|
||||||
);
|
|
||||||
normal.transform(normalMatrix);
|
|
||||||
normal.normalize();
|
|
||||||
vertexList.normalX(i, normal.x());
|
|
||||||
vertexList.normalY(i, normal.y());
|
|
||||||
vertexList.normalZ(i, normal.z());
|
|
||||||
|
|
||||||
vertexList.r(i, r);
|
vertexList.r(i, r);
|
||||||
vertexList.g(i, g);
|
vertexList.g(i, g);
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.util.ResourceUtil;
|
import com.jozufozu.flywheel.util.ResourceUtil;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class StructTypes {
|
public final class StructTypes {
|
||||||
public static final StructType<TransformedPart> TRANSFORMED = StructType.REGISTRY.registerAndGet(new TransformedType());
|
public static final StructType<TransformedPart> TRANSFORMED = StructType.REGISTRY.registerAndGet(new TransformedType());
|
||||||
public static final StructType<OrientedPart> ORIENTED = StructType.REGISTRY.registerAndGet(new OrientedType());
|
public static final StructType<OrientedPart> ORIENTED = StructType.REGISTRY.registerAndGet(new OrientedType());
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// noop
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Files {
|
public static final class Files {
|
||||||
public static final ResourceLocation TRANSFORMED = ResourceUtil.subPath(Names.TRANSFORMED, ".vert");
|
public static final ResourceLocation TRANSFORMED = ResourceUtil.subPath(Names.TRANSFORMED, ".vert");
|
||||||
public static final ResourceLocation ORIENTED = ResourceUtil.subPath(Names.ORIENTED, ".vert");
|
public static final ResourceLocation ORIENTED = ResourceUtil.subPath(Names.ORIENTED, ".vert");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Names {
|
public static final class Names {
|
||||||
public static final ResourceLocation TRANSFORMED = Flywheel.rl("instance/transformed");
|
public static final ResourceLocation TRANSFORMED = Flywheel.rl("instance/transformed");
|
||||||
public static final ResourceLocation ORIENTED = Flywheel.rl("instance/oriented");
|
public static final ResourceLocation ORIENTED = Flywheel.rl("instance/oriented");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
import com.jozufozu.flywheel.api.struct.Handle;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
import com.jozufozu.flywheel.lib.transform.Transform;
|
import com.jozufozu.flywheel.lib.transform.Transform;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Matrix3f;
|
import com.mojang.math.Matrix3f;
|
||||||
|
@ -16,8 +17,8 @@ public class TransformedPart extends ColoredLitPart implements Transform<Transfo
|
||||||
public final Matrix4f model = new Matrix4f();
|
public final Matrix4f model = new Matrix4f();
|
||||||
public final Matrix3f normal = new Matrix3f();
|
public final Matrix3f normal = new Matrix3f();
|
||||||
|
|
||||||
public TransformedPart(Handle handle) {
|
public TransformedPart(StructType<? extends TransformedPart> type, Handle handle) {
|
||||||
super(StructTypes.TRANSFORMED, handle);
|
super(type, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransformedPart setTransform(PoseStack stack) {
|
public TransformedPart setTransform(PoseStack stack) {
|
||||||
|
@ -106,7 +107,7 @@ public class TransformedPart extends ColoredLitPart implements Transform<Transfo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TransformedPart copy(Handle handle) {
|
public TransformedPart copy(Handle handle) {
|
||||||
var out = new TransformedPart(handle);
|
var out = StructTypes.TRANSFORMED.create(handle);
|
||||||
out.model.load(this.model);
|
out.model.load(this.model);
|
||||||
out.normal.load(this.normal);
|
out.normal.load(this.normal);
|
||||||
out.r = this.r;
|
out.r = this.r;
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.Handle;
|
|
||||||
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
import com.jozufozu.flywheel.api.layout.BufferLayout;
|
||||||
|
import com.jozufozu.flywheel.api.struct.Handle;
|
||||||
import com.jozufozu.flywheel.api.struct.StructType;
|
import com.jozufozu.flywheel.api.struct.StructType;
|
||||||
|
import com.jozufozu.flywheel.api.struct.StructVertexTransformer;
|
||||||
import com.jozufozu.flywheel.api.struct.StructWriter;
|
import com.jozufozu.flywheel.api.struct.StructWriter;
|
||||||
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
||||||
import com.jozufozu.flywheel.util.RenderMath;
|
import com.jozufozu.flywheel.lib.math.RenderMath;
|
||||||
import com.mojang.math.Vector3f;
|
import com.jozufozu.flywheel.lib.vertex.VertexTransformations;
|
||||||
import com.mojang.math.Vector4f;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public class TransformedType implements StructType<TransformedPart> {
|
public class TransformedType implements StructType<TransformedPart> {
|
||||||
|
|
||||||
public static final BufferLayout FORMAT = BufferLayout.builder()
|
public static final BufferLayout FORMAT = BufferLayout.builder()
|
||||||
.addItem(CommonItems.LIGHT_COORD, "light")
|
.addItem(CommonItems.LIGHT_COORD, "light")
|
||||||
.addItem(CommonItems.UNORM_4x8, "color")
|
.addItem(CommonItems.UNORM_4x8, "color")
|
||||||
|
@ -22,7 +21,7 @@ public class TransformedType implements StructType<TransformedPart> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TransformedPart create(Handle handle) {
|
public TransformedPart create(Handle handle) {
|
||||||
return new TransformedPart(handle);
|
return new TransformedPart(this, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,11 +40,8 @@ public class TransformedType implements StructType<TransformedPart> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexTransformer<TransformedPart> getVertexTransformer() {
|
public StructVertexTransformer<TransformedPart> getVertexTransformer() {
|
||||||
return (vertexList, struct, level) -> {
|
return (vertexList, struct, level) -> {
|
||||||
Vector4f pos = new Vector4f();
|
|
||||||
Vector3f normal = new Vector3f();
|
|
||||||
|
|
||||||
float r = RenderMath.uf(struct.r);
|
float r = RenderMath.uf(struct.r);
|
||||||
float g = RenderMath.uf(struct.g);
|
float g = RenderMath.uf(struct.g);
|
||||||
float b = RenderMath.uf(struct.b);
|
float b = RenderMath.uf(struct.b);
|
||||||
|
@ -53,27 +49,8 @@ public class TransformedType implements StructType<TransformedPart> {
|
||||||
int light = struct.getPackedLight();
|
int light = struct.getPackedLight();
|
||||||
|
|
||||||
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
for (int i = 0; i < vertexList.vertexCount(); i++) {
|
||||||
pos.set(
|
VertexTransformations.transformPos(vertexList, i, struct.model);
|
||||||
vertexList.x(i),
|
VertexTransformations.transformNormal(vertexList, i, struct.normal);
|
||||||
vertexList.y(i),
|
|
||||||
vertexList.z(i),
|
|
||||||
1f
|
|
||||||
);
|
|
||||||
pos.transform(struct.model);
|
|
||||||
vertexList.x(i, pos.x());
|
|
||||||
vertexList.y(i, pos.y());
|
|
||||||
vertexList.z(i, pos.z());
|
|
||||||
|
|
||||||
normal.set(
|
|
||||||
vertexList.normalX(i),
|
|
||||||
vertexList.normalY(i),
|
|
||||||
vertexList.normalZ(i)
|
|
||||||
);
|
|
||||||
normal.transform(struct.normal);
|
|
||||||
normal.normalize();
|
|
||||||
vertexList.normalX(i, normal.x());
|
|
||||||
vertexList.normalY(i, normal.y());
|
|
||||||
vertexList.normalZ(i, normal.z());
|
|
||||||
|
|
||||||
vertexList.r(i, r);
|
vertexList.r(i, r);
|
||||||
vertexList.g(i, g);
|
vertexList.g(i, g);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.jozufozu.flywheel.lib.struct;
|
package com.jozufozu.flywheel.lib.struct;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.MatrixUtil;
|
import com.jozufozu.flywheel.lib.math.MatrixUtil;
|
||||||
|
|
||||||
public class TransformedWriter extends ColoredLitWriter<TransformedPart> {
|
public class TransformedWriter extends ColoredLitWriter<TransformedPart> {
|
||||||
public static final TransformedWriter INSTANCE = new TransformedWriter();
|
public static final TransformedWriter INSTANCE = new TransformedWriter();
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class WorkGroup {
|
public final class WorkGroup {
|
||||||
public static void run(Iterator<Runnable> tasks, Executor executor) {
|
public static void run(Iterator<Runnable> tasks, Executor executor) {
|
||||||
tasks.forEachRemaining(executor::execute);
|
tasks.forEachRemaining(executor::execute);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
||||||
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
import com.jozufozu.flywheel.lib.math.MatrixUtil;
|
||||||
import com.jozufozu.flywheel.util.MatrixUtil;
|
import com.jozufozu.flywheel.lib.math.MoreMath;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
|
@ -134,7 +134,7 @@ public class FlwShaderUniforms implements ShaderUniforms {
|
||||||
var projection = MatrixUtil.toJoml(context.viewProjection());
|
var projection = MatrixUtil.toJoml(context.viewProjection());
|
||||||
projection.translate(-camX, -camY, -camZ);
|
projection.translate(-camX, -camY, -camZ);
|
||||||
|
|
||||||
FlwUtil.writePackedFrustumPlanes(ptr + 128, projection);
|
MoreMath.writePackedFrustumPlanes(ptr + 128, projection);
|
||||||
|
|
||||||
FRUSTUM_CAPTURE = false;
|
FRUSTUM_CAPTURE = false;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue