package net.minecraft.client.renderer; import com.mojang.blaze3d.buffers.Std140Builder; import com.mojang.blaze3d.buffers.Std140SizeCalculator; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.util.ExtraCodecs; import net.minecraft.util.StringRepresentable; import org.joml.Matrix4fc; import org.joml.Vector2f; import org.joml.Vector3f; import org.joml.Vector3i; import org.joml.Vector4f; @Environment(EnvType.CLIENT) public interface UniformValue { Codec CODEC = UniformValue.Type.CODEC.dispatch(UniformValue::type, type -> type.valueCodec); void writeTo(Std140Builder builder); void addSize(Std140SizeCalculator builder); UniformValue.Type type(); @Environment(EnvType.CLIENT) public record FloatUniform(float value) implements UniformValue { public static final Codec CODEC = Codec.FLOAT.xmap(UniformValue.FloatUniform::new, UniformValue.FloatUniform::value); @Override public void writeTo(Std140Builder builder) { builder.putFloat(this.value); } @Override public void addSize(Std140SizeCalculator builder) { builder.putFloat(); } @Override public UniformValue.Type type() { return UniformValue.Type.FLOAT; } } @Environment(EnvType.CLIENT) public record IVec3Uniform(Vector3i value) implements UniformValue { public static final Codec CODEC = ExtraCodecs.VECTOR3I.xmap(UniformValue.IVec3Uniform::new, UniformValue.IVec3Uniform::value); @Override public void writeTo(Std140Builder builder) { builder.putIVec3(this.value); } @Override public void addSize(Std140SizeCalculator builder) { builder.putIVec3(); } @Override public UniformValue.Type type() { return UniformValue.Type.IVEC3; } } @Environment(EnvType.CLIENT) public record IntUniform(int value) implements UniformValue { public static final Codec CODEC = Codec.INT.xmap(UniformValue.IntUniform::new, UniformValue.IntUniform::value); @Override public void writeTo(Std140Builder builder) { builder.putInt(this.value); } @Override public void addSize(Std140SizeCalculator builder) { builder.putInt(); } @Override public UniformValue.Type type() { return UniformValue.Type.INT; } } @Environment(EnvType.CLIENT) public record Matrix4x4Uniform(Matrix4fc value) implements UniformValue { public static final Codec CODEC = ExtraCodecs.MATRIX4F .xmap(UniformValue.Matrix4x4Uniform::new, UniformValue.Matrix4x4Uniform::value); @Override public void writeTo(Std140Builder builder) { builder.putMat4f(this.value); } @Override public void addSize(Std140SizeCalculator builder) { builder.putMat4f(); } @Override public UniformValue.Type type() { return UniformValue.Type.MATRIX4X4; } } @Environment(EnvType.CLIENT) public static enum Type implements StringRepresentable { INT("int", UniformValue.IntUniform.CODEC), IVEC3("ivec3", UniformValue.IVec3Uniform.CODEC), FLOAT("float", UniformValue.FloatUniform.CODEC), VEC2("vec2", UniformValue.Vec2Uniform.CODEC), VEC3("vec3", UniformValue.Vec3Uniform.CODEC), VEC4("vec4", UniformValue.Vec4Uniform.CODEC), MATRIX4X4("matrix4x4", UniformValue.Matrix4x4Uniform.CODEC); public static final StringRepresentable.EnumCodec CODEC = StringRepresentable.fromEnum(UniformValue.Type::values); private final String name; final MapCodec valueCodec; private Type(final String name, final Codec codec) { this.name = name; this.valueCodec = codec.fieldOf("value"); } @Override public String getSerializedName() { return this.name; } } @Environment(EnvType.CLIENT) public record Vec2Uniform(Vector2f value) implements UniformValue { public static final Codec CODEC = ExtraCodecs.VECTOR2F.xmap(UniformValue.Vec2Uniform::new, UniformValue.Vec2Uniform::value); @Override public void writeTo(Std140Builder builder) { builder.putVec2(this.value); } @Override public void addSize(Std140SizeCalculator builder) { builder.putVec2(); } @Override public UniformValue.Type type() { return UniformValue.Type.VEC2; } } @Environment(EnvType.CLIENT) public record Vec3Uniform(Vector3f value) implements UniformValue { public static final Codec CODEC = ExtraCodecs.VECTOR3F.xmap(UniformValue.Vec3Uniform::new, UniformValue.Vec3Uniform::value); @Override public void writeTo(Std140Builder builder) { builder.putVec3(this.value); } @Override public void addSize(Std140SizeCalculator builder) { builder.putVec3(); } @Override public UniformValue.Type type() { return UniformValue.Type.VEC3; } } @Environment(EnvType.CLIENT) public record Vec4Uniform(Vector4f value) implements UniformValue { public static final Codec CODEC = ExtraCodecs.VECTOR4F.xmap(UniformValue.Vec4Uniform::new, UniformValue.Vec4Uniform::value); @Override public void writeTo(Std140Builder builder) { builder.putVec4(this.value); } @Override public void addSize(Std140SizeCalculator builder) { builder.putVec4(); } @Override public UniformValue.Type type() { return UniformValue.Type.VEC4; } } }