diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java index c12fba537..365035f68 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java @@ -210,7 +210,7 @@ public class IndirectCullingGroup { } } - public void bindWithContextShader(SimpleContextShader override) { + public GlProgram bindWithContextShader(SimpleContextShader override) { var program = programs.getIndirectProgram(instanceType, override); program.bind(); @@ -223,6 +223,8 @@ public class IndirectCullingGroup { var flwBaseDraw = drawProgram.getUniformLocation("_flw_baseDraw"); glUniform1ui(flwBaseDraw, 0); + + return program; } private void drawBarrier() { diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java index 98e664df2..a520bd073 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java @@ -22,10 +22,12 @@ import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl; import com.jozufozu.flywheel.backend.engine.InstancerKey; import com.jozufozu.flywheel.backend.engine.InstancerStorage; import com.jozufozu.flywheel.backend.engine.MaterialRenderState; +import com.jozufozu.flywheel.backend.engine.textures.TextureBinder; import com.jozufozu.flywheel.backend.engine.textures.TexturesImpl; 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; @@ -127,7 +129,7 @@ public class IndirectDrawManager extends InstancerStorage> var byProgress = instanceTypeEntry.getValue(); // Set up the crumbling program buffers. Nothing changes here between draws. - cullingGroups.get(instanceTypeEntry.getKey()) + var program = cullingGroups.get(instanceTypeEntry.getKey()) .bindWithContextShader(ContextShaders.CRUMBLING); for (var progressEntry : byProgress.int2ObjectEntrySet()) { @@ -136,16 +138,14 @@ public class IndirectDrawManager extends InstancerStorage> int instanceIndex = instanceHandlePair.second().index; for (IndirectDraw draw : instancer.draws()) { - var baseMaterial = draw.material(); - int diffuseTexture = CommonCrumbling.getDiffuseTexture(baseMaterial); // Transform the material to be suited for crumbling. - CommonCrumbling.applyCrumblingProperties(crumblingMaterial, baseMaterial); - crumblingMaterial.texture(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); + CommonCrumbling.applyCrumblingProperties(crumblingMaterial, draw.material()); + Contexts.CRUMBLING.get(progressEntry.getIntKey()) + .prepare(crumblingMaterial, program, textures); // Set up gl state for the draw. MaterialRenderState.setup(crumblingMaterial); - CommonCrumbling.setActiveAndBindForCrumbling(diffuseTexture); // Upload the draw command. draw.writeWithOverrides(block.ptr(), instanceIndex, crumblingMaterial); @@ -153,6 +153,8 @@ public class IndirectDrawManager extends InstancerStorage> // Submit! Everything is already bound by here. glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); + + TextureBinder.resetTextureBindings(); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java index 5fa323478..51db84c77 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedCrumbling.java @@ -6,14 +6,17 @@ import java.util.List; import java.util.Map; import com.jozufozu.flywheel.api.backend.Engine; +import com.jozufozu.flywheel.api.context.Textures; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.backend.compile.InstancingPrograms; import com.jozufozu.flywheel.backend.engine.CommonCrumbling; import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl; import com.jozufozu.flywheel.backend.engine.MaterialRenderState; +import com.jozufozu.flywheel.backend.engine.textures.TextureBinder; import com.jozufozu.flywheel.backend.engine.uniform.Uniforms; import com.jozufozu.flywheel.backend.gl.GlStateTracker; 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; @@ -21,7 +24,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.minecraft.client.resources.model.ModelBakery; public class InstancedCrumbling { - public static void render(List crumblingBlocks, InstancingPrograms programs) { + public static void render(List crumblingBlocks, InstancingPrograms programs, Textures textures) { // Sort draw calls into buckets, so we don't have to do as many shader binds. var byShaderState = doCrumblingSort(crumblingBlocks); @@ -41,10 +44,7 @@ public class InstancedCrumbling { ShaderState shader = shaderStateEntry.getKey(); - var baseMaterial = shader.material(); - int diffuseTexture = CommonCrumbling.getDiffuseTexture(baseMaterial); - - CommonCrumbling.applyCrumblingProperties(crumblingMaterial, baseMaterial); + CommonCrumbling.applyCrumblingProperties(crumblingMaterial, shader.material()); var program = programs.get(shader.instanceType(), ContextShaders.CRUMBLING); program.bind(); @@ -52,6 +52,8 @@ public class InstancedCrumbling { Uniforms.bindForDraw(); InstancingEngine.uploadMaterialUniform(program, crumblingMaterial); + MaterialRenderState.setup(crumblingMaterial); + for (Int2ObjectMap.Entry> progressEntry : byProgress.int2ObjectEntrySet()) { var drawCalls = progressEntry.getValue(); @@ -59,12 +61,12 @@ public class InstancedCrumbling { continue; } - crumblingMaterial.texture(ModelBakery.BREAKING_LOCATIONS.get(progressEntry.getIntKey())); - - MaterialRenderState.setup(crumblingMaterial); - CommonCrumbling.setActiveAndBindForCrumbling(diffuseTexture); + Contexts.CRUMBLING.get(progressEntry.getIntKey()) + .prepare(crumblingMaterial, program, textures); drawCalls.forEach(Runnable::run); + + TextureBinder.resetTextureBindings(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java index b09a31b0c..51dd214a4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java @@ -73,7 +73,7 @@ public class InstancingEngine extends AbstractEngine { // Need to wait for flush before we can inspect instancer state. executor.syncUntil(flushFlag::isRaised); - InstancedCrumbling.render(crumblingBlocks, programs); + InstancedCrumbling.render(crumblingBlocks, programs, textures); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java b/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java index 22f4007ab..523dd2729 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java +++ b/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java @@ -6,6 +6,9 @@ import com.jozufozu.flywheel.api.context.Shader; import com.jozufozu.flywheel.api.context.Textures; import com.jozufozu.flywheel.api.material.Material; +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 { @@ -26,7 +29,22 @@ public final class Contexts { } }; - public static final Context CRUMBLING = new Context() { + public static final Int2ObjectMap CRUMBLING; + + static { + var map = new Int2ObjectArrayMap(); + + for (int i = 0; i < ModelBakery.BREAKING_LOCATIONS.size(); i++) { + map.put(i, new Crumbling(i)); + } + + CRUMBLING = Int2ObjectMaps.unmodifiable(map); + } + + private Contexts() { + } + + private record Crumbling(int stage) implements Context { @Override public ContextShader contextShader() { return ContextShaders.CRUMBLING; @@ -38,11 +56,8 @@ public final class Contexts { texture.filter(material.blur(), material.mipmap()); shader.setTexture("_flw_diffuseTex", texture); - var crumblingTexture = textures.byName(ModelBakery.BREAKING_LOCATIONS.get(0)); + var crumblingTexture = textures.byName(ModelBakery.BREAKING_LOCATIONS.get(stage)); shader.setTexture("_flw_crumblingTex", crumblingTexture); } - }; - - private Contexts() { } }