mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 07:26:48 +01:00
Rewrite the layout API
This commit is contained in:
parent
c8590629a1
commit
2cb68fea95
29 changed files with 529 additions and 193 deletions
|
@ -26,11 +26,11 @@ public interface InstanceType<I extends Instance> {
|
|||
* @deprecated Use {@link #layout()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
BufferLayout getLayout();
|
||||
BufferLayout oldLayout();
|
||||
|
||||
Layout layout();
|
||||
|
||||
InstanceWriter<I> getWriter();
|
||||
InstanceWriter<I> writer();
|
||||
|
||||
ResourceLocation vertexShader();
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
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}.
|
||||
* <br>
|
||||
* 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}.
|
||||
* <br>
|
||||
* 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 {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
public sealed interface ElementType permits ScalarElementType, VectorElementType, MatrixElementType {
|
||||
int byteSize();
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
public enum FloatRepr implements ValueRepr {
|
||||
BYTE(Byte.BYTES),
|
||||
NORMALIZED_BYTE(Byte.BYTES),
|
||||
UNSIGNED_BYTE(Byte.BYTES),
|
||||
NORMALIZED_UNSIGNED_BYTE(Byte.BYTES),
|
||||
SHORT(Short.BYTES),
|
||||
NORMALIZED_SHORT(Short.BYTES),
|
||||
UNSIGNED_SHORT(Short.BYTES),
|
||||
NORMALIZED_UNSIGNED_SHORT(Short.BYTES),
|
||||
INT(Integer.BYTES),
|
||||
NORMALIZED_INT(Integer.BYTES),
|
||||
UNSIGNED_INT(Integer.BYTES),
|
||||
NORMALIZED_UNSIGNED_INT(Integer.BYTES),
|
||||
FLOAT(Float.BYTES);
|
||||
|
||||
private final int byteSize;
|
||||
|
||||
FloatRepr(int byteSize) {
|
||||
this.byteSize = byteSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return byteSize;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
/**
|
||||
* The backing type of traditional floating point vertex attributes.
|
||||
* <br>
|
||||
* 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,
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
public enum IntegerRepr implements ValueRepr {
|
||||
BYTE(Byte.BYTES),
|
||||
SHORT(Short.BYTES),
|
||||
INT(Integer.BYTES);
|
||||
|
||||
private final int byteSize;
|
||||
|
||||
IntegerRepr(int byteSize) {
|
||||
this.byteSize = byteSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return byteSize;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
/**
|
||||
* Integral types backing layout elements.
|
||||
*/
|
||||
public enum IntegerType {
|
||||
BYTE,
|
||||
UNSIGNED_BYTE,
|
||||
SHORT,
|
||||
UNSIGNED_SHORT,
|
||||
INT,
|
||||
UNSIGNED_INT
|
||||
}
|
|
@ -1,6 +1,27 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public record Layout(List<Element> elements) {
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public interface Layout {
|
||||
int MAX_ELEMENT_NAME_LENGTH = 896;
|
||||
|
||||
@Unmodifiable
|
||||
List<Element> elements();
|
||||
|
||||
@Unmodifiable
|
||||
Map<String, ElementType> asMap();
|
||||
|
||||
int byteSize();
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
interface Element {
|
||||
String name();
|
||||
|
||||
ElementType type();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
import com.jozufozu.flywheel.impl.layout.LayoutBuilderImpl;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public interface LayoutBuilder {
|
||||
LayoutBuilder scalar(String name, ValueRepr repr);
|
||||
|
||||
LayoutBuilder vector(String name, ValueRepr repr, @Range(from = 2, to = 4) int size);
|
||||
|
||||
LayoutBuilder matrix(String name, FloatRepr repr, @Range(from = 2, to = 4) int rows, @Range(from = 2, to = 4) int columns);
|
||||
|
||||
LayoutBuilder matrix(String name, FloatRepr repr, @Range(from = 2, to = 4) int size);
|
||||
|
||||
Layout build();
|
||||
|
||||
static LayoutBuilder create() {
|
||||
return new LayoutBuilderImpl();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public non-sealed interface MatrixElementType extends ElementType {
|
||||
FloatRepr repr();
|
||||
|
||||
@Range(from = 2, to = 4)
|
||||
int rows();
|
||||
|
||||
@Range(from = 2, to = 4)
|
||||
int columns();
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
/**
|
||||
* The size of a single dimension in a matrix.
|
||||
*/
|
||||
public enum MatrixSize {
|
||||
TWO,
|
||||
THREE,
|
||||
FOUR,
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public non-sealed interface ScalarElementType extends ElementType {
|
||||
ValueRepr repr();
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
public enum UnsignedIntegerRepr implements ValueRepr {
|
||||
UNSIGNED_BYTE(Byte.BYTES),
|
||||
UNSIGNED_SHORT(Short.BYTES),
|
||||
UNSIGNED_INT(Integer.BYTES);
|
||||
|
||||
private final int byteSize;
|
||||
|
||||
UnsignedIntegerRepr(int byteSize) {
|
||||
this.byteSize = byteSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return byteSize;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
public sealed interface ValueRepr permits IntegerRepr, UnsignedIntegerRepr, FloatRepr {
|
||||
int byteSize();
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
@ApiStatus.NonExtendable
|
||||
public non-sealed interface VectorElementType extends ElementType {
|
||||
ValueRepr repr();
|
||||
|
||||
@Range(from = 2, to = 4)
|
||||
int size();
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package com.jozufozu.flywheel.api.layout;
|
||||
|
||||
/**
|
||||
* The number of components in a vector.
|
||||
* <br>
|
||||
* If the vector size is 1, the attribute is presented as a scalar.
|
||||
*/
|
||||
public enum VectorSize {
|
||||
ONE,
|
||||
TWO,
|
||||
THREE,
|
||||
FOUR,
|
||||
}
|
|
@ -34,7 +34,7 @@ public class IndirectComponent implements SourceComponent {
|
|||
}
|
||||
|
||||
public static IndirectComponent create(InstanceType<?> instanceType) {
|
||||
return new IndirectComponent(instanceType.getLayout().layoutItems);
|
||||
return new IndirectComponent(instanceType.oldLayout().layoutItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,7 +25,7 @@ public class InstancedArraysComponent implements SourceComponent {
|
|||
|
||||
public InstancedArraysComponent(Pipeline.InstanceAssemblerContext ctx) {
|
||||
this.layoutItems = ctx.instanceType()
|
||||
.getLayout().layoutItems;
|
||||
.oldLayout().layoutItems;
|
||||
this.baseIndex = ctx.baseAttribute();
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
|||
applyProgram = programs.getApplyProgram();
|
||||
drawProgram = programs.getIndirectProgram(instanceType, Contexts.DEFAULT);
|
||||
|
||||
objectStride = instanceType.getLayout()
|
||||
objectStride = instanceType.oldLayout()
|
||||
.getStride() + IndirectBuffers.INT_SIZE;
|
||||
|
||||
buffers = new IndirectBuffers(objectStride);
|
||||
|
|
|
@ -20,10 +20,10 @@ public class IndirectInstancer<I extends Instance> extends AbstractInstancer<I>
|
|||
|
||||
public IndirectInstancer(InstanceType<I> type) {
|
||||
super(type);
|
||||
long instanceStride = type.getLayout()
|
||||
long instanceStride = type.oldLayout()
|
||||
.getStride();
|
||||
this.objectStride = instanceStride + IndirectBuffers.INT_SIZE;
|
||||
writer = this.type.getWriter();
|
||||
writer = this.type.writer();
|
||||
}
|
||||
|
||||
public void addDraw(IndirectDraw draw) {
|
||||
|
|
|
@ -28,9 +28,9 @@ public class InstancedInstancer<I extends Instance> extends AbstractInstancer<I>
|
|||
|
||||
public InstancedInstancer(InstanceType<I> type) {
|
||||
super(type);
|
||||
instanceFormat = type.getLayout();
|
||||
instanceFormat = type.oldLayout();
|
||||
instanceStride = instanceFormat.getStride();
|
||||
writer = type.getWriter();
|
||||
writer = type.writer();
|
||||
}
|
||||
|
||||
public int getAttributeCount() {
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
package com.jozufozu.flywheel.impl.layout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
import com.jozufozu.flywheel.api.layout.FloatRepr;
|
||||
import com.jozufozu.flywheel.api.layout.Layout;
|
||||
import com.jozufozu.flywheel.api.layout.Layout.Element;
|
||||
import com.jozufozu.flywheel.api.layout.LayoutBuilder;
|
||||
import com.jozufozu.flywheel.api.layout.ValueRepr;
|
||||
import com.jozufozu.flywheel.impl.layout.LayoutImpl.ElementImpl;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
|
||||
public class LayoutBuilderImpl implements LayoutBuilder {
|
||||
private static final Set<String> GLSL_KEYWORDS = Set.of(
|
||||
// standard keywords
|
||||
"const", "uniform", "buffer", "shared", "attribute", "varying",
|
||||
"coherent", "volatile", "restrict", "readonly", "writeonly",
|
||||
"atomic_uint",
|
||||
"layout",
|
||||
"centroid", "flat", "smooth", "noperspective",
|
||||
"patch", "sample",
|
||||
"invariant", "precise",
|
||||
"break", "continue", "do", "for", "while", "switch", "case", "default",
|
||||
"if", "else",
|
||||
"subroutine",
|
||||
"in", "out", "inout",
|
||||
"int", "void", "bool", "true", "false", "float", "double",
|
||||
"discard", "return",
|
||||
"vec2", "vec3", "vec4", "ivec2", "ivec3", "ivec4", "bvec2", "bvec3", "bvec4",
|
||||
"uint", "uvec2", "uvec3", "uvec4",
|
||||
"dvec2", "dvec3", "dvec4",
|
||||
"mat2", "mat3", "mat4",
|
||||
"mat2x2", "mat2x3", "mat2x4",
|
||||
"mat3x2", "mat3x3", "mat3x4",
|
||||
"mat4x2", "mat4x3", "mat4x4",
|
||||
"dmat2", "dmat3", "dmat4",
|
||||
"dmat2x2", "dmat2x3", "dmat2x4",
|
||||
"dmat3x2", "dmat3x3", "dmat3x4",
|
||||
"dmat4x2", "dmat4x3", "dmat4x4",
|
||||
"lowp", "mediump", "highp", "precision",
|
||||
"sampler1D", "sampler1DShadow", "sampler1DArray", "sampler1DArrayShadow",
|
||||
"isampler1D", "isampler1DArray", "usampler1D", "usampler1DArray",
|
||||
"sampler2D", "sampler2DShadow", "sampler2DArray", "sampler2DArrayShadow",
|
||||
"isampler2D", "isampler2DArray", "usampler2D", "usampler2DArray",
|
||||
"sampler2DRect", "sampler2DRectShadow", "isampler2DRect", "usampler2DRect",
|
||||
"sampler2DMS", "isampler2DMS", "usampler2DMS",
|
||||
"sampler2DMSArray", "isampler2DMSArray", "usampler2DMSArray",
|
||||
"sampler3D", "isampler3D", "usampler3D",
|
||||
"samplerCube", "samplerCubeShadow", "isamplerCube", "usamplerCube",
|
||||
"samplerCubeArray", "samplerCubeArrayShadow",
|
||||
"isamplerCubeArray", "usamplerCubeArray",
|
||||
"samplerBuffer", "isamplerBuffer", "usamplerBuffer",
|
||||
"image1D", "iimage1D", "uimage1D",
|
||||
"image1DArray", "iimage1DArray", "uimage1DArray",
|
||||
"image2D", "iimage2D", "uimage2D",
|
||||
"image2DArray", "iimage2DArray", "uimage2DArray",
|
||||
"image2DRect", "iimage2DRect", "uimage2DRect",
|
||||
"image2DMS", "iimage2DMS", "uimage2DMS",
|
||||
"image2DMSArray", "iimage2DMSArray", "uimage2DMSArray",
|
||||
"image3D", "iimage3D", "uimage3D",
|
||||
"imageCube", "iimageCube", "uimageCube",
|
||||
"imageCubeArray", "iimageCubeArray", "uimageCubeArray",
|
||||
"imageBuffer", "iimageBuffer", "uimageBuffer",
|
||||
"struct",
|
||||
// Vulkan keywords
|
||||
"texture1D", "texture1DArray",
|
||||
"itexture1D", "itexture1DArray", "utexture1D", "utexture1DArray",
|
||||
"texture2D", "texture2DArray",
|
||||
"itexture2D", "itexture2DArray", "utexture2D", "utexture2DArray",
|
||||
"texture2DRect", "itexture2DRect", "utexture2DRect",
|
||||
"texture2DMS", "itexture2DMS", "utexture2DMS",
|
||||
"texture2DMSArray", "itexture2DMSArray", "utexture2DMSArray",
|
||||
"texture3D", "itexture3D", "utexture3D",
|
||||
"textureCube", "itextureCube", "utextureCube",
|
||||
"textureCubeArray", "itextureCubeArray", "utextureCubeArray",
|
||||
"textureBuffer", "itextureBuffer", "utextureBuffer",
|
||||
"sampler", "samplerShadow",
|
||||
"subpassInput", "isubpassInput", "usubpassInput",
|
||||
"subpassInputMS", "isubpassInputMS", "usubpassInputMS",
|
||||
// reserved keywords
|
||||
"common", "partition", "active",
|
||||
"asm",
|
||||
"class", "union", "enum", "typedef", "template", "this",
|
||||
"resource",
|
||||
"goto",
|
||||
"inline", "noinline", "public", "static", "extern", "external", "interface",
|
||||
"long", "short", "half", "fixed", "unsigned", "superp",
|
||||
"input", "output",
|
||||
"hvec2", "hvec3", "hvec4", "fvec2", "fvec3", "fvec4",
|
||||
"filter",
|
||||
"sizeof", "cast",
|
||||
"namespace", "using",
|
||||
"sampler3DRect"
|
||||
);
|
||||
|
||||
private final List<Element> elements = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public LayoutBuilder scalar(String name, ValueRepr repr) {
|
||||
elements.add(new ElementImpl(name, new ScalarElementTypeImpl(repr)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutBuilder vector(String name, ValueRepr repr, @Range(from = 2, to = 4) int size) {
|
||||
elements.add(new ElementImpl(name, new VectorElementTypeImpl(repr, size)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutBuilder matrix(String name, FloatRepr repr, @Range(from = 2, to = 4) int rows, @Range(from = 2, to = 4) int columns) {
|
||||
elements.add(new ElementImpl(name, new MatrixElementTypeImpl(repr, rows, columns)));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutBuilder matrix(String name, FloatRepr repr, @Range(from = 2, to = 4) int size) {
|
||||
return matrix(name, repr, size, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layout build() {
|
||||
Object2IntMap<String> name2IndexMap = new Object2IntOpenHashMap<>();
|
||||
name2IndexMap.defaultReturnValue(-1);
|
||||
|
||||
for (int i = 0; i < elements.size(); i++) {
|
||||
Element element = elements.get(i);
|
||||
String name = element.name();
|
||||
|
||||
if (GLSL_KEYWORDS.contains(name)) {
|
||||
throw new IllegalStateException("Element at index " + i + " has invalid name '" + name + "'; this is a GLSL keyword!");
|
||||
}
|
||||
|
||||
for (int j = 0; j < name.length(); j++) {
|
||||
char c = name.charAt(j);
|
||||
if (j == 0) {
|
||||
if (!isLetter(c)) {
|
||||
throw new IllegalStateException("Element at index " + i + " has invalid name '" + name + "'! Names must start with a letter.");
|
||||
}
|
||||
} else {
|
||||
if (!isValidNameCharacter(c)) {
|
||||
throw new IllegalStateException("Element at index " + i + " has invalid name '" + name + "'! Names must only contain letters, digits, and underscores.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String lowerCaseName = name.toLowerCase(Locale.ROOT);
|
||||
if (lowerCaseName.startsWith("gl") || lowerCaseName.startsWith("flw")) {
|
||||
throw new IllegalStateException("Element at index " + i + " has invalid name '" + name + "'! Names must not start with 'gl' or 'flw' (case-insensitive).");
|
||||
}
|
||||
|
||||
if (name.length() > Layout.MAX_ELEMENT_NAME_LENGTH) {
|
||||
throw new IllegalStateException("Element at index " + i + " has invalid name '" + name + "'! Names must not be longer than " + Layout.MAX_ELEMENT_NAME_LENGTH + " characters.");
|
||||
}
|
||||
|
||||
int prevIndex = name2IndexMap.putIfAbsent(name, i);
|
||||
if (prevIndex != -1) {
|
||||
throw new IllegalStateException("Elements at indices " + prevIndex + " and " + i + " have the same name; this is not valid!");
|
||||
}
|
||||
}
|
||||
|
||||
return new LayoutImpl(List.copyOf(elements));
|
||||
}
|
||||
|
||||
private static boolean isValidNameCharacter(char c) {
|
||||
return isLetter(c) || c >= '0' && c <= '9' || c == '_';
|
||||
}
|
||||
|
||||
private static boolean isLetter(char c) {
|
||||
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.jozufozu.flywheel.impl.layout;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import com.jozufozu.flywheel.api.layout.ElementType;
|
||||
import com.jozufozu.flywheel.api.layout.Layout;
|
||||
|
||||
final class LayoutImpl implements Layout {
|
||||
private final List<Element> elements;
|
||||
private final Map<String, ElementType> map;
|
||||
private final int byteSize;
|
||||
|
||||
LayoutImpl(List<Element> elements) {
|
||||
this.elements = elements;
|
||||
|
||||
map = new HashMap<>();
|
||||
int byteSize = 0;
|
||||
for (Element element : this.elements) {
|
||||
map.put(element.name(), element.type());
|
||||
byteSize += element.type().byteSize();
|
||||
}
|
||||
this.byteSize = byteSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unmodifiable
|
||||
public List<Element> elements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Unmodifiable
|
||||
public Map<String, ElementType> asMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return byteSize;
|
||||
}
|
||||
|
||||
record ElementImpl(String name, ElementType type) implements Element {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.jozufozu.flywheel.impl.layout;
|
||||
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
import com.jozufozu.flywheel.api.layout.FloatRepr;
|
||||
import com.jozufozu.flywheel.api.layout.MatrixElementType;
|
||||
|
||||
final class MatrixElementTypeImpl implements MatrixElementType {
|
||||
private final FloatRepr repr;
|
||||
@Range(from = 2, to = 4)
|
||||
private final int rows;
|
||||
@Range(from = 2, to = 4)
|
||||
private final int columns;
|
||||
private final int byteSize;
|
||||
|
||||
MatrixElementTypeImpl(FloatRepr repr, @Range(from = 2, to = 4) int rows, @Range(from = 2, to = 4) int columns) {
|
||||
if (rows < 2 || rows > 4) {
|
||||
throw new IllegalArgumentException("Matrix element row count must be in range [2, 4]!");
|
||||
}
|
||||
if (columns < 2 || columns > 4) {
|
||||
throw new IllegalArgumentException("Matrix element column count must be in range [2, 4]!");
|
||||
}
|
||||
|
||||
this.repr = repr;
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
byteSize = repr.byteSize() * rows * columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FloatRepr repr() {
|
||||
return repr;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Range(from = 2, to = 4)
|
||||
public int rows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Range(from = 2, to = 4)
|
||||
public int columns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return byteSize;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.jozufozu.flywheel.impl.layout;
|
||||
|
||||
import com.jozufozu.flywheel.api.layout.ScalarElementType;
|
||||
import com.jozufozu.flywheel.api.layout.ValueRepr;
|
||||
|
||||
final class ScalarElementTypeImpl implements ScalarElementType {
|
||||
private final ValueRepr repr;
|
||||
private final int byteSize;
|
||||
|
||||
ScalarElementTypeImpl(ValueRepr repr) {
|
||||
this.repr = repr;
|
||||
byteSize = repr.byteSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueRepr repr() {
|
||||
return repr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return byteSize;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.jozufozu.flywheel.impl.layout;
|
||||
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
import com.jozufozu.flywheel.api.layout.ValueRepr;
|
||||
import com.jozufozu.flywheel.api.layout.VectorElementType;
|
||||
|
||||
final class VectorElementTypeImpl implements VectorElementType {
|
||||
private final ValueRepr repr;
|
||||
@Range(from = 2, to = 4)
|
||||
private final int size;
|
||||
private final int byteSize;
|
||||
|
||||
VectorElementTypeImpl(ValueRepr repr, @Range(from = 2, to = 4) int size) {
|
||||
if (size < 2 || size > 4) {
|
||||
throw new IllegalArgumentException("Vector element size must be in range [2, 4]!");
|
||||
}
|
||||
|
||||
this.repr = repr;
|
||||
this.size = size;
|
||||
byteSize = repr.byteSize() * size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueRepr repr() {
|
||||
return repr;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Range(from = 2, to = 4)
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int byteSize() {
|
||||
return byteSize;
|
||||
}
|
||||
}
|
|
@ -4,17 +4,17 @@ import com.jozufozu.flywheel.Flywheel;
|
|||
import com.jozufozu.flywheel.api.instance.InstanceHandle;
|
||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
||||
import com.jozufozu.flywheel.api.layout.FloatType;
|
||||
import com.jozufozu.flywheel.api.layout.IntegerType;
|
||||
import com.jozufozu.flywheel.api.layout.FloatRepr;
|
||||
import com.jozufozu.flywheel.api.layout.IntegerRepr;
|
||||
import com.jozufozu.flywheel.api.layout.Layout;
|
||||
import com.jozufozu.flywheel.api.layout.VectorSize;
|
||||
import com.jozufozu.flywheel.api.layout.LayoutBuilder;
|
||||
import com.jozufozu.flywheel.lib.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
||||
import com.jozufozu.flywheel.lib.layout.LayoutBuilder;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class OrientedType implements InstanceType<OrientedInstance> {
|
||||
@Deprecated
|
||||
private static final BufferLayout OLD_LAYOUT = BufferLayout.builder()
|
||||
.addItem(CommonItems.LIGHT_COORD, "light")
|
||||
.addItem(CommonItems.UNORM_4x8, "color")
|
||||
|
@ -23,12 +23,12 @@ public class OrientedType implements InstanceType<OrientedInstance> {
|
|||
.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)
|
||||
private static final Layout LAYOUT = LayoutBuilder.create()
|
||||
.vector("light", IntegerRepr.SHORT, 2)
|
||||
.vector("color", FloatRepr.NORMALIZED_UNSIGNED_BYTE, 4)
|
||||
.vector("position", FloatRepr.FLOAT, 3)
|
||||
.vector("pivot", FloatRepr.FLOAT, 3)
|
||||
.vector("rotation", FloatRepr.FLOAT, 4)
|
||||
.build();
|
||||
|
||||
private static final ResourceLocation VERTEX_SHADER = Flywheel.rl("instance/oriented.vert");
|
||||
|
@ -40,7 +40,8 @@ public class OrientedType implements InstanceType<OrientedInstance> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BufferLayout getLayout() {
|
||||
@Deprecated
|
||||
public BufferLayout oldLayout() {
|
||||
return OLD_LAYOUT;
|
||||
}
|
||||
|
||||
|
@ -50,7 +51,7 @@ public class OrientedType implements InstanceType<OrientedInstance> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InstanceWriter<OrientedInstance> getWriter() {
|
||||
public InstanceWriter<OrientedInstance> writer() {
|
||||
return OrientedWriter.INSTANCE;
|
||||
}
|
||||
|
||||
|
@ -63,5 +64,4 @@ public class OrientedType implements InstanceType<OrientedInstance> {
|
|||
public ResourceLocation cullShader() {
|
||||
return CULL_SHADER;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,17 +4,17 @@ import com.jozufozu.flywheel.Flywheel;
|
|||
import com.jozufozu.flywheel.api.instance.InstanceHandle;
|
||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||
import com.jozufozu.flywheel.api.instance.InstanceWriter;
|
||||
import com.jozufozu.flywheel.api.layout.IntegerType;
|
||||
import com.jozufozu.flywheel.api.layout.FloatRepr;
|
||||
import com.jozufozu.flywheel.api.layout.IntegerRepr;
|
||||
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.api.layout.LayoutBuilder;
|
||||
import com.jozufozu.flywheel.lib.layout.BufferLayout;
|
||||
import com.jozufozu.flywheel.lib.layout.CommonItems;
|
||||
import com.jozufozu.flywheel.lib.layout.LayoutBuilder;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public class TransformedType implements InstanceType<TransformedInstance> {
|
||||
@Deprecated
|
||||
private static final BufferLayout OLD_LAYOUT = BufferLayout.builder()
|
||||
.addItem(CommonItems.LIGHT_COORD, "light")
|
||||
.addItem(CommonItems.UNORM_4x8, "color")
|
||||
|
@ -22,11 +22,11 @@ public class TransformedType implements InstanceType<TransformedInstance> {
|
|||
.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)
|
||||
private static final Layout LAYOUT = LayoutBuilder.create()
|
||||
.vector("light", IntegerRepr.SHORT, 2)
|
||||
.vector("color", FloatRepr.NORMALIZED_UNSIGNED_BYTE, 4)
|
||||
.matrix("pose", FloatRepr.FLOAT, 4)
|
||||
.matrix("normal", FloatRepr.FLOAT, 3)
|
||||
.build();
|
||||
|
||||
private static final ResourceLocation VERTEX_SHADER = Flywheel.rl("instance/transformed.vert");
|
||||
|
@ -38,7 +38,8 @@ public class TransformedType implements InstanceType<TransformedInstance> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public BufferLayout getLayout() {
|
||||
@Deprecated
|
||||
public BufferLayout oldLayout() {
|
||||
return OLD_LAYOUT;
|
||||
}
|
||||
|
||||
|
@ -48,7 +49,7 @@ public class TransformedType implements InstanceType<TransformedInstance> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public InstanceWriter<TransformedInstance> getWriter() {
|
||||
public InstanceWriter<TransformedInstance> writer() {
|
||||
return TransformedWriter.INSTANCE;
|
||||
}
|
||||
|
||||
|
@ -61,5 +62,4 @@ public class TransformedType implements InstanceType<TransformedInstance> {
|
|||
public ResourceLocation cullShader() {
|
||||
return CULL_SHADER;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
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<Element> 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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue