From c79e94cd1828e3be675e17a6d819e1fca49cd95b Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Wed, 13 Dec 2023 13:40:31 -0800 Subject: [PATCH] Layout on me, dev - Move gl-coupled BufferLayout and co. to lib. - Add new Layout record to API. - List of Elements, a sealed interface of type safe records representing most possible vertex attributes. - Deprecate InstanceType#getLayout. - Add LayoutBuilder in lib for convenience. - TODO: use new Layouts in backends. --- .../flywheel/api/instance/InstanceType.java | 7 ++- .../jozufozu/flywheel/api/layout/Element.java | 54 +++++++++++++++++++ .../flywheel/api/layout/FloatType.java | 19 +++++++ .../flywheel/api/layout/IntegerType.java | 13 +++++ .../jozufozu/flywheel/api/layout/Layout.java | 6 +++ .../flywheel/api/layout/MatrixSize.java | 10 ++++ .../flywheel/api/layout/VectorSize.java | 13 +++++ .../flywheel/backend/InternalVertex.java | 2 +- .../compile/component/IndirectComponent.java | 2 +- .../component/InstancedArraysComponent.java | 2 +- .../engine/instancing/InstancedInstancer.java | 2 +- .../flywheel/lib/instance/OrientedType.java | 22 +++++++- .../lib/instance/TransformedType.java | 21 +++++++- .../{api => lib}/layout/BufferLayout.java | 2 +- .../{api => lib}/layout/InputType.java | 2 +- .../flywheel/lib/layout/LayoutBuilder.java | 49 +++++++++++++++++ .../{api => lib}/layout/LayoutItem.java | 2 +- .../flywheel/lib/layout/MatInput.java | 1 - .../flywheel/lib/layout/VecInput.java | 1 - 19 files changed, 216 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/layout/Element.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/layout/FloatType.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/layout/IntegerType.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/layout/Layout.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/layout/MatrixSize.java create mode 100644 src/main/java/com/jozufozu/flywheel/api/layout/VectorSize.java rename src/main/java/com/jozufozu/flywheel/{api => lib}/layout/BufferLayout.java (97%) rename src/main/java/com/jozufozu/flywheel/{api => lib}/layout/InputType.java (91%) create mode 100644 src/main/java/com/jozufozu/flywheel/lib/layout/LayoutBuilder.java rename src/main/java/com/jozufozu/flywheel/{api => lib}/layout/LayoutItem.java (58%) diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstanceType.java b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceType.java index 68509c366..7d069cce8 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/InstanceType.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceType.java @@ -1,8 +1,9 @@ package com.jozufozu.flywheel.api.instance; -import com.jozufozu.flywheel.api.layout.BufferLayout; +import com.jozufozu.flywheel.api.layout.Layout; import com.jozufozu.flywheel.api.registry.Registry; import com.jozufozu.flywheel.impl.RegistryImpl; +import com.jozufozu.flywheel.lib.layout.BufferLayout; import net.minecraft.resources.ResourceLocation; @@ -22,9 +23,13 @@ public interface InstanceType { /** * @return The layout of I when buffered. + * @deprecated Use {@link #layout()} instead. */ + @Deprecated BufferLayout getLayout(); + Layout layout(); + InstanceWriter getWriter(); ResourceLocation vertexShader(); diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/Element.java b/src/main/java/com/jozufozu/flywheel/api/layout/Element.java new file mode 100644 index 000000000..4332c8295 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/layout/Element.java @@ -0,0 +1,54 @@ +package com.jozufozu.flywheel.api.layout; + +/** + * A single element in a {@link Layout}. + */ +public sealed interface Element { + String name(); + + /** + * A simple vector of floats, i.e. {@code vec3}, {@code dvec2}. + *
+ * If {@link #type} is an integral type, the shader will implicitly convert it to a float without normalization. + * If you want normalization, use {@link NormalizedVector}. + * + * @param name The name of the element to be used in the shader. + * @param type The backing type of the element. + * @param size The number of components in the vector. + */ + record Vector(String name, FloatType type, VectorSize size) implements Element { + } + + /** + * A vector of integers, i.e. {@code ivec3}, {@code uvec2}. + *
+ * All backing types will be presented as either {@code int} or {@code uint} in the shader, + * depending on the signedness of the type. + * + * @param name The name of the element to be used in the shader. + * @param type The backing type of the element. + * @param size The number of components in the vector. + */ + record IntegerVector(String name, IntegerType type, VectorSize size) implements Element { + } + + /** + * A vector of integers, normalized and presented as a float in the shader. + * + * @param name The name of the element to be used in the shader. + * @param type The backing type of the element. + * @param size The number of components in the vector. + */ + record NormalizedVector(String name, IntegerType type, VectorSize size) implements Element { + } + + /** + * A matrix of 32-bit floating point numbers, i.e. {@code mat3}, {@code mat2x4}. + * + * @param name The name of the element to be used in the shader. + * @param rows The number of rows in the matrix. + * @param cols The number of columns in the matrix. + */ + record Matrix(String name, MatrixSize rows, MatrixSize cols) implements Element { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/FloatType.java b/src/main/java/com/jozufozu/flywheel/api/layout/FloatType.java new file mode 100644 index 000000000..8b7eb0939 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/layout/FloatType.java @@ -0,0 +1,19 @@ +package com.jozufozu.flywheel.api.layout; + +/** + * The backing type of traditional floating point vertex attributes. + *
+ * Integral types are implicitly converted to floats in the shader. + */ +public enum FloatType { + BYTE, + UNSIGNED_BYTE, + SHORT, + UNSIGNED_SHORT, + INT, + UNSIGNED_INT, + HALF_FLOAT, + FLOAT, + DOUBLE, + FIXED, +} diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/IntegerType.java b/src/main/java/com/jozufozu/flywheel/api/layout/IntegerType.java new file mode 100644 index 000000000..7ebd9e640 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/layout/IntegerType.java @@ -0,0 +1,13 @@ +package com.jozufozu.flywheel.api.layout; + +/** + * Integral types backing layout elements. + */ +public enum IntegerType { + BYTE, + UNSIGNED_BYTE, + SHORT, + UNSIGNED_SHORT, + INT, + UNSIGNED_INT +} diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/Layout.java b/src/main/java/com/jozufozu/flywheel/api/layout/Layout.java new file mode 100644 index 000000000..24f54c6be --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/layout/Layout.java @@ -0,0 +1,6 @@ +package com.jozufozu.flywheel.api.layout; + +import java.util.List; + +public record Layout(List elements) { +} diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/MatrixSize.java b/src/main/java/com/jozufozu/flywheel/api/layout/MatrixSize.java new file mode 100644 index 000000000..e1515aa35 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/layout/MatrixSize.java @@ -0,0 +1,10 @@ +package com.jozufozu.flywheel.api.layout; + +/** + * The size of a single dimension in a matrix. + */ +public enum MatrixSize { + TWO, + THREE, + FOUR, +} diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/VectorSize.java b/src/main/java/com/jozufozu/flywheel/api/layout/VectorSize.java new file mode 100644 index 000000000..d4a3152ba --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/layout/VectorSize.java @@ -0,0 +1,13 @@ +package com.jozufozu.flywheel.api.layout; + +/** + * The number of components in a vector. + *
+ * If the vector size is 1, the attribute is presented as a scalar. + */ +public enum VectorSize { + ONE, + TWO, + THREE, + FOUR, +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/InternalVertex.java b/src/main/java/com/jozufozu/flywheel/backend/InternalVertex.java index dc133b6db..b41e8ee73 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/InternalVertex.java +++ b/src/main/java/com/jozufozu/flywheel/backend/InternalVertex.java @@ -1,8 +1,8 @@ package com.jozufozu.flywheel.backend; import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.api.layout.BufferLayout; import com.jozufozu.flywheel.api.vertex.VertexView; +import com.jozufozu.flywheel.lib.layout.BufferLayout; import com.jozufozu.flywheel.lib.layout.CommonItems; import com.jozufozu.flywheel.lib.vertex.FullVertexView; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java b/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java index 53a88ecd0..9ff9d0e94 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/component/IndirectComponent.java @@ -6,13 +6,13 @@ import java.util.List; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.instance.InstanceType; -import com.jozufozu.flywheel.api.layout.LayoutItem; import com.jozufozu.flywheel.backend.compile.Pipeline; import com.jozufozu.flywheel.glsl.SourceComponent; import com.jozufozu.flywheel.glsl.generate.FnSignature; import com.jozufozu.flywheel.glsl.generate.GlslBlock; import com.jozufozu.flywheel.glsl.generate.GlslBuilder; import com.jozufozu.flywheel.glsl.generate.GlslExpr; +import com.jozufozu.flywheel.lib.layout.LayoutItem; import net.minecraft.resources.ResourceLocation; diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/component/InstancedArraysComponent.java b/src/main/java/com/jozufozu/flywheel/backend/compile/component/InstancedArraysComponent.java index cd9e29f59..4e1dffdaa 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/component/InstancedArraysComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/component/InstancedArraysComponent.java @@ -5,13 +5,13 @@ import java.util.Collections; import java.util.List; import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.api.layout.LayoutItem; import com.jozufozu.flywheel.backend.compile.Pipeline; import com.jozufozu.flywheel.glsl.SourceComponent; import com.jozufozu.flywheel.glsl.generate.FnSignature; import com.jozufozu.flywheel.glsl.generate.GlslBlock; import com.jozufozu.flywheel.glsl.generate.GlslBuilder; import com.jozufozu.flywheel.glsl.generate.GlslExpr; +import com.jozufozu.flywheel.lib.layout.LayoutItem; import net.minecraft.resources.ResourceLocation; diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java index 7dbb1773c..6ccf510f4 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedInstancer.java @@ -9,12 +9,12 @@ import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceWriter; -import com.jozufozu.flywheel.api.layout.BufferLayout; import com.jozufozu.flywheel.backend.engine.AbstractInstancer; import com.jozufozu.flywheel.gl.array.GlVertexArray; import com.jozufozu.flywheel.gl.buffer.GlBuffer; import com.jozufozu.flywheel.gl.buffer.GlBufferUsage; import com.jozufozu.flywheel.gl.buffer.MappedBuffer; +import com.jozufozu.flywheel.lib.layout.BufferLayout; public class InstancedInstancer extends AbstractInstancer { private final BufferLayout instanceFormat; diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedType.java b/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedType.java index cd9b50401..53b0e0095 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedType.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedType.java @@ -9,15 +9,20 @@ import com.jozufozu.flywheel.api.instance.InstanceHandle; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceVertexTransformer; import com.jozufozu.flywheel.api.instance.InstanceWriter; -import com.jozufozu.flywheel.api.layout.BufferLayout; +import com.jozufozu.flywheel.api.layout.FloatType; +import com.jozufozu.flywheel.api.layout.IntegerType; +import com.jozufozu.flywheel.api.layout.Layout; +import com.jozufozu.flywheel.api.layout.VectorSize; +import com.jozufozu.flywheel.lib.layout.BufferLayout; import com.jozufozu.flywheel.lib.layout.CommonItems; +import com.jozufozu.flywheel.lib.layout.LayoutBuilder; import com.jozufozu.flywheel.lib.math.RenderMath; import com.jozufozu.flywheel.lib.vertex.VertexTransformations; import net.minecraft.resources.ResourceLocation; public class OrientedType implements InstanceType { - private static final BufferLayout LAYOUT = BufferLayout.builder() + private static final BufferLayout OLD_LAYOUT = BufferLayout.builder() .addItem(CommonItems.LIGHT_COORD, "light") .addItem(CommonItems.UNORM_4x8, "color") .addItem(CommonItems.VEC3, "position") @@ -25,6 +30,14 @@ public class OrientedType implements InstanceType { .addItem(CommonItems.VEC4, "rotation") .build(); + private static final Layout LAYOUT = LayoutBuilder.of() + .integer("light", IntegerType.SHORT, VectorSize.TWO) + .normalized("color", IntegerType.BYTE, VectorSize.FOUR) + .vector("position", FloatType.FLOAT, VectorSize.THREE) + .vector("pivot", FloatType.FLOAT, VectorSize.THREE) + .vector("rotation", FloatType.FLOAT, VectorSize.FOUR) + .build(); + private static final ResourceLocation VERTEX_SHADER = Flywheel.rl("instance/oriented.vert"); private static final ResourceLocation CULL_SHADER = Flywheel.rl("instance/cull/oriented.glsl"); @@ -35,6 +48,11 @@ public class OrientedType implements InstanceType { @Override public BufferLayout getLayout() { + return OLD_LAYOUT; + } + + @Override + public Layout layout() { return LAYOUT; } diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedType.java b/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedType.java index e7cc580c3..4f0ac7d35 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedType.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedType.java @@ -6,8 +6,13 @@ import com.jozufozu.flywheel.api.instance.InstanceHandle; import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.InstanceVertexTransformer; import com.jozufozu.flywheel.api.instance.InstanceWriter; -import com.jozufozu.flywheel.api.layout.BufferLayout; +import com.jozufozu.flywheel.api.layout.IntegerType; +import com.jozufozu.flywheel.api.layout.Layout; +import com.jozufozu.flywheel.api.layout.MatrixSize; +import com.jozufozu.flywheel.api.layout.VectorSize; +import com.jozufozu.flywheel.lib.layout.BufferLayout; import com.jozufozu.flywheel.lib.layout.CommonItems; +import com.jozufozu.flywheel.lib.layout.LayoutBuilder; import com.jozufozu.flywheel.lib.math.MatrixMath; import com.jozufozu.flywheel.lib.math.RenderMath; import com.jozufozu.flywheel.lib.vertex.VertexTransformations; @@ -15,13 +20,20 @@ import com.jozufozu.flywheel.lib.vertex.VertexTransformations; import net.minecraft.resources.ResourceLocation; public class TransformedType implements InstanceType { - private static final BufferLayout LAYOUT = BufferLayout.builder() + private static final BufferLayout OLD_LAYOUT = BufferLayout.builder() .addItem(CommonItems.LIGHT_COORD, "light") .addItem(CommonItems.UNORM_4x8, "color") .addItem(CommonItems.MAT4, "pose") .addItem(CommonItems.MAT3, "normal") .build(); + public static final Layout LAYOUT = LayoutBuilder.of() + .integer("light", IntegerType.SHORT, VectorSize.TWO) + .normalized("color", IntegerType.BYTE, VectorSize.FOUR) + .mat("pose", MatrixSize.FOUR) + .mat("normal", MatrixSize.THREE) + .build(); + private static final ResourceLocation VERTEX_SHADER = Flywheel.rl("instance/transformed.vert"); private static final ResourceLocation CULL_SHADER = Flywheel.rl("instance/cull/transformed.glsl"); @@ -32,6 +44,11 @@ public class TransformedType implements InstanceType { @Override public BufferLayout getLayout() { + return OLD_LAYOUT; + } + + @Override + public Layout layout() { return LAYOUT; } diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/BufferLayout.java b/src/main/java/com/jozufozu/flywheel/lib/layout/BufferLayout.java similarity index 97% rename from src/main/java/com/jozufozu/flywheel/api/layout/BufferLayout.java rename to src/main/java/com/jozufozu/flywheel/lib/layout/BufferLayout.java index 808c5031b..f074df1b0 100644 --- a/src/main/java/com/jozufozu/flywheel/api/layout/BufferLayout.java +++ b/src/main/java/com/jozufozu/flywheel/lib/layout/BufferLayout.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.api.layout; +package com.jozufozu.flywheel.lib.layout; import java.util.List; diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/InputType.java b/src/main/java/com/jozufozu/flywheel/lib/layout/InputType.java similarity index 91% rename from src/main/java/com/jozufozu/flywheel/api/layout/InputType.java rename to src/main/java/com/jozufozu/flywheel/lib/layout/InputType.java index 376697555..1bbf67a8f 100644 --- a/src/main/java/com/jozufozu/flywheel/api/layout/InputType.java +++ b/src/main/java/com/jozufozu/flywheel/lib/layout/InputType.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.api.layout; +package com.jozufozu.flywheel.lib.layout; import java.util.function.Consumer; diff --git a/src/main/java/com/jozufozu/flywheel/lib/layout/LayoutBuilder.java b/src/main/java/com/jozufozu/flywheel/lib/layout/LayoutBuilder.java new file mode 100644 index 000000000..8e11bf90c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/layout/LayoutBuilder.java @@ -0,0 +1,49 @@ +package com.jozufozu.flywheel.lib.layout; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.ImmutableList; +import com.jozufozu.flywheel.api.layout.Element; +import com.jozufozu.flywheel.api.layout.FloatType; +import com.jozufozu.flywheel.api.layout.IntegerType; +import com.jozufozu.flywheel.api.layout.Layout; +import com.jozufozu.flywheel.api.layout.MatrixSize; +import com.jozufozu.flywheel.api.layout.VectorSize; + +public class LayoutBuilder { + private final List elements = new ArrayList<>(); + + public static LayoutBuilder of() { + return new LayoutBuilder(); + } + + public Layout build() { + return new Layout(ImmutableList.copyOf(elements)); + } + + public LayoutBuilder element(Element element) { + elements.add(element); + return this; + } + + public LayoutBuilder integer(String name, IntegerType type, VectorSize size) { + return element(new Element.IntegerVector(name, type, size)); + } + + public LayoutBuilder normalized(String name, IntegerType type, VectorSize size) { + return element(new Element.NormalizedVector(name, type, size)); + } + + public LayoutBuilder vector(String name, FloatType type, VectorSize size) { + return element(new Element.Vector(name, type, size)); + } + + public LayoutBuilder mat(String name, MatrixSize rows, MatrixSize cols) { + return element(new Element.Matrix(name, rows, cols)); + } + + public LayoutBuilder mat(String name, MatrixSize size) { + return mat(name, size, size); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/LayoutItem.java b/src/main/java/com/jozufozu/flywheel/lib/layout/LayoutItem.java similarity index 58% rename from src/main/java/com/jozufozu/flywheel/api/layout/LayoutItem.java rename to src/main/java/com/jozufozu/flywheel/lib/layout/LayoutItem.java index 07d152153..5bc8c082d 100644 --- a/src/main/java/com/jozufozu/flywheel/api/layout/LayoutItem.java +++ b/src/main/java/com/jozufozu/flywheel/lib/layout/LayoutItem.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.api.layout; +package com.jozufozu.flywheel.lib.layout; public record LayoutItem(InputType type, String name) { diff --git a/src/main/java/com/jozufozu/flywheel/lib/layout/MatInput.java b/src/main/java/com/jozufozu/flywheel/lib/layout/MatInput.java index e985375f8..d5a4e9ab5 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/layout/MatInput.java +++ b/src/main/java/com/jozufozu/flywheel/lib/layout/MatInput.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; -import com.jozufozu.flywheel.api.layout.InputType; import com.jozufozu.flywheel.gl.GlNumericType; import com.jozufozu.flywheel.gl.array.VertexAttribute; import com.jozufozu.flywheel.glsl.generate.FnSignature; diff --git a/src/main/java/com/jozufozu/flywheel/lib/layout/VecInput.java b/src/main/java/com/jozufozu/flywheel/lib/layout/VecInput.java index 00844872d..6878364f5 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/layout/VecInput.java +++ b/src/main/java/com/jozufozu/flywheel/lib/layout/VecInput.java @@ -3,7 +3,6 @@ package com.jozufozu.flywheel.lib.layout; import java.util.function.Consumer; import java.util.function.Function; -import com.jozufozu.flywheel.api.layout.InputType; import com.jozufozu.flywheel.gl.array.VertexAttribute; import com.jozufozu.flywheel.glsl.generate.GlslBuilder; import com.jozufozu.flywheel.glsl.generate.GlslExpr;