mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-14 16:26:07 +01:00
Reduced to ashes
- renderCrumblingInstances accepts a list. - Implement crumbling for InstancingEngine. - It's ugly. - Track what draw calls belong with what instancers. - DrawCalls lazily create a second VAO for one-off rendering. - Bind instance vbo with offset to scratch VAO to emulate a draw with baseInstance. - Ignore discard predicate in crumbling context. - SimpleContext takes a Consumer to set sampler bindings. - Fix debugCrumbling command. - Compile shaders against all contexts. Side note: not sure if Context is the right place for crumbling. It feels like it should be a material, but I don't know how that would work.
This commit is contained in:
parent
791c2ddf5c
commit
b400229ea4
15 changed files with 168 additions and 43 deletions
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.api.backend;
|
package com.jozufozu.flywheel.api.backend;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
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.instance.Instance;
|
import com.jozufozu.flywheel.api.instance.Instance;
|
||||||
|
@ -25,7 +27,14 @@ public interface Engine extends InstancerProvider {
|
||||||
*/
|
*/
|
||||||
void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage);
|
void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage);
|
||||||
|
|
||||||
void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress);
|
/**
|
||||||
|
* Render the given instances as a crumbling overlay.
|
||||||
|
* @param taskExecutor The task executor running the frame plan.
|
||||||
|
* @param context The render context for this frame.
|
||||||
|
* @param instances The instances to render.
|
||||||
|
* @param progress The progress of the crumbling animation, i.e. which texture to use.
|
||||||
|
*/
|
||||||
|
void renderCrumblingInstances(TaskExecutor taskExecutor, RenderContext context, List<Instance> instances, int progress);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maintain the render origin to be within a certain distance from the camera in all directions,
|
* Maintain the render origin to be within a certain distance from the camera in all directions,
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.compile;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
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;
|
||||||
|
@ -76,9 +77,12 @@ public class FlwPrograms {
|
||||||
|
|
||||||
private static ImmutableList<PipelineProgramKey> createPipelineKeys() {
|
private static ImmutableList<PipelineProgramKey> createPipelineKeys() {
|
||||||
ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder();
|
ImmutableList.Builder<PipelineProgramKey> builder = ImmutableList.builder();
|
||||||
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
|
// TODO: ubershader'd contexts?
|
||||||
for (VertexType vertexType : VertexType.REGISTRY) {
|
for (Context context : Context.REGISTRY) {
|
||||||
builder.add(new PipelineProgramKey(vertexType, instanceType, Contexts.WORLD));
|
for (InstanceType<?> instanceType : InstanceType.REGISTRY) {
|
||||||
|
for (VertexType vertexType : VertexType.REGISTRY) {
|
||||||
|
builder.add(new PipelineProgramKey(vertexType, instanceType, context));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
|
@ -81,7 +81,7 @@ public abstract class AbstractInstancer<I extends Instance> implements Instancer
|
||||||
handles.set(j, handle);
|
handles.set(j, handle);
|
||||||
instances.set(j, instance);
|
instances.set(j, instance);
|
||||||
|
|
||||||
handle.setIndex(j);
|
handle.index = j;
|
||||||
changed.set(j);
|
changed.set(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import com.jozufozu.flywheel.api.instance.InstanceHandle;
|
||||||
|
|
||||||
public class InstanceHandleImpl implements InstanceHandle {
|
public class InstanceHandleImpl implements InstanceHandle {
|
||||||
public final AbstractInstancer<?> instancer;
|
public final AbstractInstancer<?> instancer;
|
||||||
private int index;
|
public int index;
|
||||||
|
|
||||||
public InstanceHandleImpl(AbstractInstancer<?> instancer, int index) {
|
public InstanceHandleImpl(AbstractInstancer<?> instancer, int index) {
|
||||||
this.instancer = instancer;
|
this.instancer = instancer;
|
||||||
|
@ -21,10 +21,6 @@ public class InstanceHandleImpl implements InstanceHandle {
|
||||||
instancer.notifyRemoval(index);
|
instancer.notifyRemoval(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIndex(int i) {
|
|
||||||
index = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
index = -1;
|
index = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class BatchingEngine extends AbstractEngine implements SimplyComposedPlan
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress) {
|
public void renderCrumblingInstances(TaskExecutor taskExecutor, RenderContext context, List<Instance> instances, int progress) {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.indirect;
|
package com.jozufozu.flywheel.backend.engine.indirect;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||||
|
@ -69,7 +71,7 @@ public class IndirectEngine extends AbstractEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress) {
|
public void renderCrumblingInstances(TaskExecutor taskExecutor, RenderContext context, List<Instance> instances, int progress) {
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,18 @@ package com.jozufozu.flywheel.backend.engine.instancing;
|
||||||
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
import com.jozufozu.flywheel.gl.array.GlVertexArray;
|
||||||
|
|
||||||
public class DrawCall {
|
public class DrawCall {
|
||||||
|
public final ShaderState shaderState;
|
||||||
private final InstancedInstancer<?> instancer;
|
private final InstancedInstancer<?> instancer;
|
||||||
private final InstancedMeshPool.BufferedMesh mesh;
|
private final InstancedMeshPool.BufferedMesh mesh;
|
||||||
|
|
||||||
private final int meshAttributes;
|
private final int meshAttributes;
|
||||||
private GlVertexArray vao;
|
private GlVertexArray vao;
|
||||||
|
private GlVertexArray vaoScratch;
|
||||||
|
|
||||||
public DrawCall(InstancedInstancer<?> instancer, InstancedMeshPool.BufferedMesh mesh) {
|
public DrawCall(InstancedInstancer<?> instancer, InstancedMeshPool.BufferedMesh mesh, ShaderState shaderState) {
|
||||||
this.instancer = instancer;
|
this.instancer = instancer;
|
||||||
this.mesh = mesh;
|
this.mesh = mesh;
|
||||||
|
this.shaderState = shaderState;
|
||||||
|
|
||||||
meshAttributes = this.mesh.getAttributeCount();
|
meshAttributes = this.mesh.getAttributeCount();
|
||||||
vao = GlVertexArray.create();
|
vao = GlVertexArray.create();
|
||||||
|
@ -22,14 +25,14 @@ public class DrawCall {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
if (isInvalid()) {
|
if (isInvalid() || mesh.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
instancer.update();
|
instancer.update();
|
||||||
|
|
||||||
int instanceCount = instancer.getInstanceCount();
|
int instanceCount = instancer.getInstanceCount();
|
||||||
if (instanceCount <= 0 || mesh.isEmpty()) {
|
if (instanceCount <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +44,44 @@ public class DrawCall {
|
||||||
mesh.draw(instanceCount);
|
mesh.draw(instanceCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void renderOne(int index) {
|
||||||
if (vao == null) {
|
if (isInvalid() || mesh.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vao.delete();
|
instancer.update();
|
||||||
vao = null;
|
|
||||||
|
int instanceCount = instancer.getInstanceCount();
|
||||||
|
if (instanceCount <= 0 || index >= instanceCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var vao = lazyScratchVao();
|
||||||
|
|
||||||
|
instancer.bindRaw(vao, meshAttributes, index);
|
||||||
|
mesh.setup(vao);
|
||||||
|
|
||||||
|
vao.bindForDraw();
|
||||||
|
|
||||||
|
mesh.draw(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GlVertexArray lazyScratchVao() {
|
||||||
|
if (vaoScratch == null) {
|
||||||
|
vaoScratch = GlVertexArray.create();
|
||||||
|
}
|
||||||
|
return vaoScratch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
if (vao != null) {
|
||||||
|
vao.delete();
|
||||||
|
vao = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vaoScratch != null) {
|
||||||
|
vaoScratch.delete();
|
||||||
|
vaoScratch = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import com.jozufozu.flywheel.backend.engine.InstancerKey;
|
||||||
public class InstancedDrawManager {
|
public class InstancedDrawManager {
|
||||||
private final Map<InstancerKey<?>, InstancedInstancer<?>> instancers = new HashMap<>();
|
private final Map<InstancerKey<?>, InstancedInstancer<?>> instancers = new HashMap<>();
|
||||||
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
private final List<UninitializedInstancer> uninitializedInstancers = new ArrayList<>();
|
||||||
private final List<InstancedInstancer<?>> initializedInstancers = new ArrayList<>();
|
private final List<InitializedInstancer> initializedInstancers = new ArrayList<>();
|
||||||
private final Map<RenderStage, DrawSet> drawSets = new EnumMap<>(RenderStage.class);
|
private final Map<RenderStage, DrawSet> drawSets = new EnumMap<>(RenderStage.class);
|
||||||
private final Map<VertexType, InstancedMeshPool> meshPools = new HashMap<>();
|
private final Map<VertexType, InstancedMeshPool> meshPools = new HashMap<>();
|
||||||
private final EBOCache eboCache = new EBOCache();
|
private final EBOCache eboCache = new EBOCache();
|
||||||
|
@ -68,27 +68,33 @@ public class InstancedDrawManager {
|
||||||
.forEach(DrawSet::delete);
|
.forEach(DrawSet::delete);
|
||||||
drawSets.clear();
|
drawSets.clear();
|
||||||
|
|
||||||
initializedInstancers.forEach(InstancedInstancer::delete);
|
initializedInstancers.forEach(InitializedInstancer::deleteInstancer);
|
||||||
initializedInstancers.clear();
|
initializedInstancers.clear();
|
||||||
|
|
||||||
eboCache.invalidate();
|
eboCache.invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearInstancers() {
|
public void clearInstancers() {
|
||||||
initializedInstancers.forEach(InstancedInstancer::clear);
|
initializedInstancers.forEach(InitializedInstancer::clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(InstancedInstancer<?> instancer, Model model, RenderStage stage) {
|
private void add(InstancedInstancer<?> instancer, Model model, RenderStage stage) {
|
||||||
instancer.init();
|
instancer.init();
|
||||||
|
|
||||||
DrawSet drawSet = drawSets.computeIfAbsent(stage, DrawSet::new);
|
DrawSet drawSet = drawSets.computeIfAbsent(stage, DrawSet::new);
|
||||||
|
List<DrawCall> drawCalls = new ArrayList<>();
|
||||||
|
|
||||||
var meshes = model.getMeshes();
|
var meshes = model.getMeshes();
|
||||||
for (var entry : meshes.entrySet()) {
|
for (var entry : meshes.entrySet()) {
|
||||||
var mesh = alloc(entry.getValue());
|
var mesh = alloc(entry.getValue());
|
||||||
|
|
||||||
ShaderState shaderState = new ShaderState(entry.getKey(), mesh.getVertexType(), instancer.type);
|
ShaderState shaderState = new ShaderState(entry.getKey(), mesh.getVertexType(), instancer.type);
|
||||||
DrawCall drawCall = new DrawCall(instancer, mesh);
|
DrawCall drawCall = new DrawCall(instancer, mesh, shaderState);
|
||||||
|
|
||||||
drawSet.put(shaderState, drawCall);
|
drawSet.put(shaderState, drawCall);
|
||||||
|
drawCalls.add(drawCall);
|
||||||
}
|
}
|
||||||
initializedInstancers.add(instancer);
|
initializedInstancers.add(new InitializedInstancer(instancer, drawCalls));
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstancedMeshPool.BufferedMesh alloc(Mesh mesh) {
|
private InstancedMeshPool.BufferedMesh alloc(Mesh mesh) {
|
||||||
|
@ -96,6 +102,16 @@ public class InstancedDrawManager {
|
||||||
.alloc(mesh, eboCache);
|
.alloc(mesh, eboCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<DrawCall> drawCallsForInstancer(InstancedInstancer<?> instancer) {
|
||||||
|
for (InitializedInstancer initializedInstancer : initializedInstancers) {
|
||||||
|
if (initializedInstancer.instancer == instancer) {
|
||||||
|
return initializedInstancer.drawCalls;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
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());
|
||||||
|
|
||||||
|
@ -134,4 +150,14 @@ public class InstancedDrawManager {
|
||||||
|
|
||||||
private record UninitializedInstancer(InstancedInstancer<?> instancer, Model model, RenderStage stage) {
|
private record UninitializedInstancer(InstancedInstancer<?> instancer, Model model, RenderStage stage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private record InitializedInstancer(InstancedInstancer<?> instancer, List<DrawCall> drawCalls) {
|
||||||
|
public void deleteInstancer() {
|
||||||
|
instancer.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
instancer.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,12 @@ public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I>
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vao.bindVertexBuffer(1, vbo.handle(), 0L, instanceStride);
|
bindRaw(vao, startAttrib, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindRaw(GlVertexArray vao, int startAttrib, int baseInstance) {
|
||||||
|
long offset = (long) baseInstance * instanceStride;
|
||||||
|
vao.bindVertexBuffer(1, vbo.handle(), offset, instanceStride);
|
||||||
vao.setBindingDivisor(1, 1);
|
vao.setBindingDivisor(1, 1);
|
||||||
vao.bindAttributes(1, startAttrib, instanceFormat.attributes());
|
vao.bindAttributes(1, startAttrib, instanceFormat.attributes());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.jozufozu.flywheel.backend.engine.instancing;
|
package com.jozufozu.flywheel.backend.engine.instancing;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL32;
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
|
@ -13,9 +15,12 @@ import com.jozufozu.flywheel.api.task.Plan;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
|
import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractEngine;
|
import com.jozufozu.flywheel.backend.engine.AbstractEngine;
|
||||||
|
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
||||||
|
import com.jozufozu.flywheel.backend.engine.indirect.Textures;
|
||||||
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.context.Contexts;
|
||||||
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
import com.jozufozu.flywheel.lib.material.MaterialIndices;
|
||||||
import com.jozufozu.flywheel.lib.task.Flag;
|
import com.jozufozu.flywheel.lib.task.Flag;
|
||||||
import com.jozufozu.flywheel.lib.task.NamedFlag;
|
import com.jozufozu.flywheel.lib.task.NamedFlag;
|
||||||
|
@ -24,6 +29,8 @@ import com.jozufozu.flywheel.lib.task.SyncedPlan;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.resources.model.ModelBakery;
|
||||||
|
|
||||||
public class InstancingEngine extends AbstractEngine {
|
public class InstancingEngine extends AbstractEngine {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
@ -76,8 +83,39 @@ public class InstancingEngine extends AbstractEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderCrumblingInstance(TaskExecutor taskExecutor, RenderContext context, Instance instance, int progress) {
|
public void renderCrumblingInstances(TaskExecutor taskExecutor, RenderContext context, List<Instance> instances, int progress) {
|
||||||
// TODO: implement
|
// TODO: optimize
|
||||||
|
|
||||||
|
taskExecutor.syncUntil(flushFlag::isRaised);
|
||||||
|
|
||||||
|
var type = ModelBakery.DESTROY_TYPES.get(progress);
|
||||||
|
|
||||||
|
try (var state = GlStateTracker.getRestoreState()) {
|
||||||
|
type.setupRenderState();
|
||||||
|
|
||||||
|
Textures.bindActiveTextures();
|
||||||
|
|
||||||
|
for (Instance instance : instances) {
|
||||||
|
if (!(instance.handle() instanceof InstanceHandleImpl impl)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!(impl.instancer instanceof InstancedInstancer<?> instancer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DrawCall> draws = drawManager.drawCallsForInstancer(instancer);
|
||||||
|
|
||||||
|
draws.removeIf(DrawCall::isInvalid);
|
||||||
|
|
||||||
|
for (DrawCall draw : draws) {
|
||||||
|
var shader = draw.shaderState;
|
||||||
|
|
||||||
|
setup(shader, Contexts.CRUMBLING);
|
||||||
|
|
||||||
|
draw.renderOne(impl.index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setup() {
|
private void setup() {
|
||||||
|
|
|
@ -116,7 +116,7 @@ public class FlwCommands {
|
||||||
.then(Commands.argument("pos", BlockPosArgument.blockPos())
|
.then(Commands.argument("pos", BlockPosArgument.blockPos())
|
||||||
.then(Commands.argument("stage", IntegerArgumentType.integer(0, 9))
|
.then(Commands.argument("stage", IntegerArgumentType.integer(0, 9))
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
BlockPos pos = BlockPosArgument.getLoadedBlockPos(context, "pos");
|
BlockPos pos = BlockPosArgument.getBlockPos(context, "pos");
|
||||||
int value = IntegerArgumentType.getInteger(context, "stage");
|
int value = IntegerArgumentType.getInteger(context, "stage");
|
||||||
|
|
||||||
Entity executor = context.getSource()
|
Entity executor = context.getSource()
|
||||||
|
@ -145,6 +145,7 @@ public class FlwCommands {
|
||||||
}))
|
}))
|
||||||
.then(Commands.literal("capture")
|
.then(Commands.literal("capture")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
|
FlwShaderUniforms.FRUSTUM_PAUSED = true;
|
||||||
FlwShaderUniforms.FRUSTUM_CAPTURE = true;
|
FlwShaderUniforms.FRUSTUM_CAPTURE = true;
|
||||||
return 1;
|
return 1;
|
||||||
})));
|
})));
|
||||||
|
|
|
@ -8,7 +8,6 @@ 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.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.instance.Instance;
|
|
||||||
import com.jozufozu.flywheel.api.task.Plan;
|
import com.jozufozu.flywheel.api.task.Plan;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
import com.jozufozu.flywheel.api.visual.DynamicVisual;
|
import com.jozufozu.flywheel.api.visual.DynamicVisual;
|
||||||
|
@ -220,9 +219,9 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var instanceList = visual.getCrumblingInstances();
|
var instances = visual.getCrumblingInstances();
|
||||||
|
|
||||||
if (instanceList.isEmpty()) {
|
if (instances.isEmpty()) {
|
||||||
// The visual doesn't want to render anything crumbling.
|
// The visual doesn't want to render anything crumbling.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -232,9 +231,7 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
||||||
int progress = set.last()
|
int progress = set.last()
|
||||||
.getProgress();
|
.getProgress();
|
||||||
|
|
||||||
for (Instance instance : instanceList) {
|
engine.renderCrumblingInstances(taskExecutor, context, instances, progress);
|
||||||
engine.renderCrumblingInstance(taskExecutor, context, instance, progress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,26 @@ 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.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.lib.util.ResourceUtil;
|
import com.jozufozu.flywheel.lib.util.ResourceUtil;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public final 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, program -> {
|
||||||
public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT));
|
program.bind();
|
||||||
|
program.setSamplerBinding("flw_diffuseTex", 0);
|
||||||
|
program.setSamplerBinding("flw_overlayTex", 1);
|
||||||
|
program.setSamplerBinding("flw_lightTex", 2);
|
||||||
|
GlProgram.unbind();
|
||||||
|
}));
|
||||||
|
|
||||||
|
// TODO: can we make crumbling a fragment material?
|
||||||
|
public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT, program -> {
|
||||||
|
program.bind();
|
||||||
|
program.setSamplerBinding("flw_diffuseTex", 0);
|
||||||
|
GlProgram.unbind();
|
||||||
|
}));
|
||||||
|
|
||||||
private Contexts() {
|
private Contexts() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
package com.jozufozu.flywheel.lib.context;
|
package com.jozufozu.flywheel.lib.context;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.gl.shader.GlProgram;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
public record SimpleContext(ResourceLocation vertexShader, ResourceLocation fragmentShader) implements Context {
|
public record SimpleContext(ResourceLocation vertexShader, ResourceLocation fragmentShader, Consumer<GlProgram> onLink) implements Context {
|
||||||
@Override
|
@Override
|
||||||
public void onProgramLink(GlProgram program) {
|
public void onProgramLink(GlProgram program) {
|
||||||
program.bind();
|
onLink.accept(program);
|
||||||
program.setSamplerBinding("flw_diffuseTex", 0);
|
|
||||||
program.setSamplerBinding("flw_overlayTex", 1);
|
|
||||||
program.setSamplerBinding("flw_lightTex", 2);
|
|
||||||
GlProgram.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -34,7 +34,8 @@ void flw_initFragment() {
|
||||||
void flw_contextFragment() {
|
void flw_contextFragment() {
|
||||||
vec4 color = flw_fragColor;
|
vec4 color = flw_fragColor;
|
||||||
|
|
||||||
if (flw_discardPredicate(color)) {
|
// Ignore the discard predicate since we control the texture.
|
||||||
|
if (color.a < 0.01) {
|
||||||
discard;
|
discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue