Sanstexts

- Add EmbeddedLevel to api
- Move all context api/lib stuffs into backend
- Move context shaders into internal
- Inline Shader and TextureSource interfaces
- Move matrix bounding sphere transform into util
- Add uniforms to cull shader to allow it to work with embedded levels
- Engine has 2 instancer methods, one that accepts an EmbeddedLevel and
  one without the parameter
- Change VisualizationContext#withContext to #embed
- Remove crumbling stuff from Contexts
This commit is contained in:
Jozufozu 2024-02-25 15:42:20 -08:00
parent 94ae32b9a7
commit e55d506511
45 changed files with 261 additions and 223 deletions

View File

@ -11,6 +11,7 @@ import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.backend.Backends;
import com.jozufozu.flywheel.backend.ShaderIndices;
import com.jozufozu.flywheel.backend.compile.FlwPrograms;
import com.jozufozu.flywheel.backend.context.ContextShaders;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
import com.jozufozu.flywheel.config.BackendArgument;
import com.jozufozu.flywheel.config.FlwCommands;
@ -19,7 +20,6 @@ import com.jozufozu.flywheel.impl.BackendManagerImpl;
import com.jozufozu.flywheel.impl.registry.IdRegistryImpl;
import com.jozufozu.flywheel.impl.registry.RegistryImpl;
import com.jozufozu.flywheel.impl.visualization.VisualizationEventHandler;
import com.jozufozu.flywheel.lib.context.ContextShaders;
import com.jozufozu.flywheel.lib.instance.InstanceTypes;
import com.jozufozu.flywheel.lib.material.CutoutShaders;
import com.jozufozu.flywheel.lib.material.FogShaders;

View File

@ -3,7 +3,6 @@ package com.jozufozu.flywheel.api.backend;
import java.util.List;
import com.jozufozu.flywheel.api.BackendImplemented;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
@ -13,6 +12,7 @@ import com.jozufozu.flywheel.api.instance.InstancerProvider;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.api.task.Plan;
import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
import net.minecraft.client.Camera;
import net.minecraft.core.BlockPos;
@ -32,7 +32,9 @@ public interface Engine {
* @return An instancer for the given instance type, model, and render stage.
* @see InstancerProvider
*/
<I extends Instance> Instancer<I> instancer(InstanceType<I> type, Context context, Model model, RenderStage stage);
<I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model, RenderStage stage);
<I extends Instance> Instancer<I> instancer(EmbeddedLevel world, InstanceType<I> type, Model model, RenderStage stage);
/**
* Create a plan that will be executed every frame.

View File

@ -1,20 +0,0 @@
package com.jozufozu.flywheel.api.context;
import org.joml.Matrix4fc;
import com.jozufozu.flywheel.api.BackendImplemented;
@BackendImplemented
public interface Shader {
void setTexture(String glslName, Texture texture);
void setFloat(String glslName, float value);
void setVec2(String glslName, float x, float y);
void setVec3(String glslName, float x, float y, float z);
void setVec4(String glslName, float x, float y, float z, float w);
void setMat4(String glslName, Matrix4fc matrix);
}

View File

@ -1,32 +0,0 @@
package com.jozufozu.flywheel.api.context;
import com.jozufozu.flywheel.api.BackendImplemented;
import net.minecraft.resources.ResourceLocation;
@BackendImplemented
public interface TextureSource {
/**
* Get a built-in texture by its resource location.
*
* @param texture The texture's resource location.
* @return The texture.
*/
Texture byName(ResourceLocation texture);
/**
* Get the overlay texture.
*
* @return The overlay texture.
*/
Texture overlay();
/**
* Get the light texture.
*
* @return The light texture.
*/
Texture light();
// TODO: Allow creating dynamic textures.
}

View File

@ -0,0 +1,11 @@
package com.jozufozu.flywheel.api.visualization;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.phys.AABB;
public interface EmbeddedLevel {
void transform(PoseStack stack);
AABB boundingBox();
}

View File

@ -2,8 +2,8 @@ package com.jozufozu.flywheel.api.visualization;
import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstancerProvider;
import com.jozufozu.flywheel.backend.context.Context;
import net.minecraft.core.Vec3i;
@ -32,5 +32,5 @@ public interface VisualizationContext {
* @return A new {@link VisualizationContext} for use with child visuals.
*/
@ApiStatus.Experimental
VisualizationContext withContext(Context context, Vec3i renderOrigin);
VisualizationContext embed(EmbeddedLevel world);
}

View File

@ -8,12 +8,12 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.ContextShader;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.ShaderIndices;
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
import com.jozufozu.flywheel.backend.context.ContextShader;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
import com.jozufozu.flywheel.backend.glsl.generate.FnSignature;

View File

@ -7,11 +7,11 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.ContextShader;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
import com.jozufozu.flywheel.backend.compile.core.Compile;
import com.jozufozu.flywheel.backend.context.ContextShader;
import com.jozufozu.flywheel.backend.gl.GlCompat;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;

View File

@ -6,8 +6,8 @@ import java.util.Map;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.api.context.ContextShader;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.context.ContextShader;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
import com.jozufozu.flywheel.backend.glsl.SourceComponent;

View File

@ -1,7 +1,7 @@
package com.jozufozu.flywheel.backend.compile;
import com.jozufozu.flywheel.api.context.ContextShader;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.context.ContextShader;
/**
* Represents the entire context of a program's usage.

View File

@ -1,6 +1,8 @@
package com.jozufozu.flywheel.api.context;
package com.jozufozu.flywheel.backend.context;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
public interface Context {
ContextShader contextShader();
@ -12,5 +14,5 @@ public interface Context {
* @param shader The shader to prepare.
* @param textureSource Source of the textures to use.
*/
void prepare(Material material, Shader shader, TextureSource textureSource);
void prepare(Material material, GlProgram shader, TextureSource textureSource);
}

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.api.context;
package com.jozufozu.flywheel.backend.context;
import com.jozufozu.flywheel.api.internal.InternalFlywheelApi;
import com.jozufozu.flywheel.api.registry.Registry;

View File

@ -0,0 +1,18 @@
package com.jozufozu.flywheel.backend.context;
import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.Flywheel;
public class ContextShaders {
public static final SimpleContextShader DEFAULT = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("internal/context/default.vert"), Flywheel.rl("internal/context/default.frag")));
public static final SimpleContextShader CRUMBLING = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("internal/context/crumbling.vert"), Flywheel.rl("internal/context/crumbling.frag")));
public static final SimpleContextShader EMBEDDED = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("internal/context/embedded.vert"), Flywheel.rl("internal/context/embedded.frag")));
private ContextShaders() {
}
@ApiStatus.Internal
public static void init() {
}
}

View File

@ -0,0 +1,9 @@
package com.jozufozu.flywheel.backend.context;
public final class Contexts {
public static final Context DEFAULT = SimpleContext.builder(ContextShaders.DEFAULT)
.build();
private Contexts() {
}
}

View File

@ -0,0 +1,33 @@
package com.jozufozu.flywheel.backend.context;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.mojang.blaze3d.vertex.PoseStack;
public class EmbeddedContext implements Context {
private final EmbeddedLevel world;
public EmbeddedContext(EmbeddedLevel world) {
this.world = world;
}
@Override
public ContextShader contextShader() {
return ContextShaders.EMBEDDED;
}
@Override
public void prepare(Material material, GlProgram shader, TextureSource textureSource) {
var stack = new PoseStack();
world.transform(stack);
// shader.setVec3("create_oneOverLightBoxSize");
// shader.setVec3("create_lightVolumeMin");
shader.setMat4("_flw_model", stack.last()
.pose());
shader.setMat3("_flw_normal", stack.last()
.normal());
}
}

View File

@ -1,12 +1,10 @@
package com.jozufozu.flywheel.lib.context;
package com.jozufozu.flywheel.backend.context;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.context.ContextShader;
import com.jozufozu.flywheel.api.context.Shader;
import com.jozufozu.flywheel.api.context.TextureSource;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
public class SimpleContext implements Context {
private final ContextShader contextShader;
@ -27,13 +25,13 @@ public class SimpleContext implements Context {
}
@Override
public void prepare(Material material, Shader shader, TextureSource textureSource) {
public void prepare(Material material, GlProgram shader, TextureSource textureSource) {
preparation.prepare(material, shader, textureSource);
}
@FunctionalInterface
public interface Preparation {
void prepare(Material material, Shader shader, TextureSource textureSource);
void prepare(Material material, GlProgram shader, TextureSource textureSource);
}
public static class Builder {

View File

@ -1,6 +1,4 @@
package com.jozufozu.flywheel.lib.context;
import com.jozufozu.flywheel.api.context.ContextShader;
package com.jozufozu.flywheel.backend.context;
import net.minecraft.resources.ResourceLocation;

View File

@ -1,4 +1,4 @@
package com.jozufozu.flywheel.api.context;
package com.jozufozu.flywheel.backend.context;
import com.jozufozu.flywheel.api.BackendImplemented;

View File

@ -1,12 +1,14 @@
package com.jozufozu.flywheel.backend.engine;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.Instancer;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
import com.jozufozu.flywheel.backend.context.Contexts;
import com.jozufozu.flywheel.backend.context.EmbeddedContext;
import net.minecraft.client.Camera;
import net.minecraft.core.BlockPos;
@ -22,8 +24,13 @@ public abstract class AbstractEngine implements Engine {
}
@Override
public <I extends Instance> Instancer<I> instancer(InstanceType<I> type, Context context, Model model, RenderStage stage) {
return getStorage().getInstancer(type, context, model, stage);
public <I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model, RenderStage stage) {
return getStorage().getInstancer(type, Contexts.DEFAULT, model, stage);
}
@Override
public <I extends Instance> Instancer<I> instancer(EmbeddedLevel world, InstanceType<I> type, Model model, RenderStage stage) {
return getStorage().getInstancer(type, new EmbeddedContext(world), model, stage);
}
@Override

View File

@ -2,10 +2,10 @@ package com.jozufozu.flywheel.backend.engine;
import java.util.ArrayList;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.Instancer;
import com.jozufozu.flywheel.backend.context.Context;
import com.jozufozu.flywheel.lib.util.AtomicBitset;
public abstract class AbstractInstancer<I extends Instance> implements Instancer<I> {

View File

@ -1,10 +1,10 @@
package com.jozufozu.flywheel.backend.engine;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.backend.context.Context;
public record InstancerKey<I extends Instance>(InstanceType<I> type, Context context, Model model, RenderStage stage) {
}

View File

@ -6,12 +6,12 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.Instancer;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.backend.context.Context;
public abstract class InstancerStorage<N extends AbstractInstancer<?>> {
/**

View File

@ -16,22 +16,22 @@ import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
import com.jozufozu.flywheel.backend.context.Context;
import com.jozufozu.flywheel.backend.context.SimpleContextShader;
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
import com.jozufozu.flywheel.backend.engine.MeshPool;
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
import com.jozufozu.flywheel.backend.engine.textures.TextureSourceImpl;
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
import com.jozufozu.flywheel.backend.gl.Driver;
import com.jozufozu.flywheel.backend.gl.GlCompat;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.lib.context.SimpleContextShader;
public class IndirectCullingGroup<I extends Instance> {
private static final Comparator<IndirectDraw> DRAW_COMPARATOR = Comparator.comparing(IndirectDraw::stage)
@ -191,7 +191,7 @@ public class IndirectCullingGroup<I extends Instance> {
needsDrawSort = true;
}
public void submit(RenderStage stage, TextureSourceImpl textures) {
public void submit(RenderStage stage, TextureSource textures) {
if (nothingToDo(stage)) {
return;
}

View File

@ -12,11 +12,12 @@ import java.util.List;
import java.util.Map;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
import com.jozufozu.flywheel.backend.context.Context;
import com.jozufozu.flywheel.backend.context.ContextShaders;
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
import com.jozufozu.flywheel.backend.engine.InstancerKey;
@ -24,14 +25,12 @@ import com.jozufozu.flywheel.backend.engine.InstancerStorage;
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
import com.jozufozu.flywheel.backend.engine.MeshPool;
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
import com.jozufozu.flywheel.backend.engine.textures.TextureSourceImpl;
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.lib.context.ContextShaders;
import com.jozufozu.flywheel.lib.context.Contexts;
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.jozufozu.flywheel.lib.util.Pair;
@ -45,7 +44,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
private final StagingBuffer stagingBuffer;
private final MeshPool meshPool;
private final GlVertexArray vertexArray;
private final TextureSourceImpl textures = new TextureSourceImpl();
private final TextureSource textures = new TextureSource();
private final Map<GroupKey<?>, IndirectCullingGroup<?>> cullingGroups = new HashMap<>();
private final GlBuffer crumblingDrawBuffer = new GlBuffer();
@ -169,6 +168,8 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
.bindWithContextShader(ContextShaders.CRUMBLING);
for (var progressEntry : byProgress.int2ObjectEntrySet()) {
program.setTexture("crumblingTex", textures.byName(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())));
for (var instanceHandlePair : progressEntry.getValue()) {
IndirectInstancer<?> instancer = instanceHandlePair.first();
int instanceIndex = instanceHandlePair.second().index;
@ -177,9 +178,7 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
// Transform the material to be suited for crumbling.
CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material());
var context = Contexts.CRUMBLING.get(progressEntry.getIntKey());
context.prepare(crumblingMaterial, program, textures);
MaterialRenderState.setup(crumblingMaterial);
// Upload the draw command.
@ -188,10 +187,10 @@ public class IndirectDrawManager extends InstancerStorage<IndirectInstancer<?>>
// Submit! Everything is already bound by here.
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
TextureBinder.resetTextureBindings();
}
}
TextureBinder.resetTextureBindings();
}
}

View File

@ -6,11 +6,11 @@ import java.util.List;
import org.joml.Vector4fc;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.InstanceWriter;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.backend.context.Context;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I> {

View File

@ -20,6 +20,7 @@ import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.backend.ShaderIndices;
import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
import com.jozufozu.flywheel.backend.context.ContextShaders;
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
import com.jozufozu.flywheel.backend.engine.InstancerKey;
@ -28,15 +29,13 @@ import com.jozufozu.flywheel.backend.engine.MaterialEncoder;
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
import com.jozufozu.flywheel.backend.engine.MeshPool;
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
import com.jozufozu.flywheel.backend.engine.textures.TextureSourceImpl;
import com.jozufozu.flywheel.backend.engine.textures.TextureSource;
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
import com.jozufozu.flywheel.backend.gl.TextureBuffer;
import com.jozufozu.flywheel.backend.gl.array.GlVertexArray;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
import com.jozufozu.flywheel.lib.context.ContextShaders;
import com.jozufozu.flywheel.lib.context.Contexts;
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
@ -54,7 +53,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
*/
private final MeshPool meshPool;
private final GlVertexArray vao;
private final TextureSourceImpl textures;
private final TextureSource textures;
private final TextureBuffer instanceTexture;
public InstancedDrawManager(InstancingPrograms programs) {
@ -63,7 +62,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
meshPool = new MeshPool();
vao = GlVertexArray.create();
textures = new TextureSourceImpl();
textures = new TextureSource();
instanceTexture = new TextureBuffer();
meshPool.bind(vao);
@ -223,8 +222,7 @@ public class InstancedDrawManager extends InstancerStorage<InstancedInstancer<?>
continue;
}
var context = Contexts.CRUMBLING.get(progressEntry.getIntKey());
context.prepare(crumblingMaterial, program, textures);
program.setTexture("crumblingTex", textures.byName(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())));
GlTextureUnit.T3.makeActive();
program.setSamplerBinding("_flw_instances", 3);

View File

@ -5,10 +5,10 @@ import java.util.List;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.InstanceWriter;
import com.jozufozu.flywheel.backend.context.Context;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
import com.jozufozu.flywheel.backend.gl.TextureBuffer;
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;

View File

@ -1,8 +1,8 @@
package com.jozufozu.flywheel.backend.engine.instancing;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.backend.context.Context;
public record ShaderState(Material material, InstanceType<?> instanceType, Context context) {
}

View File

@ -1,6 +1,6 @@
package com.jozufozu.flywheel.backend.engine.textures;
import com.jozufozu.flywheel.api.context.Texture;
import com.jozufozu.flywheel.backend.context.Texture;
/**
* Internal base interface that {@link com.jozufozu.flywheel.backend.gl.shader.GlProgram GlProgram} expects.

View File

@ -3,8 +3,7 @@ package com.jozufozu.flywheel.backend.engine.textures;
import java.util.HashMap;
import java.util.Map;
import com.jozufozu.flywheel.api.context.Texture;
import com.jozufozu.flywheel.api.context.TextureSource;
import com.jozufozu.flywheel.backend.context.Texture;
import com.jozufozu.flywheel.backend.mixin.LightTextureAccessor;
import com.jozufozu.flywheel.backend.mixin.OverlayTextureAccessor;
@ -12,13 +11,13 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.resources.ResourceLocation;
public class TextureSourceImpl implements TextureSource {
public class TextureSource {
private final DirectTexture lightTexture;
private final DirectTexture overlayTexture;
private final Map<ResourceLocation, WrappedTexture> wrappers = new HashMap<>();
public TextureSourceImpl() {
public TextureSource() {
var gameRenderer = Minecraft.getInstance().gameRenderer;
this.lightTexture = new DirectTexture(((LightTextureAccessor) gameRenderer.lightTexture()).flywheel$texture()
@ -28,19 +27,32 @@ public class TextureSourceImpl implements TextureSource {
}
@Override
/**
* Get a built-in texture by its resource location.
*
* @param texture The texture's resource location.
* @return The texture.
*/
public Texture byName(ResourceLocation texture) {
return wrappers.computeIfAbsent(texture, key -> new WrappedTexture(Minecraft.getInstance()
.getTextureManager()
.getTexture(key)));
}
@Override
/**
* Get the overlay texture.
*
* @return The overlay texture.
*/
public Texture overlay() {
return overlayTexture;
}
@Override
/**
* Get the light texture.
*
* @return The light texture.
*/
public Texture light() {
return lightTexture;
}

View File

@ -8,16 +8,17 @@ import static org.lwjgl.opengl.GL20.glUniform1i;
import static org.lwjgl.opengl.GL20.glUniform2f;
import static org.lwjgl.opengl.GL20.glUniform3f;
import static org.lwjgl.opengl.GL20.glUniform4f;
import static org.lwjgl.opengl.GL20.glUniformMatrix3fv;
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
import static org.lwjgl.opengl.GL31.GL_INVALID_INDEX;
import static org.lwjgl.opengl.GL31.glGetUniformBlockIndex;
import static org.lwjgl.opengl.GL31.glUniformBlockBinding;
import org.joml.Matrix3fc;
import org.joml.Matrix4fc;
import org.slf4j.Logger;
import com.jozufozu.flywheel.api.context.Shader;
import com.jozufozu.flywheel.api.context.Texture;
import com.jozufozu.flywheel.backend.context.Texture;
import com.jozufozu.flywheel.backend.engine.textures.IdentifiedTexture;
import com.jozufozu.flywheel.backend.engine.textures.TextureBinder;
import com.jozufozu.flywheel.backend.gl.GlObject;
@ -27,7 +28,7 @@ import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
public class GlProgram extends GlObject implements Shader {
public class GlProgram extends GlObject {
private static final Logger LOGGER = LogUtils.getLogger();
private final Object2IntMap<String> uniformLocationCache = new Object2IntOpenHashMap<>();
@ -44,10 +45,7 @@ public class GlProgram extends GlObject implements Shader {
ProgramManager.glUseProgram(0);
}
@Override
public void setTexture(String glslName, Texture texture) {
throwIfReserved(glslName);
if (!(texture instanceof IdentifiedTexture identified)) {
return;
}
@ -64,10 +62,7 @@ public class GlProgram extends GlObject implements Shader {
glUniform1i(uniform, binding);
}
@Override
public void setFloat(String glslName, float value) {
throwIfReserved(glslName);
int uniform = getUniformLocation(glslName);
if (uniform < 0) {
@ -77,10 +72,7 @@ public class GlProgram extends GlObject implements Shader {
glUniform1f(uniform, value);
}
@Override
public void setVec2(String glslName, float x, float y) {
throwIfReserved(glslName);
int uniform = getUniformLocation(glslName);
if (uniform < 0) {
@ -90,10 +82,7 @@ public class GlProgram extends GlObject implements Shader {
glUniform2f(uniform, x, y);
}
@Override
public void setVec3(String glslName, float x, float y, float z) {
throwIfReserved(glslName);
int uniform = getUniformLocation(glslName);
if (uniform < 0) {
@ -103,10 +92,7 @@ public class GlProgram extends GlObject implements Shader {
glUniform3f(uniform, x, y, z);
}
@Override
public void setVec4(String glslName, float x, float y, float z, float w) {
throwIfReserved(glslName);
int uniform = getUniformLocation(glslName);
if (uniform < 0) {
@ -116,10 +102,7 @@ public class GlProgram extends GlObject implements Shader {
glUniform4f(uniform, x, y, z, w);
}
@Override
public void setMat4(String glslName, Matrix4fc matrix) {
throwIfReserved(glslName);
int uniform = getUniformLocation(glslName);
if (uniform < 0) {
@ -129,6 +112,16 @@ public class GlProgram extends GlObject implements Shader {
glUniformMatrix4fv(uniform, false, matrix.get(new float[16]));
}
public void setMat3(String glslName, Matrix3fc matrix) {
int uniform = getUniformLocation(glslName);
if (uniform < 0) {
return;
}
glUniformMatrix3fv(uniform, false, matrix.get(new float[9]));
}
/**
* Retrieves the index of the uniform with the given name.
*
@ -179,18 +172,4 @@ public class GlProgram extends GlObject implements Shader {
protected void deleteInternal(int handle) {
glDeleteProgram(handle);
}
public static void throwIfReserved(String glslName) {
if (glslName.startsWith("flw_")) {
throw new IllegalArgumentException("Uniform names starting with flw_are reserved");
}
if (glslName.startsWith("_flw_")) {
throw new IllegalArgumentException("Uniform names starting with _flw_ are reserved for internal use");
}
if (glslName.startsWith("gl_")) {
throw new IllegalArgumentException("Uniform names cannot start with gl_");
}
}
}

View File

@ -3,25 +3,63 @@ package com.jozufozu.flywheel.impl.visualization;
import java.util.function.Supplier;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.InstanceType;
import com.jozufozu.flywheel.api.instance.Instancer;
import com.jozufozu.flywheel.api.instance.InstancerProvider;
import com.jozufozu.flywheel.api.model.Model;
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
public record InstancerProviderImpl(Engine engine,
Context context,
RenderStage renderStage) implements InstancerProvider, Supplier<VisualizationContext> {
public class InstancerProviderImpl implements InstancerProvider, Supplier<VisualizationContext> {
protected final Engine engine;
protected final RenderStage renderStage;
public InstancerProviderImpl(Engine engine, RenderStage renderStage) {
this.engine = engine;
this.renderStage = renderStage;
}
@Override
public <I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model) {
return engine.instancer(type, context, model, renderStage);
return engine.instancer(type, model, renderStage);
}
@Override
public VisualizationContext get() {
return new VisualizationContextImpl(this, engine.renderOrigin());
}
public Embedded embed(EmbeddedLevel world) {
return new Embedded(engine, world, renderStage);
}
@Override
public String toString() {
return "InstancerProviderImpl[" + "engine=" + engine + ", " + "renderStage=" + renderStage + ']';
}
public static final class Embedded extends InstancerProviderImpl {
private final EmbeddedLevel world;
public Embedded(Engine engine, EmbeddedLevel world, RenderStage renderStage) {
super(engine, renderStage);
this.world = world;
}
@Override
public <I extends Instance> Instancer<I> instancer(InstanceType<I> type, Model model) {
return engine.instancer(world, type, model, renderStage);
}
public EmbeddedLevel world() {
return world;
}
@Override
public String toString() {
return "InstancerProviderImpl.EmbeddedImpl[" + "world=" + world + ", " + "engine=" + engine + ", " + "renderStage=" + renderStage + ']';
}
}
}

View File

@ -1,7 +1,7 @@
package com.jozufozu.flywheel.impl.visualization;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.instance.InstancerProvider;
import com.jozufozu.flywheel.api.visualization.EmbeddedLevel;
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import net.minecraft.core.Vec3i;
@ -15,8 +15,7 @@ import net.minecraft.core.Vec3i;
*/
public record VisualizationContextImpl(InstancerProviderImpl instancerProvider, Vec3i renderOrigin) implements VisualizationContext {
@Override
public VisualizationContext withContext(Context context, Vec3i renderOrigin) {
var provider = new InstancerProviderImpl(instancerProvider.engine(), context, instancerProvider.renderStage());
return new VisualizationContextImpl(provider, renderOrigin);
public VisualizationContext embed(EmbeddedLevel world) {
return new VisualizationContextImpl(instancerProvider.embed(world), renderOrigin);
}
}

View File

@ -36,7 +36,6 @@ import com.jozufozu.flywheel.impl.visualization.manager.VisualManagerImpl;
import com.jozufozu.flywheel.impl.visualization.ratelimit.BandedPrimeLimiter;
import com.jozufozu.flywheel.impl.visualization.ratelimit.DistanceUpdateLimiterImpl;
import com.jozufozu.flywheel.impl.visualization.ratelimit.NonLimiter;
import com.jozufozu.flywheel.lib.context.Contexts;
import com.jozufozu.flywheel.lib.task.Flag;
import com.jozufozu.flywheel.lib.task.IfElsePlan;
import com.jozufozu.flywheel.lib.task.MapContextPlan;
@ -85,9 +84,9 @@ public class VisualizationManagerImpl implements VisualizationManager {
.createEngine(level);
taskExecutor = FlwTaskExecutor.get();
var blockEntitiesStorage = new BlockEntityStorage(new InstancerProviderImpl(engine, Contexts.DEFAULT, RenderStage.AFTER_BLOCK_ENTITIES));
var entitiesStorage = new EntityStorage(new InstancerProviderImpl(engine, Contexts.DEFAULT, RenderStage.AFTER_ENTITIES));
var effectsStorage = new EffectStorage(new InstancerProviderImpl(engine, Contexts.DEFAULT, RenderStage.AFTER_PARTICLES));
var blockEntitiesStorage = new BlockEntityStorage(new InstancerProviderImpl(engine, RenderStage.AFTER_BLOCK_ENTITIES));
var entitiesStorage = new EntityStorage(new InstancerProviderImpl(engine, RenderStage.AFTER_ENTITIES));
var effectsStorage = new EffectStorage(new InstancerProviderImpl(engine, RenderStage.AFTER_PARTICLES));
blockEntities = new VisualManagerImpl<>(blockEntitiesStorage);
entities = new VisualManagerImpl<>(entitiesStorage);

View File

@ -1,18 +0,0 @@
package com.jozufozu.flywheel.lib.context;
import org.jetbrains.annotations.ApiStatus;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.ContextShader;
public class ContextShaders {
public static final SimpleContextShader DEFAULT = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("context/default.vert"), Flywheel.rl("context/default.frag")));
public static final SimpleContextShader CRUMBLING = ContextShader.REGISTRY.registerAndGet(new SimpleContextShader(Flywheel.rl("context/crumbling.vert"), Flywheel.rl("context/crumbling.frag")));
private ContextShaders() {
}
@ApiStatus.Internal
public static void init() {
}
}

View File

@ -1,33 +0,0 @@
package com.jozufozu.flywheel.lib.context;
import com.jozufozu.flywheel.api.context.Context;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
import net.minecraft.client.resources.model.ModelBakery;
public final class Contexts {
public static final Context DEFAULT = SimpleContext.builder(ContextShaders.DEFAULT)
.build();
public static final Int2ObjectMap<Context> CRUMBLING;
static {
var map = new Int2ObjectArrayMap<Context>();
for (int i = 0; i < ModelBakery.BREAKING_LOCATIONS.size(); i++) {
var crumblingLocation = ModelBakery.BREAKING_LOCATIONS.get(i);
map.put(i, SimpleContext.builder(ContextShaders.CRUMBLING)
.preparation((material, shader, textureSource) -> {
shader.setTexture("crumblingTex", textureSource.byName(crumblingLocation));
})
.build());
}
CRUMBLING = Int2ObjectMaps.unmodifiable(map);
}
private Contexts() {
}
}

View File

@ -1,14 +1,5 @@
#include "flywheel:util/matrix.glsl"
void flw_transformBoundingSphere(in FlwInstance i, inout vec3 center, inout float radius) {
mat4 pose = i.pose;
center = (pose * vec4(center, 1.0)).xyz;
vec3 c0 = pose[0].xyz;
vec3 c1 = pose[1].xyz;
vec3 c2 = pose[2].xyz;
// Comute the squared maximum to avoid 2 unnecessary sqrts.
// I don't think this makes it any faster but why not /shrug
float scaleSqr = max(dot(c0, c0), max(dot(c1, c1), dot(c2, c2)));
float scale = sqrt(scaleSqr);
radius *= scale;
transformBoundingSphere(i.pose, center, radius);
}

View File

@ -0,0 +1,10 @@
uniform sampler3D _flw_lightVolume;
in vec3 _flw_lightVolumeCoord;
void flw_beginFragment() {
flw_fragLight = max(flw_fragLight, texture(_flw_lightVolume, _flw_lightVolumeCoord).rg);
}
void flw_endFragment() {
}

View File

@ -0,0 +1,16 @@
uniform vec3 _flw_oneOverLightBoxSize;
uniform vec3 _flw_lightVolumeMin;
uniform mat4 _flw_model;
uniform mat3 _flw_normal;
out vec3 _flw_lightVolumeCoord;
void flw_beginVertex() {
}
void flw_endVertex() {
_flw_lightVolumeCoord = (flw_vertexPos.xyz - _flw_lightVolumeMin) * _flw_oneOverLightBoxSize;
flw_vertexPos = _flw_model * flw_vertexPos;
flw_vertexNormal = _flw_normal * flw_vertexNormal;
}

View File

@ -2,6 +2,7 @@
#include "flywheel:internal/indirect/model_descriptor.glsl"
#include "flywheel:internal/indirect/object.glsl"
#include "flywheel:internal/uniforms/frame.glsl"
#include "flywheel:util/matrix.glsl"
layout(local_size_x = _FLW_SUBGROUP_SIZE) in;
@ -17,6 +18,9 @@ layout(std430, binding = _FLW_MODEL_BUFFER_BINDING) restrict buffer ModelBuffer
ModelDescriptor models[];
};
uniform mat4 _flw_embeddedModel;
uniform bool _flw_useEmbeddedModel = false;
// Disgustingly vectorized sphere frustum intersection taking advantage of ahead of time packing.
// Only uses 6 fmas and some boolean ops.
// See also:
@ -41,6 +45,10 @@ bool _flw_isVisible(uint objectIndex, uint modelIndex) {
flw_transformBoundingSphere(instance, center, radius);
if (_flw_useEmbeddedModel) {
transformBoundingSphere(_flw_embeddedModel, center, radius);
}
return _flw_testSphere(center, radius);
}

View File

@ -41,3 +41,17 @@ mat3 modelToNormal(mat4 mat) {
m[2] = mat[2].xyz;
return m;
}
void transformBoundingSphere(in mat4 mat, inout vec3 center, inout float radius) {
center = (mat * vec4(center, 1.)).xyz;
vec3 c0 = mat[0].xyz;
vec3 c1 = mat[1].xyz;
vec3 c2 = mat[2].xyz;
// Comute the squared maximum to avoid 2 unnecessary sqrts.
// I don't think this makes it any faster but why not /shrug
float scaleSqr = max(dot(c0, c0), max(dot(c1, c1), dot(c2, c2)));
float scale = sqrt(scaleSqr);
radius *= scale;
}