diff --git a/src/main/java/com/jozufozu/flywheel/api/material/WriteMask.java b/src/main/java/com/jozufozu/flywheel/api/material/WriteMask.java index f3abe71d3..74511f3d8 100644 --- a/src/main/java/com/jozufozu/flywheel/api/material/WriteMask.java +++ b/src/main/java/com/jozufozu/flywheel/api/material/WriteMask.java @@ -13,4 +13,13 @@ public enum WriteMask { * Write to the depth buffer only. */ DEPTH, + ; + + public boolean depth() { + return this == BOTH || this == DEPTH; + } + + public boolean color() { + return this == BOTH || this == COLOR; + } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/MaterialUtil.java b/src/main/java/com/jozufozu/flywheel/backend/MaterialUtil.java index 4b37e8b5e..59ac1ae47 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/MaterialUtil.java +++ b/src/main/java/com/jozufozu/flywheel/backend/MaterialUtil.java @@ -1,7 +1,10 @@ package com.jozufozu.flywheel.backend; +import java.util.Comparator; + import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.material.Transparency; +import com.jozufozu.flywheel.api.material.WriteMask; import com.jozufozu.flywheel.gl.GlTextureUnit; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; @@ -10,7 +13,59 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.AbstractTexture; public class MaterialUtil { + public static final Comparator BY_STATE = Comparator.comparing(Material::baseTexture) + .thenComparing(Material::mip) + .thenComparing(Material::blur) + .thenComparing(Material::backfaceCull) + .thenComparing(Material::polygonOffset) + .thenComparing(Material::writeMask); + public static void setup(Material material) { + setupTexture(material); + + setupBackfaceCull(material.backfaceCull()); + setupTransparency(material.transparency()); + setupWriteMask(material.writeMask()); + setupPolygonOffset(material.polygonOffset()); + } + + private static void setupPolygonOffset(boolean polygonOffset) { + if (polygonOffset) { + RenderSystem.polygonOffset(-1.0F, -10.0F); + RenderSystem.enablePolygonOffset(); + } + } + + private static void setupWriteMask(WriteMask mask) { + RenderSystem.depthMask(mask.depth()); + boolean writeColor = mask.color(); + RenderSystem.colorMask(writeColor, writeColor, writeColor, writeColor); + } + + private static void setupTransparency(Transparency transparency) { + if (transparency != Transparency.OPAQUE) { + RenderSystem.enableBlend(); + } + + switch (transparency) { + case ADDITIVE -> RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); + case LIGHTING -> RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE); + case GLINT -> + RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_COLOR, GlStateManager.DestFactor.ONE, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); + case CRUMBLING -> + RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.DST_COLOR, GlStateManager.DestFactor.SRC_COLOR, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + case TRANSLUCENT -> + RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); + } + } + + private static void setupBackfaceCull(boolean backfaceCull) { + if (!backfaceCull) { + RenderSystem.disableCull(); + } + } + + private static void setupTexture(Material material) { GlTextureUnit.T0.makeActive(); AbstractTexture texture = Minecraft.getInstance() .getTextureManager() @@ -19,29 +74,38 @@ public class MaterialUtil { texture.setFilter(material.blur(), material.mip()); RenderSystem.setShaderTexture(0, textureId); RenderSystem.bindTexture(textureId); - - if (!material.backfaceCull()) { - RenderSystem.disableCull(); - } - - if (material.transparency() != Transparency.OPAQUE) { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - } } - public static void clear(Material material) { + public static void reset() { + resetDiffuse(); + resetBackfaceCull(); + resetTransparency(); + resetWriteMask(); + resetPolygonOffset(); + } + + private static void resetPolygonOffset() { + RenderSystem.polygonOffset(0.0F, 0.0F); + RenderSystem.disablePolygonOffset(); + } + + private static void resetWriteMask() { + RenderSystem.depthMask(true); + RenderSystem.colorMask(true, true, true, true); + } + + private static void resetTransparency() { + RenderSystem.disableBlend(); + RenderSystem.defaultBlendFunc(); + } + + private static void resetBackfaceCull() { + RenderSystem.enableCull(); + } + + private static void resetDiffuse() { GlTextureUnit.T0.makeActive(); RenderSystem.setShaderTexture(0, 0); - - if (!material.backfaceCull()) { - RenderSystem.enableCull(); - } - - if (material.transparency() != Transparency.OPAQUE) { - RenderSystem.disableBlend(); - RenderSystem.defaultBlendFunc(); - } } public static final int DIFFUSE_MASK = 1; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java index 8162c7559..6a8a9eb37 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java @@ -42,14 +42,14 @@ public class IndirectDrawSet { for (var multiDraw : multiDraws.get(stage)) { multiDraw.submit(); } + MaterialUtil.reset(); } public void determineMultiDraws() { - // TODO: Better material equality. Really we only need to bin by the results of the setup method. multiDraws.clear(); // sort by stage, then material indirectDraws.sort(Comparator.comparing(IndirectDraw::stage) - .thenComparing(draw -> draw.material().hashCode())); + .thenComparing(IndirectDraw::material, MaterialUtil.BY_STATE)); for (int start = 0, i = 0; i < indirectDraws.size(); i++) { var draw = indirectDraws.get(i); @@ -75,7 +75,6 @@ public class IndirectDrawSet { void submit() { MaterialUtil.setup(material); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, start * IndirectBuffers.DRAW_COMMAND_STRIDE, end - start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE); - MaterialUtil.clear(material); } } } 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 451e95d95..dcc434235 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 @@ -120,7 +120,7 @@ public class InstancingEngine extends AbstractEngine { drawCall.render(); } - MaterialUtil.clear(shader.material()); + MaterialUtil.reset(); } } diff --git a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag index bb8ffc68b..49c5b1563 100644 --- a/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag +++ b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag @@ -9,16 +9,11 @@ vec4 flw_crumblingSampleColor; void flw_beginFragment() { flw_crumblingSampleColor = texture(flw_crumblingTex, _flw_crumblingTexCoord); - // Let the other components modify the diffuse color as they normally would. - flw_fragColor = flw_vertexColor * flw_sampleColor; - flw_fragOverlay = flw_vertexOverlay; - flw_fragLight = flw_vertexLight; -} - -void flw_endFragment() { - // Still need to discard based on the diffuse color so we don't crumble over empty space. if (flw_crumblingSampleColor.a < 0.01) { discard; } - +} + +void flw_endFragment() { + flw_fragColor = flw_crumblingSampleColor; } diff --git a/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.vert b/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.vert index 36e9c35c5..4083ef906 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.vert +++ b/src/main/resources/assets/flywheel/flywheel/internal/indirect/draw.vert @@ -1,6 +1,7 @@ #include "flywheel:internal/indirect/api/vertex.glsl" #include "flywheel:internal/indirect/mesh.glsl" #include "flywheel:internal/material.glsl" +#include "flywheel:util/diffuse.glsl" flat out uvec2 _flw_material;