From b453a79faa4f5cdad7a9f03430011b78fea68df5 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Sat, 17 Aug 2024 14:04:00 -0700 Subject: [PATCH] Multiple misc changes to shader interfaces --- .../serializer/VertexSerializerRegistry.java | 2 + .../gl/attribute/GlVertexAttributeFormat.java | 3 + .../client/gl/attribute/GlVertexFormat.java | 70 +++++++++-------- .../client/gl/buffer/IndexedVertexData.java | 2 +- .../sodium/client/gl/shader/GlProgram.java | 16 +++- .../sodium/client/gl/shader/ShaderType.java | 15 ++++ .../gl/tessellation/GlPrimitiveType.java | 6 +- .../client/gui/SodiumGameOptionPages.java | 6 +- .../sodium/client/gui/options/OptionImpl.java | 11 +-- .../render/chunk/DefaultChunkRenderer.java | 14 +--- .../render/chunk/ShaderChunkRenderer.java | 12 ++- .../chunk/shader/ChunkShaderFogComponent.java | 8 +- .../chunk/shader/ChunkShaderInterface.java | 66 ++-------------- .../chunk/shader/DefaultShaderInterface.java | 75 +++++++++++++++++++ .../chunk/shader/ShaderBindingContext.java | 4 +- .../vertex/format/ChunkMeshAttribute.java | 10 --- .../chunk/vertex/format/ChunkVertexType.java | 2 +- .../format/impl/CompactChunkVertex.java | 17 ++--- .../impl/DefaultChunkMeshAttributes.java | 12 +++ .../render/vertex/VertexFormatAttribute.java | 7 ++ .../VertexSerializerRegistryImpl.java | 5 ++ 21 files changed, 216 insertions(+), 147 deletions(-) create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java delete mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkMeshAttribute.java create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/DefaultChunkMeshAttributes.java create mode 100644 common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexFormatAttribute.java diff --git a/common/src/api/java/net/caffeinemc/mods/sodium/api/vertex/serializer/VertexSerializerRegistry.java b/common/src/api/java/net/caffeinemc/mods/sodium/api/vertex/serializer/VertexSerializerRegistry.java index 8aecabc7d9..cd870e90b4 100644 --- a/common/src/api/java/net/caffeinemc/mods/sodium/api/vertex/serializer/VertexSerializerRegistry.java +++ b/common/src/api/java/net/caffeinemc/mods/sodium/api/vertex/serializer/VertexSerializerRegistry.java @@ -12,4 +12,6 @@ static VertexSerializerRegistry instance() { } VertexSerializer get(VertexFormatDescription srcFormat, VertexFormatDescription dstFormat); + + void registerSerializer(VertexFormatDescription srcFormat, VertexFormatDescription dstFormat, VertexSerializer serializer); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java index 91d42c1662..7bcdfc628a 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexAttributeFormat.java @@ -7,6 +7,9 @@ */ public record GlVertexAttributeFormat(int typeId, int size) { public static final GlVertexAttributeFormat FLOAT = new GlVertexAttributeFormat(GL33C.GL_FLOAT, 4); + public static final GlVertexAttributeFormat INT = new GlVertexAttributeFormat(GL33C.GL_INT, 4); + public static final GlVertexAttributeFormat SHORT = new GlVertexAttributeFormat(GL33C.GL_SHORT, 2); + public static final GlVertexAttributeFormat BYTE = new GlVertexAttributeFormat(GL33C.GL_BYTE, 1); public static final GlVertexAttributeFormat UNSIGNED_SHORT = new GlVertexAttributeFormat(GL33C.GL_UNSIGNED_SHORT, 2); public static final GlVertexAttributeFormat UNSIGNED_BYTE = new GlVertexAttributeFormat(GL33C.GL_UNSIGNED_BYTE, 1); public static final GlVertexAttributeFormat UNSIGNED_INT = new GlVertexAttributeFormat(GL33C.GL_UNSIGNED_INT, 4); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexFormat.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexFormat.java index aee75108d0..f0d3e615c0 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexFormat.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/attribute/GlVertexFormat.java @@ -1,34 +1,38 @@ package net.caffeinemc.mods.sodium.client.gl.attribute; +import it.unimi.dsi.fastutil.objects.Object2IntArrayMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import net.caffeinemc.mods.sodium.client.render.vertex.VertexFormatAttribute; + import java.util.EnumMap; +import java.util.Map; /** - * Provides a generic vertex format which contains the attributes defined by {@param T}. Other code can then retrieve + * Provides a generic vertex format which contains the attributes defined by a {@link VertexFormatAttribute}. Other code can then retrieve * the attributes and work with encoded data in a generic manner without needing to rely on a specific format. - * - * @param The enumeration over the vertex attributes */ -public class GlVertexFormat> { - private final Class attributeEnum; - private final EnumMap attributesKeyed; +public class GlVertexFormat { + private final Map attributesKeyed; private final int stride; + private final GlVertexAttributeBinding[] bindings; - public GlVertexFormat(Class attributeEnum, EnumMap attributesKeyed, int stride) { - this.attributeEnum = attributeEnum; + public GlVertexFormat(Map attributesKeyed, GlVertexAttributeBinding[] bindings, int stride) { this.attributesKeyed = attributesKeyed; + this.bindings = bindings; this.stride = stride; } - public static > Builder builder(Class type, int stride) { - return new Builder<>(type, stride); + public static Builder builder(int stride) { + return new Builder(stride); } /** * Returns the {@link GlVertexAttribute} of this vertex format bound to the type {@param name}. * @throws NullPointerException If the attribute does not exist in this format */ - public GlVertexAttribute getAttribute(T name) { + public GlVertexAttribute getAttribute(VertexFormatAttribute name) { GlVertexAttribute attr = this.attributesKeyed.get(name); if (attr == null) { @@ -47,23 +51,27 @@ public int getStride() { @Override public String toString() { - return String.format("GlVertexFormat<%s>{attributes=%d,stride=%d}", this.attributeEnum.getName(), + return String.format("GlVertexFormat{attributes=%d,stride=%d}", this.attributesKeyed.size(), this.stride); } - public static class Builder> { - private final EnumMap attributes; - private final Class type; + public GlVertexAttributeBinding[] getShaderBindings() { + return bindings; + } + + public static class Builder { + private final Map attributes; + private final Object2IntMap bindings; private final int stride; - public Builder(Class type, int stride) { - this.type = type; - this.attributes = new EnumMap<>(type); + public Builder(int stride) { + this.attributes = new Object2ObjectArrayMap<>(); + this.bindings = new Object2IntArrayMap<>(); this.stride = stride; } - public Builder addElement(T type, int pointer, GlVertexAttributeFormat format, int count, boolean normalized, boolean intType) { - return this.addElement(type, new GlVertexAttribute(format, count, normalized, pointer, this.stride, intType)); + public Builder addElement(VertexFormatAttribute attribute, int binding, int pointer) { + return this.addElement(attribute, binding, new GlVertexAttribute(attribute.format(), attribute.count(), attribute.normalized(), pointer, this.stride, attribute.intType())); } /** @@ -73,7 +81,7 @@ public Builder addElement(T type, int pointer, GlVertexAttributeFormat format * @param attribute The attribute to bind * @throws IllegalStateException If an attribute is already bound to the generic type */ - private Builder addElement(T type, GlVertexAttribute attribute) { + private Builder addElement(VertexFormatAttribute type, int binding, GlVertexAttribute attribute) { if (attribute.getPointer() >= this.stride) { throw new IllegalArgumentException("Element starts outside vertex format"); } @@ -86,22 +94,20 @@ private Builder addElement(T type, GlVertexAttribute attribute) { throw new IllegalStateException("Generic attribute " + type.name() + " already defined in vertex format"); } + if (binding != -1) { + this.bindings.put(attribute, binding); + } + return this; } /** * Creates a {@link GlVertexFormat} from the current builder. */ - public GlVertexFormat build() { + public GlVertexFormat build() { int size = 0; - for (T key : this.type.getEnumConstants()) { - GlVertexAttribute attribute = this.attributes.get(key); - - if (attribute == null) { - throw new NullPointerException("Generic attribute not assigned to enumeration " + key.name()); - } - + for (GlVertexAttribute attribute : this.attributes.values()) { size = Math.max(size, attribute.getPointer() + attribute.getSize()); } @@ -111,7 +117,11 @@ public GlVertexFormat build() { throw new IllegalArgumentException("Stride is too small"); } - return new GlVertexFormat<>(this.type, this.attributes, this.stride); + GlVertexAttributeBinding[] bindings = this.bindings.object2IntEntrySet().stream() + .map(entry -> new GlVertexAttributeBinding(entry.getIntValue(), entry.getKey())) + .toArray(GlVertexAttributeBinding[]::new); + + return new GlVertexFormat(this.attributes, bindings, this.stride); } } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/buffer/IndexedVertexData.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/buffer/IndexedVertexData.java index e76d54d4fd..12b879ba99 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/buffer/IndexedVertexData.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/buffer/IndexedVertexData.java @@ -6,7 +6,7 @@ /** * Helper type for tagging the vertex format alongside the raw buffer data. */ -public record IndexedVertexData(GlVertexFormat vertexFormat, +public record IndexedVertexData(GlVertexFormat vertexFormat, NativeBuffer vertexBuffer, NativeBuffer indexBuffer) { public void delete() { diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/GlProgram.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/GlProgram.java index 94038561df..6c80eb1b41 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/GlProgram.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/GlProgram.java @@ -51,22 +51,30 @@ public void delete() { } @Override - public > U bindUniform(String name, IntFunction factory) { + public > U bindUniform(String name, IntFunction factory, boolean required) { int index = GL20C.glGetUniformLocation(this.handle(), name); if (index < 0) { - throw new NullPointerException("No uniform exists with name: " + name); + if (required) { + throw new NullPointerException("No uniform exists with name: " + name); + } else { + return null; + } } return factory.apply(index); } @Override - public GlUniformBlock bindUniformBlock(String name, int bindingPoint) { + public GlUniformBlock bindUniformBlock(String name, int bindingPoint, boolean required) { int index = GL32C.glGetUniformBlockIndex(this.handle(), name); if (index < 0) { - throw new NullPointerException("No uniform block exists with name: " + name); + if (required) { + throw new NullPointerException("No uniform block exists with name: " + name); + } else { + return null; + } } GL32C.glUniformBlockBinding(this.handle(), index, bindingPoint); diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderType.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderType.java index 4d4f1842bf..b7ce23c2e0 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderType.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/shader/ShaderType.java @@ -1,12 +1,17 @@ package net.caffeinemc.mods.sodium.client.gl.shader; import org.lwjgl.opengl.GL20C; +import org.lwjgl.opengl.GL32C; +import org.lwjgl.opengl.GL40C; /** * An enumeration over the supported OpenGL shader types. */ public enum ShaderType { VERTEX(GL20C.GL_VERTEX_SHADER), + GEOMETRY(GL32C.GL_GEOMETRY_SHADER), + TESS_CONTROL(GL40C.GL_TESS_CONTROL_SHADER), + TESS_EVALUATION(GL40C.GL_TESS_EVALUATION_SHADER), FRAGMENT(GL20C.GL_FRAGMENT_SHADER); public final int id; @@ -14,4 +19,14 @@ public enum ShaderType { ShaderType(int id) { this.id = id; } + + public static ShaderType fromGlShaderType(int id) { + for (ShaderType type : values()) { + if (type.id == id) { + return type; + } + } + + return null; + } } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/tessellation/GlPrimitiveType.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/tessellation/GlPrimitiveType.java index 2946bc40b6..19380ff653 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/tessellation/GlPrimitiveType.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gl/tessellation/GlPrimitiveType.java @@ -1,9 +1,13 @@ package net.caffeinemc.mods.sodium.client.gl.tessellation; import org.lwjgl.opengl.GL20C; +import org.lwjgl.opengl.GL40C; public enum GlPrimitiveType { - TRIANGLES(GL20C.GL_TRIANGLES); + POINTS(GL20C.GL_POINTS), + LINES(GL20C.GL_LINES), + TRIANGLES(GL20C.GL_TRIANGLES), + PATCHES(GL40C.GL_PATCHES); private final int id; diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java index f0cb6c37c9..b512dddc4e 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumGameOptionPages.java @@ -308,7 +308,7 @@ public static OptionPage performance() { .setControl(TickBoxControl::new) .setImpact(OptionImpact.LOW) .setBinding((opts, value) -> opts.performance.useNoErrorGLContext = value, opts -> opts.performance.useNoErrorGLContext) - .setEnabled(supportsNoErrorContext()) + .setEnabled(SodiumGameOptionPages::supportsNoErrorContext) .setFlags(OptionFlag.REQUIRES_GAME_RESTART) .build()) .build()); @@ -338,13 +338,15 @@ private static boolean supportsNoErrorContext() { public static OptionPage advanced() { List groups = new ArrayList<>(); + boolean isPersistentMappingSupported = MappedStagingBuffer.isSupported(RenderDevice.INSTANCE); + groups.add(OptionGroup.createBuilder() .add(OptionImpl.createBuilder(boolean.class, sodiumOpts) .setName(Component.translatable("sodium.options.use_persistent_mapping.name")) .setTooltip(Component.translatable("sodium.options.use_persistent_mapping.tooltip")) .setControl(TickBoxControl::new) .setImpact(OptionImpact.MEDIUM) - .setEnabled(MappedStagingBuffer.isSupported(RenderDevice.INSTANCE)) + .setEnabled(() -> isPersistentMappingSupported) .setBinding((opts, value) -> opts.advanced.useAdvancedStagingBuffers = value, opts -> opts.advanced.useAdvancedStagingBuffers) .setFlags(OptionFlag.REQUIRES_RENDERER_RELOAD) .build() diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/options/OptionImpl.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/options/OptionImpl.java index 42c4af342d..893bea4363 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/options/OptionImpl.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/options/OptionImpl.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.EnumSet; import java.util.function.BiConsumer; +import java.util.function.BooleanSupplier; import java.util.function.Function; public class OptionImpl implements Option { @@ -29,7 +30,7 @@ public class OptionImpl implements Option { private T value; private T modifiedValue; - private final boolean enabled; + private final BooleanSupplier enabled; private OptionImpl(OptionStorage storage, Component name, @@ -38,7 +39,7 @@ private OptionImpl(OptionStorage storage, Function, Control> control, EnumSet flags, OptionImpact impact, - boolean enabled) { + BooleanSupplier enabled) { this.storage = storage; this.name = name; this.tooltip = tooltip; @@ -94,7 +95,7 @@ public OptionStorage getStorage() { @Override public boolean isAvailable() { - return this.enabled; + return this.enabled.getAsBoolean(); } @Override @@ -125,7 +126,7 @@ public static class Builder { private Function, Control> control; private OptionImpact impact; private final EnumSet flags = EnumSet.noneOf(OptionFlag.class); - private boolean enabled = true; + private BooleanSupplier enabled = () -> true; private Builder(OptionStorage storage) { this.storage = storage; @@ -179,7 +180,7 @@ public Builder setImpact(OptionImpact impact) { return this; } - public Builder setEnabled(boolean value) { + public Builder setEnabled(BooleanSupplier value) { this.enabled = value; return this; diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java index 51d630203b..19b131f4e0 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/DefaultChunkRenderer.java @@ -20,7 +20,6 @@ import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderInterface; import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass; import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.SortBehavior; -import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType; import net.caffeinemc.mods.sodium.client.render.viewport.CameraTransform; import net.caffeinemc.mods.sodium.client.util.BitwiseMath; @@ -316,18 +315,7 @@ private GlTessellation prepareIndexedTessellation(CommandList commandList, Rende private GlTessellation createRegionTessellation(CommandList commandList, RenderRegion.DeviceResources resources, boolean useSharedIndexBuffer) { return commandList.createTessellation(GlPrimitiveType.TRIANGLES, new TessellationBinding[] { - TessellationBinding.forVertexBuffer(resources.getGeometryBuffer(), new GlVertexAttributeBinding[] { - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_HI, - this.vertexFormat.getAttribute(ChunkMeshAttribute.POSITION_HI)), - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_POSITION_LO, - this.vertexFormat.getAttribute(ChunkMeshAttribute.POSITION_LO)), - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_COLOR, - this.vertexFormat.getAttribute(ChunkMeshAttribute.COLOR)), - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_TEXTURE, - this.vertexFormat.getAttribute(ChunkMeshAttribute.TEXTURE)), - new GlVertexAttributeBinding(ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_MATERIAL_INDEX, - this.vertexFormat.getAttribute(ChunkMeshAttribute.LIGHT_MATERIAL_INDEX)) - }), + TessellationBinding.forVertexBuffer(resources.getGeometryBuffer(), this.vertexFormat.getShaderBindings()), TessellationBinding.forElementBuffer(useSharedIndexBuffer ? this.sharedIndexBuffer.getBufferObject() : resources.getIndexBuffer()) diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/ShaderChunkRenderer.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/ShaderChunkRenderer.java index ccd34ac6d4..fecce3ba8f 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/ShaderChunkRenderer.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/ShaderChunkRenderer.java @@ -4,14 +4,10 @@ import net.caffeinemc.mods.sodium.client.gl.attribute.GlVertexFormat; import net.caffeinemc.mods.sodium.client.gl.device.CommandList; import net.caffeinemc.mods.sodium.client.gl.device.RenderDevice; +import net.caffeinemc.mods.sodium.client.render.chunk.shader.*; import net.caffeinemc.mods.sodium.client.render.chunk.terrain.TerrainRenderPass; -import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType; import net.caffeinemc.mods.sodium.client.gl.shader.*; -import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkFogMode; -import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderBindingPoints; -import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderInterface; -import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderOptions; import net.minecraft.resources.ResourceLocation; import java.util.Map; @@ -19,7 +15,7 @@ public abstract class ShaderChunkRenderer implements ChunkRenderer { private final Map> programs = new Object2ObjectOpenHashMap<>(); protected final ChunkVertexType vertexType; - protected final GlVertexFormat vertexFormat; + protected final GlVertexFormat vertexFormat; protected final RenderDevice device; @@ -60,7 +56,7 @@ private GlProgram createShader(String path, ChunkShaderOpt .bindAttribute("a_TexCoord", ChunkShaderBindingPoints.ATTRIBUTE_TEXTURE) .bindAttribute("a_LightAndData", ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_MATERIAL_INDEX) .bindFragmentData("fragColor", ChunkShaderBindingPoints.FRAG_COLOR) - .link((shader) -> new ChunkShaderInterface(shader, options)); + .link((shader) -> new DefaultShaderInterface(shader, options)); } finally { vertShader.delete(); fragShader.delete(); @@ -79,6 +75,8 @@ protected void begin(TerrainRenderPass pass) { } protected void end(TerrainRenderPass pass) { + this.activeProgram.getInterface() + .resetState(); this.activeProgram.unbind(); this.activeProgram = null; diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderFogComponent.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderFogComponent.java index 6855970186..654b7b072e 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderFogComponent.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderFogComponent.java @@ -37,10 +37,10 @@ public static class Smooth extends ChunkShaderFogComponent { private final GlUniformFloat uFogEnd; public Smooth(ShaderBindingContext context) { - this.uFogColor = context.bindUniform("u_FogColor", GlUniformFloat4v::new); - this.uFogShape = context.bindUniform("u_FogShape", GlUniformInt::new); - this.uFogStart = context.bindUniform("u_FogStart", GlUniformFloat::new); - this.uFogEnd = context.bindUniform("u_FogEnd", GlUniformFloat::new); + this.uFogColor = context.bindUniform("u_FogColor", GlUniformFloat4v::new, true); + this.uFogShape = context.bindUniform("u_FogShape", GlUniformInt::new, true); + this.uFogStart = context.bindUniform("u_FogStart", GlUniformFloat::new, true); + this.uFogEnd = context.bindUniform("u_FogEnd", GlUniformFloat::new, true); } @Override diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderInterface.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderInterface.java index a5da4ac192..a5e51f3518 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderInterface.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ChunkShaderInterface.java @@ -1,67 +1,17 @@ package net.caffeinemc.mods.sodium.client.render.chunk.shader; -import com.mojang.blaze3d.platform.GlStateManager; -import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformFloat3v; -import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformInt; -import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformMatrix4f; -import net.caffeinemc.mods.sodium.client.util.TextureUtil; import org.joml.Matrix4fc; -import org.lwjgl.opengl.GL32C; -import java.util.EnumMap; -import java.util.Map; +public interface ChunkShaderInterface { + @Deprecated + void setupState(); -/** - * A forward-rendering shader program for chunks. - */ -public class ChunkShaderInterface { - private final Map uniformTextures; + @Deprecated + void resetState(); - private final GlUniformMatrix4f uniformModelViewMatrix; - private final GlUniformMatrix4f uniformProjectionMatrix; - private final GlUniformFloat3v uniformRegionOffset; + void setProjectionMatrix(Matrix4fc matrix); - // The fog shader component used by this program in order to setup the appropriate GL state - private final ChunkShaderFogComponent fogShader; + void setModelViewMatrix(Matrix4fc matrix); - public ChunkShaderInterface(ShaderBindingContext context, ChunkShaderOptions options) { - this.uniformModelViewMatrix = context.bindUniform("u_ModelViewMatrix", GlUniformMatrix4f::new); - this.uniformProjectionMatrix = context.bindUniform("u_ProjectionMatrix", GlUniformMatrix4f::new); - this.uniformRegionOffset = context.bindUniform("u_RegionOffset", GlUniformFloat3v::new); - - this.uniformTextures = new EnumMap<>(ChunkShaderTextureSlot.class); - this.uniformTextures.put(ChunkShaderTextureSlot.BLOCK, context.bindUniform("u_BlockTex", GlUniformInt::new)); - this.uniformTextures.put(ChunkShaderTextureSlot.LIGHT, context.bindUniform("u_LightTex", GlUniformInt::new)); - - this.fogShader = options.fog().getFactory().apply(context); - } - - @Deprecated // the shader interface should not modify pipeline state - public void setupState() { - this.bindTexture(ChunkShaderTextureSlot.BLOCK, TextureUtil.getBlockTextureId()); - this.bindTexture(ChunkShaderTextureSlot.LIGHT, TextureUtil.getLightTextureId()); - - this.fogShader.setup(); - } - - @Deprecated(forRemoval = true) // should be handled properly in GFX instead. - private void bindTexture(ChunkShaderTextureSlot slot, int textureId) { - GlStateManager._activeTexture(GL32C.GL_TEXTURE0 + slot.ordinal()); - GlStateManager._bindTexture(textureId); - - var uniform = this.uniformTextures.get(slot); - uniform.setInt(slot.ordinal()); - } - - public void setProjectionMatrix(Matrix4fc matrix) { - this.uniformProjectionMatrix.set(matrix); - } - - public void setModelViewMatrix(Matrix4fc matrix) { - this.uniformModelViewMatrix.set(matrix); - } - - public void setRegionOffset(float x, float y, float z) { - this.uniformRegionOffset.set(x, y, z); - } + void setRegionOffset(float x, float y, float z); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java new file mode 100644 index 0000000000..108a8a55a9 --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/DefaultShaderInterface.java @@ -0,0 +1,75 @@ +package net.caffeinemc.mods.sodium.client.render.chunk.shader; + +import com.mojang.blaze3d.platform.GlStateManager; +import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformFloat3v; +import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformInt; +import net.caffeinemc.mods.sodium.client.gl.shader.uniform.GlUniformMatrix4f; +import net.caffeinemc.mods.sodium.client.util.TextureUtil; +import org.joml.Matrix4fc; +import org.lwjgl.opengl.GL32C; + +import java.util.EnumMap; +import java.util.Map; + +/** + * A forward-rendering shader program for chunks. + */ +public class DefaultShaderInterface implements ChunkShaderInterface { + private final Map uniformTextures; + + private final GlUniformMatrix4f uniformModelViewMatrix; + private final GlUniformMatrix4f uniformProjectionMatrix; + private final GlUniformFloat3v uniformRegionOffset; + + // The fog shader component used by this program in order to setup the appropriate GL state + private final ChunkShaderFogComponent fogShader; + + public DefaultShaderInterface(ShaderBindingContext context, ChunkShaderOptions options) { + this.uniformModelViewMatrix = context.bindUniform("u_ModelViewMatrix", GlUniformMatrix4f::new, true); + this.uniformProjectionMatrix = context.bindUniform("u_ProjectionMatrix", GlUniformMatrix4f::new, true); + this.uniformRegionOffset = context.bindUniform("u_RegionOffset", GlUniformFloat3v::new, true); + + this.uniformTextures = new EnumMap<>(ChunkShaderTextureSlot.class); + this.uniformTextures.put(ChunkShaderTextureSlot.BLOCK, context.bindUniform("u_BlockTex", GlUniformInt::new, true)); + this.uniformTextures.put(ChunkShaderTextureSlot.LIGHT, context.bindUniform("u_LightTex", GlUniformInt::new, true)); + + this.fogShader = options.fog().getFactory().apply(context); + } + + @Override // the shader interface should not modify pipeline state + public void setupState() { + this.bindTexture(ChunkShaderTextureSlot.BLOCK, TextureUtil.getBlockTextureId()); + this.bindTexture(ChunkShaderTextureSlot.LIGHT, TextureUtil.getLightTextureId()); + + this.fogShader.setup(); + } + + @Override // the shader interface should not modify pipeline state + public void resetState() { + // This is used by alternate implementations. + } + + @Deprecated(forRemoval = true) // should be handled properly in GFX instead. + private void bindTexture(ChunkShaderTextureSlot slot, int textureId) { + GlStateManager._activeTexture(GL32C.GL_TEXTURE0 + slot.ordinal()); + GlStateManager._bindTexture(textureId); + + var uniform = this.uniformTextures.get(slot); + uniform.setInt(slot.ordinal()); + } + + @Override + public void setProjectionMatrix(Matrix4fc matrix) { + this.uniformProjectionMatrix.set(matrix); + } + + @Override + public void setModelViewMatrix(Matrix4fc matrix) { + this.uniformModelViewMatrix.set(matrix); + } + + @Override + public void setRegionOffset(float x, float y, float z) { + this.uniformRegionOffset.set(x, y, z); + } +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ShaderBindingContext.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ShaderBindingContext.java index 0797ff5408..c4fd5e88c2 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ShaderBindingContext.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/shader/ShaderBindingContext.java @@ -6,7 +6,7 @@ import java.util.function.IntFunction; public interface ShaderBindingContext { - > U bindUniform(String name, IntFunction factory); + > U bindUniform(String name, IntFunction factory, boolean required); - GlUniformBlock bindUniformBlock(String name, int bindingPoint); + GlUniformBlock bindUniformBlock(String name, int bindingPoint, boolean required); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkMeshAttribute.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkMeshAttribute.java deleted file mode 100644 index fd9b793f98..0000000000 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkMeshAttribute.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.caffeinemc.mods.sodium.client.render.chunk.vertex.format; - -public enum ChunkMeshAttribute { - POSITION_HI, - POSITION_LO, - - COLOR, - TEXTURE, - LIGHT_MATERIAL_INDEX, -} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexType.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexType.java index e3e01b492e..be35c4bf7c 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexType.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/ChunkVertexType.java @@ -3,7 +3,7 @@ import net.caffeinemc.mods.sodium.client.gl.attribute.GlVertexFormat; public interface ChunkVertexType { - GlVertexFormat getVertexFormat(); + GlVertexFormat getVertexFormat(); ChunkVertexEncoder getEncoder(); } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java index 1220f078e4..970a6afb31 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/CompactChunkVertex.java @@ -1,8 +1,7 @@ package net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.impl; -import net.caffeinemc.mods.sodium.client.gl.attribute.GlVertexAttributeFormat; import net.caffeinemc.mods.sodium.client.gl.attribute.GlVertexFormat; -import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute; +import net.caffeinemc.mods.sodium.client.render.chunk.shader.ChunkShaderBindingPoints; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder; import net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.ChunkVertexType; import net.caffeinemc.mods.sodium.client.render.frapi.helper.ColorHelper; @@ -12,12 +11,12 @@ public class CompactChunkVertex implements ChunkVertexType { public static final int STRIDE = 20; - public static final GlVertexFormat VERTEX_FORMAT = GlVertexFormat.builder(ChunkMeshAttribute.class, STRIDE) - .addElement(ChunkMeshAttribute.POSITION_HI, 0, GlVertexAttributeFormat.UNSIGNED_INT, 1, false, true) - .addElement(ChunkMeshAttribute.POSITION_LO, 4, GlVertexAttributeFormat.UNSIGNED_INT, 1, false, true) - .addElement(ChunkMeshAttribute.COLOR, 8, GlVertexAttributeFormat.UNSIGNED_BYTE, 4, true, false) - .addElement(ChunkMeshAttribute.TEXTURE, 12, GlVertexAttributeFormat.UNSIGNED_SHORT, 2, false, true) - .addElement(ChunkMeshAttribute.LIGHT_MATERIAL_INDEX, 16, GlVertexAttributeFormat.UNSIGNED_BYTE, 4, false, true) + public static final GlVertexFormat VERTEX_FORMAT = GlVertexFormat.builder(STRIDE) + .addElement(DefaultChunkMeshAttributes.POSITION_HI, ChunkShaderBindingPoints.ATTRIBUTE_POSITION_HI, 0) + .addElement(DefaultChunkMeshAttributes.POSITION_LO, ChunkShaderBindingPoints.ATTRIBUTE_POSITION_LO, 4) + .addElement(DefaultChunkMeshAttributes.COLOR, ChunkShaderBindingPoints.ATTRIBUTE_COLOR, 8) + .addElement(DefaultChunkMeshAttributes.TEXTURE, ChunkShaderBindingPoints.ATTRIBUTE_TEXTURE, 12) + .addElement(DefaultChunkMeshAttributes.LIGHT_MATERIAL_INDEX, ChunkShaderBindingPoints.ATTRIBUTE_LIGHT_MATERIAL_INDEX, 16) .build(); private static final int POSITION_MAX_VALUE = 1 << 20; @@ -27,7 +26,7 @@ public class CompactChunkVertex implements ChunkVertexType { private static final float MODEL_RANGE = 32.0f; @Override - public GlVertexFormat getVertexFormat() { + public GlVertexFormat getVertexFormat() { return VERTEX_FORMAT; } diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/DefaultChunkMeshAttributes.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/DefaultChunkMeshAttributes.java new file mode 100644 index 0000000000..5da6117115 --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/vertex/format/impl/DefaultChunkMeshAttributes.java @@ -0,0 +1,12 @@ +package net.caffeinemc.mods.sodium.client.render.chunk.vertex.format.impl; + +import net.caffeinemc.mods.sodium.client.gl.attribute.GlVertexAttributeFormat; +import net.caffeinemc.mods.sodium.client.render.vertex.VertexFormatAttribute; + +public class DefaultChunkMeshAttributes { + public static final VertexFormatAttribute POSITION_HI = new VertexFormatAttribute("POSITION_HI", GlVertexAttributeFormat.UNSIGNED_INT, 1, false, true); + public static final VertexFormatAttribute POSITION_LO = new VertexFormatAttribute("POSITION_LO", GlVertexAttributeFormat.UNSIGNED_INT, 1, false, true); + public static final VertexFormatAttribute COLOR = new VertexFormatAttribute("COLOR", GlVertexAttributeFormat.UNSIGNED_BYTE, 4, true, false); + public static final VertexFormatAttribute TEXTURE = new VertexFormatAttribute("TEXTURE", GlVertexAttributeFormat.UNSIGNED_SHORT, 2, false, true); + public static final VertexFormatAttribute LIGHT_MATERIAL_INDEX = new VertexFormatAttribute("LIGHT_MATERIAL_INDEX", GlVertexAttributeFormat.UNSIGNED_BYTE, 4, false, true); +} diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexFormatAttribute.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexFormatAttribute.java new file mode 100644 index 0000000000..f2e8231168 --- /dev/null +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/VertexFormatAttribute.java @@ -0,0 +1,7 @@ +package net.caffeinemc.mods.sodium.client.render.vertex; + +import net.caffeinemc.mods.sodium.client.gl.attribute.GlVertexAttributeFormat; + +public record VertexFormatAttribute(String name, GlVertexAttributeFormat format, int count, boolean normalized, boolean intType) { + +} \ No newline at end of file diff --git a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/serializers/VertexSerializerRegistryImpl.java b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/serializers/VertexSerializerRegistryImpl.java index ff85ca4f34..e7e4efe593 100644 --- a/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/serializers/VertexSerializerRegistryImpl.java +++ b/common/src/main/java/net/caffeinemc/mods/sodium/client/render/vertex/serializers/VertexSerializerRegistryImpl.java @@ -46,6 +46,11 @@ public VertexSerializer get(VertexFormatDescription srcFormat, VertexFormatDescr return serializer; } + @Override + public void registerSerializer(VertexFormatDescription srcFormat, VertexFormatDescription dstFormat, VertexSerializer serializer) { + this.cache.put(createKey(srcFormat, dstFormat), serializer); + } + private VertexSerializer create(long identifier, VertexFormatDescription srcFormat, VertexFormatDescription dstFormat) { var stamp = this.lock.writeLock();