Putting crumbling in context

- Oops didn't actually put everything in last time.
- Create one context per crumbling stage.
- Let contexts handle setting both the diffuse and crumbling texture.
This commit is contained in:
Jozufozu 2024-02-11 20:49:30 -08:00
parent bab0448724
commit 1028ca4633
5 changed files with 43 additions and 22 deletions

View File

@ -210,7 +210,7 @@ public class IndirectCullingGroup<I extends Instance> {
}
}
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<I extends Instance> {
var flwBaseDraw = drawProgram.getUniformLocation("_flw_baseDraw");
glUniform1ui(flwBaseDraw, 0);
return program;
}
private void drawBarrier() {

View File

@ -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<IndirectInstancer<?>>
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<IndirectInstancer<?>>
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<IndirectInstancer<?>>
// Submit! Everything is already bound by here.
glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0);
TextureBinder.resetTextureBindings();
}
}
}

View File

@ -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<Engine.CrumblingBlock> crumblingBlocks, InstancingPrograms programs) {
public static void render(List<Engine.CrumblingBlock> 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<List<Runnable>> 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();
}
}

View File

@ -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

View File

@ -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<Context> CRUMBLING;
static {
var map = new Int2ObjectArrayMap<Context>();
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() {
}
}