diff --git a/src/main/java/com/jozufozu/flywheel/api/material/Cutout.java b/src/main/java/com/jozufozu/flywheel/api/material/Cutout.java new file mode 100644 index 000000000..70c3658fa --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/material/Cutout.java @@ -0,0 +1,16 @@ +package com.jozufozu.flywheel.api.material; + +public enum Cutout { + /** + * Do not discard any fragments based on alpha. + */ + OFF, + /** + * Discard fragments with alpha close to or equal to zero. + */ + EPSILON, + /** + * Discard fragments with alpha less than to 0.5. + */ + HALF, +} diff --git a/src/main/java/com/jozufozu/flywheel/api/material/Fog.java b/src/main/java/com/jozufozu/flywheel/api/material/Fog.java new file mode 100644 index 000000000..31d441960 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/material/Fog.java @@ -0,0 +1,16 @@ +package com.jozufozu.flywheel.api.material; + +public enum Fog { + /** + * Fade out to the fog color based on distance. + */ + LINEAR, + /** + * Fade out to black based on distance. + */ + LINEAR_FADE, + /** + * No fog. + */ + NONE, +} diff --git a/src/main/java/com/jozufozu/flywheel/api/material/Material.java b/src/main/java/com/jozufozu/flywheel/api/material/Material.java index b4e86639d..645fdf545 100644 --- a/src/main/java/com/jozufozu/flywheel/api/material/Material.java +++ b/src/main/java/com/jozufozu/flywheel/api/material/Material.java @@ -1,15 +1,54 @@ package com.jozufozu.flywheel.api.material; import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; public interface Material { - void setup(); - - void clear(); - - MaterialShaders shaders(); - RenderType getFallbackRenderType(); MaterialVertexTransformer getVertexTransformer(); + + MaterialShaders shaders(); + + ResourceLocation baseTexture(); + + /** + * Should this material be rendered with diffuse lighting? + * + * @return {@code true} if this material should be rendered with diffuse lighting. + */ + boolean diffuse(); + + /** + * Should this material be rendered with block/sky lighting? + * + * @return {@code true} if this material should be rendered with block/sky lighting. + */ + boolean lighting(); + + /** + * Should this material have linear filtering applied to the diffuse sampler? + * + * @return {@code true} if this material should be rendered with blur. + */ + boolean blur(); + + /** + * Should this material be rendered with backface culling? + * + * @return {@code true} if this material should be rendered with backface culling. + */ + boolean backfaceCull(); + + boolean polygonOffset(); + + boolean mip(); + + Fog fog(); + + Transparency transparency(); + + Cutout cutout(); + + WriteMask writeMask(); } diff --git a/src/main/java/com/jozufozu/flywheel/api/material/Transparency.java b/src/main/java/com/jozufozu/flywheel/api/material/Transparency.java new file mode 100644 index 000000000..ecdc3cebb --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/material/Transparency.java @@ -0,0 +1,10 @@ +package com.jozufozu.flywheel.api.material; + +public enum Transparency { + OPAQUE, + ADDITIVE, + LIGHTING, + GLINT, + CRUMBLING, + TRANSLUCENT, +} diff --git a/src/main/java/com/jozufozu/flywheel/api/material/WriteMask.java b/src/main/java/com/jozufozu/flywheel/api/material/WriteMask.java new file mode 100644 index 000000000..f3abe71d3 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/material/WriteMask.java @@ -0,0 +1,16 @@ +package com.jozufozu.flywheel.api.material; + +public enum WriteMask { + /** + * Write to both the color and depth buffers. + */ + BOTH, + /** + * Write to the color buffer only. + */ + COLOR, + /** + * Write to the depth buffer only. + */ + DEPTH, +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/MaterialUtil.java b/src/main/java/com/jozufozu/flywheel/backend/MaterialUtil.java new file mode 100644 index 000000000..49bb6f116 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/MaterialUtil.java @@ -0,0 +1,77 @@ +package com.jozufozu.flywheel.backend; + +import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.api.material.Transparency; +import com.jozufozu.flywheel.gl.GlTextureUnit; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.AbstractTexture; + +public class MaterialUtil { + public static void setup(Material material) { + GlTextureUnit.T0.makeActive(); + AbstractTexture texture = Minecraft.getInstance() + .getTextureManager() + .getTexture(material.baseTexture()); + texture.setFilter(material.blur(), material.mip()); + RenderSystem.setShaderTexture(0, texture.getId()); + + 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) { + 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; + public static final int LIGHTING_MASK = 1 << 1; + public static final int BLUR_MASK = 1 << 2; + public static final int BACKFACE_CULL_MASK = 1 << 3; + public static final int POLYGON_OFFSET_MASK = 1 << 4; + public static final int MIP_MASK = 1 << 5; + public static final int FOG_MASK = 0b11000000; + public static final int TRANSPARENCY_MASK = 0b11100000000; + public static final int CUTOUT_MASK = 0b1100000000000; + public static final int WRITE_MASK_MASK = 0b110000000000000; + + public static int packProperties(Material material) { + int out = 0; + + if (material.diffuse()) out |= DIFFUSE_MASK; + if (material.lighting()) out |= LIGHTING_MASK; + if (material.blur()) out |= BLUR_MASK; + if (material.backfaceCull()) out |= BACKFACE_CULL_MASK; + if (material.polygonOffset()) out |= POLYGON_OFFSET_MASK; + if (material.mip()) out |= MIP_MASK; + + out |= (material.fog() + .ordinal() & 0x3) << 6; + out |= (material.transparency() + .ordinal() & 0x7) << 8; + out |= (material.cutout() + .ordinal() & 0x3) << 11; + out |= (material.writeMask() + .ordinal() & 0x3) << 13; + + return out; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java index bbfcc6f7a..5f53fc8ec 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java @@ -6,6 +6,7 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.backend.MaterialShaderIndices; +import com.jozufozu.flywheel.backend.MaterialUtil; public class IndirectDraw { private final IndirectInstancer instancer; @@ -15,6 +16,7 @@ public class IndirectDraw { private final int vertexMaterialID; private final int fragmentMaterialID; + private final int packedMaterialProperties; private int baseInstance = -1; private boolean needsFullWrite = true; @@ -27,6 +29,7 @@ public class IndirectDraw { this.vertexMaterialID = MaterialShaderIndices.getVertexShaderIndex(material.shaders()); this.fragmentMaterialID = MaterialShaderIndices.getFragmentShaderIndex(material.shaders()); + this.packedMaterialProperties = MaterialUtil.packProperties(material); } public IndirectInstancer instancer() { @@ -75,5 +78,6 @@ public class IndirectDraw { boundingSphere.getToAddress(ptr + 20); // boundingSphere MemoryUtil.memPutInt(ptr + 36, vertexMaterialID); // vertexMaterialID MemoryUtil.memPutInt(ptr + 40, fragmentMaterialID); // fragmentMaterialID + MemoryUtil.memPutInt(ptr + 44, packedMaterialProperties); // packedMaterialProperties } } 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 78e9886c2..d7a35519a 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 @@ -13,6 +13,7 @@ import java.util.Map; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; +import com.jozufozu.flywheel.backend.MaterialUtil; public class IndirectDrawSet { @@ -72,10 +73,10 @@ public class IndirectDrawSet { private record MultiDraw(Material material, int start, int end) { void submit() { - material.setup(); + MaterialUtil.setup(material); Textures.bindActiveTextures(); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, start * IndirectBuffers.DRAW_COMMAND_STRIDE, end - start, (int) IndirectBuffers.DRAW_COMMAND_STRIDE); - material.clear(); + MaterialUtil.clear(material); } } } 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 02d071233..427530f96 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 @@ -20,6 +20,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import net.minecraft.client.Minecraft; import net.minecraft.client.resources.model.ModelBakery; public class InstancedCrumbling { @@ -109,11 +110,9 @@ public class InstancedCrumbling { } private static int getDiffuseTexture(Material material) { - material.setup(); - - int out = RenderSystem.getShaderTexture(0); - - material.clear(); - return out; + return Minecraft.getInstance() + .getTextureManager() + .getTexture(material.baseTexture()) + .getId(); } } 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 61afd655f..451e95d95 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 @@ -10,6 +10,7 @@ import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.task.Plan; import com.jozufozu.flywheel.api.task.TaskExecutor; import com.jozufozu.flywheel.backend.MaterialShaderIndices; +import com.jozufozu.flywheel.backend.MaterialUtil; import com.jozufozu.flywheel.backend.compile.InstancingPrograms; import com.jozufozu.flywheel.backend.engine.AbstractEngine; import com.jozufozu.flywheel.backend.engine.AbstractInstancer; @@ -113,20 +114,21 @@ public class InstancingEngine extends AbstractEngine { uploadMaterialIDUniform(program, shader.material()); - shader.material().setup(); + MaterialUtil.setup(shader.material()); for (var drawCall : drawCalls) { drawCall.render(); } - shader.material().clear(); + MaterialUtil.clear(shader.material()); } } public static void uploadMaterialIDUniform(GlProgram program, Material material) { - int materialIDUniform = program.getUniformLocation("_flw_materialID_instancing"); + int materialIDUniform = program.getUniformLocation("_flw_material_instancing"); int vertexID = MaterialShaderIndices.getVertexShaderIndex(material.shaders()); int fragmentID = MaterialShaderIndices.getFragmentShaderIndex(material.shaders()); - GL32.glUniform2ui(materialIDUniform, vertexID, fragmentID); + int packedMaterialProperties = MaterialUtil.packProperties(material); + GL32.glUniform3ui(materialIDUniform, vertexID, fragmentID, packedMaterialProperties); } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java index 3de25529c..6c313f037 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java @@ -2,17 +2,12 @@ package com.jozufozu.flywheel.lib.material; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.material.MaterialVertexTransformer; -import com.jozufozu.flywheel.gl.GlTextureUnit; -import com.jozufozu.flywheel.lib.material.SimpleMaterial.GlStateShard; +import com.jozufozu.flywheel.api.material.Transparency; import com.jozufozu.flywheel.lib.math.DiffuseLightCalculator; import com.jozufozu.flywheel.lib.util.ShadersModHandler; -import com.mojang.blaze3d.platform.GlStateManager; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; -import net.minecraft.client.renderer.texture.AbstractTexture; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.inventory.InventoryMenu; @@ -34,126 +29,108 @@ public final class Materials { private static final ResourceLocation MINECART_LOCATION = new ResourceLocation("textures/entity/minecart.png"); public static final Material CHUNK_SOLID_SHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(RenderType.solid()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_SOLID_UNSHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) + .diffuse(false) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) .fallbackRenderType(RenderType.solid()) .build(); public static final Material CHUNK_CUTOUT_MIPPED_SHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(RenderType.cutoutMipped()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_CUTOUT_MIPPED_UNSHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) + .diffuse(false) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) .shaders(StandardMaterialShaders.CUTOUT) .fallbackRenderType(RenderType.cutoutMipped()) .build(); public static final Material CHUNK_CUTOUT_SHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false)) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(false) .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(RenderType.cutout()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_CUTOUT_UNSHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false)) + .diffuse(false) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(false) .shaders(StandardMaterialShaders.CUTOUT) .fallbackRenderType(RenderType.cutout()) .build(); public static final Material CHUNK_TRANSLUCENT_SHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) - .addShard(Shards.TRANSLUCENT_TRANSPARENCY) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) + .transparency(Transparency.TRANSLUCENT) .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(RenderType.translucent()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_TRANSLUCENT_UNSHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) - .addShard(Shards.TRANSLUCENT_TRANSPARENCY) + .diffuse(false) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) + .transparency(Transparency.TRANSLUCENT) .fallbackRenderType(RenderType.translucent()) .build(); public static final Material CHUNK_TRIPWIRE_SHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) - .addShard(Shards.TRANSLUCENT_TRANSPARENCY) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) + .transparency(Transparency.TRANSLUCENT) .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(RenderType.tripwire()) .vertexTransformer(SHADING_TRANSFORMER) .build(); public static final Material CHUNK_TRIPWIRE_UNSHADED = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, true)) - .addShard(Shards.TRANSLUCENT_TRANSPARENCY) + .diffuse(false) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(true) + .transparency(Transparency.TRANSLUCENT) .shaders(StandardMaterialShaders.CUTOUT) .fallbackRenderType(RenderType.tripwire()) .build(); public static final Material CHEST = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(Sheets.CHEST_SHEET, false, false)) + .baseTexture(Sheets.CHEST_SHEET) + .mip(false) .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(Sheets.chestSheet()) .build(); public static final Material SHULKER = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(Sheets.SHULKER_SHEET, false, false)) - .addShard(Shards.DISABLE_CULL) + .baseTexture(Sheets.SHULKER_SHEET) + .mip(false) + .backfaceCull(false) .shaders(StandardMaterialShaders.SHADED_CUTOUT) .fallbackRenderType(Sheets.shulkerBoxSheet()) .build(); public static final Material BELL = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(InventoryMenu.BLOCK_ATLAS, false, false)) + .baseTexture(InventoryMenu.BLOCK_ATLAS) + .mip(false) .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(Sheets.solidBlockSheet()) .build(); public static final Material MINECART = SimpleMaterial.builder() - .addShard(Shards.diffuseTex(MINECART_LOCATION, false, false)) + .baseTexture(MINECART_LOCATION) + .mip(false) .shaders(StandardMaterialShaders.SHADED) .fallbackRenderType(RenderType.entitySolid(MINECART_LOCATION)) .build(); private Materials() { } - - public static final class Shards { - public static final GlStateShard DISABLE_CULL = new GlStateShard( - () -> { - RenderSystem.disableCull(); - }, - () -> { - RenderSystem.enableCull(); - } - ); - - public static final GlStateShard TRANSLUCENT_TRANSPARENCY = new GlStateShard( - () -> { - RenderSystem.enableBlend(); - RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); - }, - () -> { - RenderSystem.disableBlend(); - RenderSystem.defaultBlendFunc(); - } - ); - - public static GlStateShard diffuseTex(ResourceLocation loc, boolean blur, boolean mipmap) { - return new GlStateShard( - () -> { - GlTextureUnit.T0.makeActive(); - AbstractTexture texture = Minecraft.getInstance().getTextureManager().getTexture(loc); - texture.setFilter(blur, mipmap); - RenderSystem.setShaderTexture(0, texture.getId()); - }, - () -> { - GlTextureUnit.T0.makeActive(); - RenderSystem.setShaderTexture(0, 0); - } - ); - } - } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java index 8be882b3d..abce2153a 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java +++ b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java @@ -1,41 +1,55 @@ package com.jozufozu.flywheel.lib.material; +import com.jozufozu.flywheel.api.material.Cutout; +import com.jozufozu.flywheel.api.material.Fog; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.material.MaterialShaders; import com.jozufozu.flywheel.api.material.MaterialVertexTransformer; +import com.jozufozu.flywheel.api.material.Transparency; +import com.jozufozu.flywheel.api.material.WriteMask; -import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.InventoryMenu; public class SimpleMaterial implements Material { - protected final Runnable setup; - protected final Runnable clear; protected final MaterialShaders shaders; protected final RenderType fallbackRenderType; protected final MaterialVertexTransformer vertexTransformer; - public SimpleMaterial(Runnable setup, Runnable clear, MaterialShaders shaders, RenderType fallbackRenderType, MaterialVertexTransformer vertexTransformer) { - this.setup = setup; - this.clear = clear; - this.shaders = shaders; - this.fallbackRenderType = fallbackRenderType; - this.vertexTransformer = vertexTransformer; + protected final ResourceLocation baseTexture; + protected final boolean diffuse; + protected final boolean lighting; + protected final boolean blur; + protected final boolean backfaceCull; + protected final boolean polygonOffset; + protected final boolean mip; + protected final Fog fog; + protected final Transparency transparency; + protected final Cutout cutout; + protected final WriteMask writeMask; + + protected SimpleMaterial(Builder builder) { + this.shaders = builder.shaders; + this.fallbackRenderType = builder.fallbackRenderType; + this.vertexTransformer = builder.vertexTransformer; + this.baseTexture = builder.baseTexture; + this.diffuse = builder.diffuse; + this.lighting = builder.lighting; + this.blur = builder.blur; + this.backfaceCull = builder.backfaceCull; + this.polygonOffset = builder.polygonOffset; + this.mip = builder.mip; + this.fog = builder.fog; + this.transparency = builder.transparency; + this.cutout = builder.cutout; + this.writeMask = builder.writeMask; } public static Builder builder() { return new Builder(); } - @Override - public void setup() { - setup.run(); - } - - @Override - public void clear() { - clear.run(); - } - @Override public MaterialShaders shaders() { return shaders; @@ -51,37 +65,80 @@ public class SimpleMaterial implements Material { return vertexTransformer; } + @Override + public ResourceLocation baseTexture() { + return baseTexture; + } + + @Override + public boolean diffuse() { + return diffuse; + } + + @Override + public boolean lighting() { + return lighting; + } + + @Override + public boolean blur() { + return blur; + } + + @Override + public boolean backfaceCull() { + return backfaceCull; + } + + @Override + public boolean polygonOffset() { + return polygonOffset; + } + + @Override + public boolean mip() { + return mip; + } + + @Override + public Fog fog() { + return fog; + } + + @Override + public Transparency transparency() { + return transparency; + } + + @Override + public Cutout cutout() { + return cutout; + } + + @Override + public WriteMask writeMask() { + return WriteMask.BOTH; + } + public static class Builder { - protected Runnable setup = () -> {}; - protected Runnable clear = () -> {}; - protected MaterialShaders shaders = StandardMaterialShaders.DEFAULT; protected RenderType fallbackRenderType = RenderType.solid(); protected MaterialVertexTransformer vertexTransformer = (vertexList, level) -> {}; + protected MaterialShaders shaders = StandardMaterialShaders.DEFAULT; + protected ResourceLocation baseTexture = InventoryMenu.BLOCK_ATLAS; + protected boolean diffuse = true; + protected boolean lighting = true; + protected boolean blur = false; + protected boolean backfaceCull = true; + protected boolean polygonOffset = false; + protected boolean mip = true; + protected Fog fog = Fog.LINEAR; + protected Transparency transparency = Transparency.OPAQUE; + protected Cutout cutout = Cutout.OFF; + protected WriteMask writeMask = WriteMask.BOTH; public Builder() { } - public Builder addSetup(Runnable setup) { - this.setup = chain(this.setup, setup); - return this; - } - - public Builder addClear(Runnable clear) { - this.clear = chain(this.clear, clear); - return this; - } - - public Builder addShard(GlStateShard shard) { - addSetup(shard.getSetup()); - addClear(shard.getClear()); - return this; - } - - public Builder shaders(MaterialShaders shaders) { - this.shaders = shaders; - return this; - } - public Builder fallbackRenderType(RenderType type) { this.fallbackRenderType = type; return this; @@ -92,37 +149,68 @@ public class SimpleMaterial implements Material { return this; } + public Builder shaders(MaterialShaders value) { + this.shaders = value; + return this; + } + + public Builder baseTexture(ResourceLocation value) { + this.baseTexture = value; + return this; + } + + public Builder diffuse(boolean value) { + this.diffuse = value; + return this; + } + + public Builder lighting(boolean value) { + this.lighting = value; + return this; + } + + public Builder blur(boolean value) { + this.blur = value; + return this; + } + + public Builder backfaceCull(boolean value) { + this.backfaceCull = value; + return this; + } + + public Builder polygonOffset(boolean value) { + this.polygonOffset = value; + return this; + } + + public Builder mip(boolean value) { + this.mip = value; + return this; + } + + public Builder fog(Fog value) { + this.fog = value; + return this; + } + + public Builder transparency(Transparency value) { + this.transparency = value; + return this; + } + + public Builder cutout(Cutout value) { + this.cutout = value; + return this; + } + + public Builder writeMask(WriteMask value) { + this.writeMask = value; + return this; + } + public SimpleMaterial build() { - return new SimpleMaterial(setup, clear, shaders, fallbackRenderType, vertexTransformer); - } - - private static Runnable chain(Runnable runnable1, Runnable runnable2) { - return () -> { - runnable1.run(); - runnable2.run(); - }; - } - } - - public static class GlStateShard { - protected final Runnable setup; - protected final Runnable clear; - - public GlStateShard(Runnable setup, Runnable clear) { - this.setup = setup; - this.clear = clear; - } - - public static GlStateShard fromVanilla(RenderStateShard vanillaShard) { - return new GlStateShard(vanillaShard::setupRenderState, vanillaShard::clearRenderState); - } - - public Runnable getSetup() { - return setup; - } - - public Runnable getClear() { - return clear; + return new SimpleMaterial(this); } } } diff --git a/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl b/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl index e6a8d008a..ddd8586bd 100644 --- a/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl +++ b/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl @@ -14,6 +14,7 @@ in vec4 flw_var2; in vec4 flw_var3; flat in uint _flw_materialFragmentID; +flat in uint _flw_packedMaterialProperties; // diff --git a/src/main/resources/assets/flywheel/flywheel/api/vertex.glsl b/src/main/resources/assets/flywheel/flywheel/api/vertex.glsl index a57a89f6c..30af0bbf6 100644 --- a/src/main/resources/assets/flywheel/flywheel/api/vertex.glsl +++ b/src/main/resources/assets/flywheel/flywheel/api/vertex.glsl @@ -15,4 +15,5 @@ out vec4 flw_var1; out vec4 flw_var2; out vec4 flw_var3; flat out uint _flw_materialFragmentID; +flat out uint _flw_packedMaterialProperties; #endif 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 d4f774983..703098497 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/indirect_draw.vert +++ b/src/main/resources/assets/flywheel/flywheel/internal/indirect_draw.vert @@ -26,6 +26,7 @@ void main() { _flw_materialVertexID = drawCommands[batchID].vertexMaterialID; _flw_materialFragmentID = drawCommands[batchID].fragmentMaterialID; + _flw_packedMaterialProperties = drawCommands[batchID].packedMaterialProperties; flw_layoutVertex(); flw_initVertex(); diff --git a/src/main/resources/assets/flywheel/flywheel/internal/indirect_draw_command.glsl b/src/main/resources/assets/flywheel/flywheel/internal/indirect_draw_command.glsl index 4f4434a8a..f40faae2e 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/indirect_draw_command.glsl +++ b/src/main/resources/assets/flywheel/flywheel/internal/indirect_draw_command.glsl @@ -20,4 +20,5 @@ struct MeshDrawCommand { BoundingSphere boundingSphere; uint vertexMaterialID; uint fragmentMaterialID; + uint packedMaterialProperties; }; diff --git a/src/main/resources/assets/flywheel/flywheel/internal/instanced_arrays_draw.vert b/src/main/resources/assets/flywheel/flywheel/internal/instanced_arrays_draw.vert index 05a7aea3d..3a107c23f 100644 --- a/src/main/resources/assets/flywheel/flywheel/internal/instanced_arrays_draw.vert +++ b/src/main/resources/assets/flywheel/flywheel/internal/instanced_arrays_draw.vert @@ -1,10 +1,11 @@ #include "flywheel:api/vertex.glsl" -uniform uvec2 _flw_materialID_instancing; +uniform uvec3 _flw_material_instancing; void main() { - _flw_materialVertexID = _flw_materialID_instancing.x; - _flw_materialFragmentID = _flw_materialID_instancing.y; + _flw_materialVertexID = _flw_material_instancing.x; + _flw_materialFragmentID = _flw_material_instancing.y; + _flw_packedMaterialProperties = _flw_material_instancing.z; FlwInstance i = _flw_unpackInstance(); diff --git a/src/main/resources/assets/flywheel/flywheel/util/material.glsl b/src/main/resources/assets/flywheel/flywheel/util/material.glsl new file mode 100644 index 000000000..2eed067bb --- /dev/null +++ b/src/main/resources/assets/flywheel/flywheel/util/material.glsl @@ -0,0 +1,59 @@ +const uint LINEAR = 0; +const uint LINEAR_FADE = 1; +const uint NONE = 2; + +const uint OPAQUE_TRANSPARENCY = 0; +const uint ADDITIVE_TRANSPARENCY = 1; +const uint LIGHTING_TRANSPARENCY = 2; +const uint GLINT_TRANSPARENCY = 3; +const uint CRUMBLING_TRANSPARENCY = 4; +const uint TRANSLUCENT_TRANSPARENCY = 5; + +const uint CUTOUT_OFF = 0; +const uint CUTOUT_EPSILON = 1; +const uint CUTOUT_HALF = 2; + +const uint WRITE_MASK_BOTH = 0; +const uint WRITE_MASK_COLOR = 1; +const uint WRITE_MASK_DEPTH = 2; + +struct Material { + bool diffuse; + bool lighting; + bool blur; + bool backfaceCull; + bool polygonOffset; + bool mip; + + uint fog; + uint transparency; + uint cutout; + uint writeMask; +}; + +// Packed format: +// writeMask[2] | cutout[2] | transparency[3] | fog[2] | mip[1] | polygonOffset[1] | backfaceCull[1] | blur[1] | lighting[1] | diffuse[1] + +const uint DIFFUSE_MASK = 1; +const uint LIGHTING_MASK = 1 << 1; +const uint BLUR_MASK = 1 << 2; +const uint BACKFACE_CULL_MASK = 1 << 3; +const uint POLYGON_OFFSET_MASK = 1 << 4; +const uint MIP_MASK = 1 << 5; +const uint FOG_MASK = 3 << 6; +const uint TRANSPARENCY_MASK = 7 << 8; +const uint CUTOUT_MASK = 3 << 11; +const uint WRITE_MASK_MASK = 3 << 13; + +void unpackMaterial(uint m, out Material o) { + o.diffuse = (m & DIFFUSE_MASK) != 0; + o.lighting = (m & LIGHTING_MASK) != 0; + o.blur = (m & BLUR_MASK) != 0; + o.backfaceCull = (m & BACKFACE_CULL_MASK) != 0; + o.polygonOffset = (m & POLYGON_OFFSET_MASK) != 0; + o.mip = (m & MIP_MASK) != 0; + o.fog = (m & FOG_MASK) >> 6; + o.transparency = (m & TRANSPARENCY_MASK) >> 8; + o.cutout = (m & CUTOUT_MASK) >> 11; + o.writeMask = (m & WRITE_MASK_MASK) >> 13; +}